]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-vserver-2.3.patch
- 4.9.92
[packages/kernel.git] / kernel-vserver-2.3.patch
CommitLineData
cef7ea10
AM
1diff -NurpP --minimal linux-4.9.82/Documentation/vserver/debug.txt linux-4.9.82-vs2.3.9.7/Documentation/vserver/debug.txt
2--- linux-4.9.82/Documentation/vserver/debug.txt 1970-01-01 00:00:00.000000000 +0000
3+++ linux-4.9.82-vs2.3.9.7/Documentation/vserver/debug.txt 2018-01-10 02:50:49.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"
cc23e853
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"
cc23e853 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+
cc23e853 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"
cef7ea10
AM
159diff -NurpP --minimal linux-4.9.82/arch/alpha/Kconfig linux-4.9.82-vs2.3.9.7/arch/alpha/Kconfig
160--- linux-4.9.82/arch/alpha/Kconfig 2016-12-11 19:17:54.000000000 +0000
161+++ linux-4.9.82-vs2.3.9.7/arch/alpha/Kconfig 2018-01-10 02:50:49.000000000 +0000
cc23e853 162@@ -743,6 +743,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"
cef7ea10
AM
171diff -NurpP --minimal linux-4.9.82/arch/alpha/kernel/systbls.S linux-4.9.82-vs2.3.9.7/arch/alpha/kernel/systbls.S
172--- linux-4.9.82/arch/alpha/kernel/systbls.S 2016-12-11 19:17:54.000000000 +0000
173+++ linux-4.9.82-vs2.3.9.7/arch/alpha/kernel/systbls.S 2018-01-10 02:50:49.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 */
cef7ea10
AM
183diff -NurpP --minimal linux-4.9.82/arch/alpha/kernel/traps.c linux-4.9.82-vs2.3.9.7/arch/alpha/kernel/traps.c
184--- linux-4.9.82/arch/alpha/kernel/traps.c 2018-02-22 21:18:14.000000000 +0000
185+++ linux-4.9.82-vs2.3.9.7/arch/alpha/kernel/traps.c 2018-02-22 21:31:39.000000000 +0000
186@@ -179,7 +179,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));
cef7ea10
AM
196diff -NurpP --minimal linux-4.9.82/arch/arm/Kconfig linux-4.9.82-vs2.3.9.7/arch/arm/Kconfig
197--- linux-4.9.82/arch/arm/Kconfig 2016-12-11 19:17:54.000000000 +0000
198+++ linux-4.9.82-vs2.3.9.7/arch/arm/Kconfig 2018-01-10 02:50:49.000000000 +0000
cc23e853 199@@ -2199,6 +2199,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"
cef7ea10
AM
208diff -NurpP --minimal linux-4.9.82/arch/arm/kernel/calls.S linux-4.9.82-vs2.3.9.7/arch/arm/kernel/calls.S
209--- linux-4.9.82/arch/arm/kernel/calls.S 2016-12-11 19:17:54.000000000 +0000
210+++ linux-4.9.82-vs2.3.9.7/arch/arm/kernel/calls.S 2018-01-10 02:50:49.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)
cef7ea10
AM
220diff -NurpP --minimal linux-4.9.82/arch/arm/kernel/traps.c linux-4.9.82-vs2.3.9.7/arch/arm/kernel/traps.c
221--- linux-4.9.82/arch/arm/kernel/traps.c 2018-02-22 21:18:14.000000000 +0000
222+++ linux-4.9.82-vs2.3.9.7/arch/arm/kernel/traps.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 223@@ -278,8 +278,8 @@ static int __die(const char *str, int er
78865d5b 224
d337f35e
JR
225 print_modules();
226 __show_regs(regs);
cc23e853
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,
cef7ea10
AM
234diff -NurpP --minimal linux-4.9.82/arch/cris/Kconfig linux-4.9.82-vs2.3.9.7/arch/cris/Kconfig
235--- linux-4.9.82/arch/cris/Kconfig 2016-12-11 19:17:54.000000000 +0000
236+++ linux-4.9.82-vs2.3.9.7/arch/cris/Kconfig 2018-01-10 02:50:49.000000000 +0000
cc23e853 237@@ -583,6 +583,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"
cef7ea10
AM
246diff -NurpP --minimal linux-4.9.82/arch/ia64/Kconfig linux-4.9.82-vs2.3.9.7/arch/ia64/Kconfig
247--- linux-4.9.82/arch/ia64/Kconfig 2016-12-11 19:17:54.000000000 +0000
248+++ linux-4.9.82-vs2.3.9.7/arch/ia64/Kconfig 2018-01-10 02:50:49.000000000 +0000
cc23e853 249@@ -602,6 +602,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"
cef7ea10
AM
258diff -NurpP --minimal linux-4.9.82/arch/ia64/kernel/entry.S linux-4.9.82-vs2.3.9.7/arch/ia64/kernel/entry.S
259--- linux-4.9.82/arch/ia64/kernel/entry.S 2016-12-11 19:17:54.000000000 +0000
260+++ linux-4.9.82-vs2.3.9.7/arch/ia64/kernel/entry.S 2018-01-10 02:50:49.000000000 +0000
cc23e853 261@@ -1697,7 +1697,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
cef7ea10
AM
270diff -NurpP --minimal linux-4.9.82/arch/ia64/kernel/ptrace.c linux-4.9.82-vs2.3.9.7/arch/ia64/kernel/ptrace.c
271--- linux-4.9.82/arch/ia64/kernel/ptrace.c 2018-02-22 21:18:15.000000000 +0000
272+++ linux-4.9.82-vs2.3.9.7/arch/ia64/kernel/ptrace.c 2018-01-10 02:50:49.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>
cef7ea10
AM
281diff -NurpP --minimal linux-4.9.82/arch/ia64/kernel/traps.c linux-4.9.82-vs2.3.9.7/arch/ia64/kernel/traps.c
282--- linux-4.9.82/arch/ia64/kernel/traps.c 2016-12-11 19:17:54.000000000 +0000
283+++ linux-4.9.82-vs2.3.9.7/arch/ia64/kernel/traps.c 2018-01-10 02:50:49.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 }
cef7ea10
AM
308diff -NurpP --minimal linux-4.9.82/arch/m32r/kernel/traps.c linux-4.9.82-vs2.3.9.7/arch/m32r/kernel/traps.c
309--- linux-4.9.82/arch/m32r/kernel/traps.c 2016-12-11 19:17:54.000000000 +0000
310+++ linux-4.9.82-vs2.3.9.7/arch/m32r/kernel/traps.c 2018-01-10 02:50:49.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
cef7ea10
AM
323diff -NurpP --minimal linux-4.9.82/arch/m68k/Kconfig linux-4.9.82-vs2.3.9.7/arch/m68k/Kconfig
324--- linux-4.9.82/arch/m68k/Kconfig 2016-12-11 19:17:54.000000000 +0000
325+++ linux-4.9.82-vs2.3.9.7/arch/m68k/Kconfig 2018-01-10 02:50:49.000000000 +0000
cc23e853 326@@ -163,6 +163,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"
cef7ea10
AM
335diff -NurpP --minimal linux-4.9.82/arch/mips/Kconfig linux-4.9.82-vs2.3.9.7/arch/mips/Kconfig
336--- linux-4.9.82/arch/mips/Kconfig 2018-02-22 21:18:15.000000000 +0000
337+++ linux-4.9.82-vs2.3.9.7/arch/mips/Kconfig 2018-01-10 02:50:49.000000000 +0000
cc23e853 338@@ -3189,6 +3189,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"
cef7ea10
AM
347diff -NurpP --minimal linux-4.9.82/arch/mips/kernel/ptrace.c linux-4.9.82-vs2.3.9.7/arch/mips/kernel/ptrace.c
348--- linux-4.9.82/arch/mips/kernel/ptrace.c 2018-02-22 21:18:16.000000000 +0000
349+++ linux-4.9.82-vs2.3.9.7/arch/mips/kernel/ptrace.c 2018-01-25 00:21:31.000000000 +0000
cc23e853 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>
369dbd59 358@@ -784,6 +785,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. */
cef7ea10
AM
368diff -NurpP --minimal linux-4.9.82/arch/mips/kernel/scall32-o32.S linux-4.9.82-vs2.3.9.7/arch/mips/kernel/scall32-o32.S
369--- linux-4.9.82/arch/mips/kernel/scall32-o32.S 2018-02-22 21:18:16.000000000 +0000
370+++ linux-4.9.82-vs2.3.9.7/arch/mips/kernel/scall32-o32.S 2018-01-10 02:50:49.000000000 +0000
cc23e853 371@@ -511,7 +511,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 */
cef7ea10
AM
380diff -NurpP --minimal linux-4.9.82/arch/mips/kernel/scall64-64.S linux-4.9.82-vs2.3.9.7/arch/mips/kernel/scall64-64.S
381--- linux-4.9.82/arch/mips/kernel/scall64-64.S 2018-02-22 21:18:16.000000000 +0000
382+++ linux-4.9.82-vs2.3.9.7/arch/mips/kernel/scall64-64.S 2018-01-10 02:50:49.000000000 +0000
cc23e853 383@@ -348,7 +348,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
cef7ea10
AM
392diff -NurpP --minimal linux-4.9.82/arch/mips/kernel/scall64-n32.S linux-4.9.82-vs2.3.9.7/arch/mips/kernel/scall64-n32.S
393--- linux-4.9.82/arch/mips/kernel/scall64-n32.S 2018-02-22 21:18:16.000000000 +0000
394+++ linux-4.9.82-vs2.3.9.7/arch/mips/kernel/scall64-n32.S 2018-01-10 02:50:49.000000000 +0000
cc23e853 395@@ -343,7 +343,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
cef7ea10
AM
404diff -NurpP --minimal linux-4.9.82/arch/mips/kernel/scall64-o32.S linux-4.9.82-vs2.3.9.7/arch/mips/kernel/scall64-o32.S
405--- linux-4.9.82/arch/mips/kernel/scall64-o32.S 2018-02-22 21:18:16.000000000 +0000
406+++ linux-4.9.82-vs2.3.9.7/arch/mips/kernel/scall64-o32.S 2018-01-10 02:50:49.000000000 +0000
cc23e853 407@@ -499,7 +499,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 */
cef7ea10
AM
416diff -NurpP --minimal linux-4.9.82/arch/mips/kernel/traps.c linux-4.9.82-vs2.3.9.7/arch/mips/kernel/traps.c
417--- linux-4.9.82/arch/mips/kernel/traps.c 2018-02-22 21:18:16.000000000 +0000
418+++ linux-4.9.82-vs2.3.9.7/arch/mips/kernel/traps.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 419@@ -360,9 +360,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
cef7ea10
AM
433diff -NurpP --minimal linux-4.9.82/arch/parisc/Kconfig linux-4.9.82-vs2.3.9.7/arch/parisc/Kconfig
434--- linux-4.9.82/arch/parisc/Kconfig 2016-12-11 19:17:54.000000000 +0000
435+++ linux-4.9.82-vs2.3.9.7/arch/parisc/Kconfig 2018-01-10 02:50:49.000000000 +0000
cc23e853 436@@ -348,6 +348,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"
cef7ea10
AM
445diff -NurpP --minimal linux-4.9.82/arch/parisc/kernel/syscall_table.S linux-4.9.82-vs2.3.9.7/arch/parisc/kernel/syscall_table.S
446--- linux-4.9.82/arch/parisc/kernel/syscall_table.S 2018-02-22 21:18:16.000000000 +0000
447+++ linux-4.9.82-vs2.3.9.7/arch/parisc/kernel/syscall_table.S 2018-01-10 02:50:49.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 */
cc23e853 456 ENTRY_COMP(keyctl)
cef7ea10
AM
457diff -NurpP --minimal linux-4.9.82/arch/parisc/kernel/traps.c linux-4.9.82-vs2.3.9.7/arch/parisc/kernel/traps.c
458--- linux-4.9.82/arch/parisc/kernel/traps.c 2016-12-11 19:17:54.000000000 +0000
459+++ linux-4.9.82-vs2.3.9.7/arch/parisc/kernel/traps.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 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 }
cc23e853 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) {
cef7ea10
AM
483diff -NurpP --minimal linux-4.9.82/arch/powerpc/Kconfig linux-4.9.82-vs2.3.9.7/arch/powerpc/Kconfig
484--- linux-4.9.82/arch/powerpc/Kconfig 2018-02-22 21:18:16.000000000 +0000
485+++ linux-4.9.82-vs2.3.9.7/arch/powerpc/Kconfig 2018-02-22 21:31:39.000000000 +0000
486@@ -1086,6 +1086,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
cc23e853 494 source "crypto/Kconfig"
cef7ea10
AM
495diff -NurpP --minimal linux-4.9.82/arch/powerpc/include/uapi/asm/unistd.h linux-4.9.82-vs2.3.9.7/arch/powerpc/include/uapi/asm/unistd.h
496--- linux-4.9.82/arch/powerpc/include/uapi/asm/unistd.h 2016-12-11 19:17:54.000000000 +0000
497+++ linux-4.9.82-vs2.3.9.7/arch/powerpc/include/uapi/asm/unistd.h 2018-01-10 02:50:49.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
cef7ea10
AM
507diff -NurpP --minimal linux-4.9.82/arch/s390/Kconfig linux-4.9.82-vs2.3.9.7/arch/s390/Kconfig
508--- linux-4.9.82/arch/s390/Kconfig 2018-02-22 21:18:17.000000000 +0000
509+++ linux-4.9.82-vs2.3.9.7/arch/s390/Kconfig 2018-01-10 02:50:49.000000000 +0000
cc23e853 510@@ -729,6 +729,8 @@ source "fs/Kconfig"
d33d7b00
AM
511
512 source "arch/s390/Kconfig.debug"
513
514+source "kernel/vserver/Kconfig"
515+
516 source "security/Kconfig"
0411181d 517
d33d7b00 518 source "crypto/Kconfig"
cef7ea10
AM
519diff -NurpP --minimal linux-4.9.82/arch/s390/include/asm/tlb.h linux-4.9.82-vs2.3.9.7/arch/s390/include/asm/tlb.h
520--- linux-4.9.82/arch/s390/include/asm/tlb.h 2016-12-11 19:17:54.000000000 +0000
521+++ linux-4.9.82-vs2.3.9.7/arch/s390/include/asm/tlb.h 2018-01-10 02:50:49.000000000 +0000
dd5f3080 522@@ -24,6 +24,7 @@
0411181d 523 #include <linux/mm.h>
d33d7b00 524 #include <linux/pagemap.h>
0411181d 525 #include <linux/swap.h>
0411181d
AM
526+
527 #include <asm/processor.h>
528 #include <asm/pgalloc.h>
763640ca 529 #include <asm/tlbflush.h>
cef7ea10
AM
530diff -NurpP --minimal linux-4.9.82/arch/s390/include/uapi/asm/unistd.h linux-4.9.82-vs2.3.9.7/arch/s390/include/uapi/asm/unistd.h
531--- linux-4.9.82/arch/s390/include/uapi/asm/unistd.h 2016-12-11 19:17:54.000000000 +0000
532+++ linux-4.9.82-vs2.3.9.7/arch/s390/include/uapi/asm/unistd.h 2018-01-10 02:50:49.000000000 +0000
92598135 533@@ -200,7 +200,7 @@
cc23e853
AM
534 #define __NR_clock_gettime 260
535 #define __NR_clock_getres 261
536 #define __NR_clock_nanosleep 262
0411181d
AM
537-/* Number 263 is reserved for vserver */
538+#define __NR_vserver 263
539 #define __NR_statfs64 265
540 #define __NR_fstatfs64 266
541 #define __NR_remap_file_pages 267
cef7ea10
AM
542diff -NurpP --minimal linux-4.9.82/arch/s390/kernel/ptrace.c linux-4.9.82-vs2.3.9.7/arch/s390/kernel/ptrace.c
543--- linux-4.9.82/arch/s390/kernel/ptrace.c 2018-02-22 21:18:17.000000000 +0000
544+++ linux-4.9.82-vs2.3.9.7/arch/s390/kernel/ptrace.c 2018-01-10 02:50:49.000000000 +0000
db55b927 545@@ -21,6 +21,7 @@
ec22aa5c
AM
546 #include <linux/tracehook.h>
547 #include <linux/seccomp.h>
969f5c41 548 #include <linux/compat.h>
db55b927 549+#include <linux/vs_base.h>
ec22aa5c 550 #include <trace/syscall.h>
d337f35e 551 #include <asm/segment.h>
db55b927 552 #include <asm/page.h>
cef7ea10
AM
553diff -NurpP --minimal linux-4.9.82/arch/s390/kernel/syscalls.S linux-4.9.82-vs2.3.9.7/arch/s390/kernel/syscalls.S
554--- linux-4.9.82/arch/s390/kernel/syscalls.S 2018-02-22 21:18:17.000000000 +0000
555+++ linux-4.9.82-vs2.3.9.7/arch/s390/kernel/syscalls.S 2018-01-10 02:50:49.000000000 +0000
cc23e853
AM
556@@ -271,7 +271,7 @@ SYSCALL(sys_clock_settime,compat_sys_clo
557 SYSCALL(sys_clock_gettime,compat_sys_clock_gettime) /* 260 */
558 SYSCALL(sys_clock_getres,compat_sys_clock_getres)
559 SYSCALL(sys_clock_nanosleep,compat_sys_clock_nanosleep)
560-NI_SYSCALL /* reserved for vserver */
d337f35e 561+SYSCALL(sys_vserver,sys_vserver,sys32_vserver)
cc23e853
AM
562 SYSCALL(sys_ni_syscall,compat_sys_s390_fadvise64_64)
563 SYSCALL(sys_statfs64,compat_sys_statfs64)
564 SYSCALL(sys_fstatfs64,compat_sys_fstatfs64)
cef7ea10
AM
565diff -NurpP --minimal linux-4.9.82/arch/sh/Kconfig linux-4.9.82-vs2.3.9.7/arch/sh/Kconfig
566--- linux-4.9.82/arch/sh/Kconfig 2016-12-11 19:17:54.000000000 +0000
567+++ linux-4.9.82-vs2.3.9.7/arch/sh/Kconfig 2018-01-10 02:50:49.000000000 +0000
cc23e853 568@@ -904,6 +904,8 @@ source "fs/Kconfig"
d337f35e
JR
569
570 source "arch/sh/Kconfig.debug"
571
572+source "kernel/vserver/Kconfig"
573+
574 source "security/Kconfig"
575
576 source "crypto/Kconfig"
cef7ea10
AM
577diff -NurpP --minimal linux-4.9.82/arch/sh/kernel/irq.c linux-4.9.82-vs2.3.9.7/arch/sh/kernel/irq.c
578--- linux-4.9.82/arch/sh/kernel/irq.c 2016-12-11 19:17:54.000000000 +0000
579+++ linux-4.9.82-vs2.3.9.7/arch/sh/kernel/irq.c 2018-01-10 02:50:49.000000000 +0000
f86f0b53 580@@ -14,6 +14,7 @@
7e46296a 581 #include <linux/ftrace.h>
76514441 582 #include <linux/delay.h>
763640ca 583 #include <linux/ratelimit.h>
f86f0b53 584+// #include <linux/vs_context.h>
d337f35e 585 #include <asm/processor.h>
2380c486 586 #include <asm/machvec.h>
f86f0b53 587 #include <asm/uaccess.h>
cef7ea10
AM
588diff -NurpP --minimal linux-4.9.82/arch/sparc/Kconfig linux-4.9.82-vs2.3.9.7/arch/sparc/Kconfig
589--- linux-4.9.82/arch/sparc/Kconfig 2018-02-22 21:18:17.000000000 +0000
590+++ linux-4.9.82-vs2.3.9.7/arch/sparc/Kconfig 2018-01-10 02:50:49.000000000 +0000
cc23e853 591@@ -580,6 +580,8 @@ source "fs/Kconfig"
d33d7b00
AM
592
593 source "arch/sparc/Kconfig.debug"
594
595+source "kernel/vserver/Kconfig"
596+
597 source "security/Kconfig"
598
599 source "crypto/Kconfig"
cef7ea10
AM
600diff -NurpP --minimal linux-4.9.82/arch/sparc/include/uapi/asm/unistd.h linux-4.9.82-vs2.3.9.7/arch/sparc/include/uapi/asm/unistd.h
601--- linux-4.9.82/arch/sparc/include/uapi/asm/unistd.h 2016-12-11 19:17:54.000000000 +0000
602+++ linux-4.9.82-vs2.3.9.7/arch/sparc/include/uapi/asm/unistd.h 2018-01-10 02:50:49.000000000 +0000
537831f9 603@@ -332,7 +332,7 @@
ec22aa5c
AM
604 #define __NR_timer_getoverrun 264
605 #define __NR_timer_delete 265
606 #define __NR_timer_create 266
607-/* #define __NR_vserver 267 Reserved for VSERVER */
608+#define __NR_vserver 267
609 #define __NR_io_setup 268
610 #define __NR_io_destroy 269
611 #define __NR_io_submit 270
cef7ea10
AM
612diff -NurpP --minimal linux-4.9.82/arch/sparc/kernel/systbls_32.S linux-4.9.82-vs2.3.9.7/arch/sparc/kernel/systbls_32.S
613--- linux-4.9.82/arch/sparc/kernel/systbls_32.S 2016-12-11 19:17:54.000000000 +0000
614+++ linux-4.9.82-vs2.3.9.7/arch/sparc/kernel/systbls_32.S 2018-01-10 02:50:49.000000000 +0000
50e68740 615@@ -70,7 +70,7 @@ sys_call_table:
a168f21d 616 /*250*/ .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_ni_syscall
50e68740
JR
617 /*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
618 /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
619-/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
620+/*265*/ .long sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
621 /*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
622 /*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
623 /*280*/ .long sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
cef7ea10
AM
624diff -NurpP --minimal linux-4.9.82/arch/sparc/kernel/systbls_64.S linux-4.9.82-vs2.3.9.7/arch/sparc/kernel/systbls_64.S
625--- linux-4.9.82/arch/sparc/kernel/systbls_64.S 2016-12-11 19:17:54.000000000 +0000
626+++ linux-4.9.82-vs2.3.9.7/arch/sparc/kernel/systbls_64.S 2018-01-10 02:50:49.000000000 +0000
50e68740 627@@ -71,7 +71,7 @@ sys_call_table32:
b00e13aa 628 /*250*/ .word sys_mremap, compat_sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall
50e68740
JR
629 .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
630 /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun
631- .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
632+ .word sys_timer_delete, compat_sys_timer_create, sys32_vserver, compat_sys_io_setup, sys_io_destroy
633 /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
634 .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
b00e13aa 635 /*280*/ .word sys_tee, sys_add_key, sys_request_key, compat_sys_keyctl, compat_sys_openat
cc23e853 636@@ -152,7 +152,7 @@ sys_call_table:
a168f21d 637 /*250*/ .word sys_64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall
50e68740
JR
638 .word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
639 /*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
640- .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
641+ .word sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
642 /*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
643 .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
644 /*280*/ .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
cef7ea10
AM
645diff -NurpP --minimal linux-4.9.82/arch/um/Kconfig.rest linux-4.9.82-vs2.3.9.7/arch/um/Kconfig.rest
646--- linux-4.9.82/arch/um/Kconfig.rest 2016-12-11 19:17:54.000000000 +0000
647+++ linux-4.9.82-vs2.3.9.7/arch/um/Kconfig.rest 2018-01-10 02:50:49.000000000 +0000
f6c5ef8b 648@@ -12,6 +12,8 @@ source "arch/um/Kconfig.net"
d33d7b00
AM
649
650 source "fs/Kconfig"
651
652+source "kernel/vserver/Kconfig"
653+
654 source "security/Kconfig"
655
656 source "crypto/Kconfig"
cef7ea10
AM
657diff -NurpP --minimal linux-4.9.82/arch/x86/Kconfig linux-4.9.82-vs2.3.9.7/arch/x86/Kconfig
658--- linux-4.9.82/arch/x86/Kconfig 2018-02-22 21:18:17.000000000 +0000
659+++ linux-4.9.82-vs2.3.9.7/arch/x86/Kconfig 2018-01-25 00:21:31.000000000 +0000
369dbd59 660@@ -2777,6 +2777,8 @@ source "fs/Kconfig"
e03b8c3c 661
d33d7b00 662 source "arch/x86/Kconfig.debug"
e03b8c3c
AM
663
664+source "kernel/vserver/Kconfig"
665+
666 source "security/Kconfig"
667
668 source "crypto/Kconfig"
cef7ea10
AM
669diff -NurpP --minimal linux-4.9.82/arch/x86/entry/syscalls/syscall_32.tbl linux-4.9.82-vs2.3.9.7/arch/x86/entry/syscalls/syscall_32.tbl
670--- linux-4.9.82/arch/x86/entry/syscalls/syscall_32.tbl 2016-12-11 19:17:54.000000000 +0000
671+++ linux-4.9.82-vs2.3.9.7/arch/x86/entry/syscalls/syscall_32.tbl 2018-01-10 02:50:49.000000000 +0000
db55b927
AM
672@@ -279,7 +279,7 @@
673 270 i386 tgkill sys_tgkill
674 271 i386 utimes sys_utimes compat_sys_utimes
675 272 i386 fadvise64_64 sys_fadvise64_64 sys32_fadvise64_64
676-273 i386 vserver
677+273 i386 vserver sys_vserver sys32_vserver
678 274 i386 mbind sys_mbind
679 275 i386 get_mempolicy sys_get_mempolicy compat_sys_get_mempolicy
680 276 i386 set_mempolicy sys_set_mempolicy
cef7ea10
AM
681diff -NurpP --minimal linux-4.9.82/arch/x86/entry/syscalls/syscall_64.tbl linux-4.9.82-vs2.3.9.7/arch/x86/entry/syscalls/syscall_64.tbl
682--- linux-4.9.82/arch/x86/entry/syscalls/syscall_64.tbl 2016-12-11 19:17:54.000000000 +0000
683+++ linux-4.9.82-vs2.3.9.7/arch/x86/entry/syscalls/syscall_64.tbl 2018-01-10 02:50:49.000000000 +0000
db55b927 684@@ -242,7 +242,7 @@
1e8b8f9b
AM
685 233 common epoll_ctl sys_epoll_ctl
686 234 common tgkill sys_tgkill
687 235 common utimes sys_utimes
db55b927
AM
688-236 64 vserver
689+236 64 vserver sys_vserver
1e8b8f9b
AM
690 237 common mbind sys_mbind
691 238 common set_mempolicy sys_set_mempolicy
692 239 common get_mempolicy sys_get_mempolicy
cef7ea10
AM
693diff -NurpP --minimal linux-4.9.82/block/ioprio.c linux-4.9.82-vs2.3.9.7/block/ioprio.c
694--- linux-4.9.82/block/ioprio.c 2016-12-11 19:17:54.000000000 +0000
695+++ linux-4.9.82-vs2.3.9.7/block/ioprio.c 2018-01-10 02:50:49.000000000 +0000
bb20add7
AM
696@@ -28,6 +28,7 @@
697 #include <linux/syscalls.h>
698 #include <linux/security.h>
699 #include <linux/pid_namespace.h>
700+#include <linux/vs_base.h>
701
702 int set_task_ioprio(struct task_struct *task, int ioprio)
703 {
704@@ -105,6 +106,8 @@ SYSCALL_DEFINE3(ioprio_set, int, which,
705 else
706 pgrp = find_vpid(who);
707 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
708+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
709+ continue;
710 ret = set_task_ioprio(p, ioprio);
711 if (ret)
712 break;
cc23e853 713@@ -203,6 +206,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which,
bb20add7
AM
714 else
715 pgrp = find_vpid(who);
716 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
717+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
718+ continue;
719 tmpio = get_task_ioprio(p);
720 if (tmpio < 0)
721 continue;
cef7ea10
AM
722diff -NurpP --minimal linux-4.9.82/drivers/block/Kconfig linux-4.9.82-vs2.3.9.7/drivers/block/Kconfig
723--- linux-4.9.82/drivers/block/Kconfig 2016-12-11 19:17:54.000000000 +0000
724+++ linux-4.9.82-vs2.3.9.7/drivers/block/Kconfig 2018-01-10 02:50:49.000000000 +0000
cc23e853 725@@ -273,6 +273,13 @@ config BLK_DEV_CRYPTOLOOP
2bf5ad28
AM
726
727 source "drivers/block/drbd/Kconfig"
d337f35e
JR
728
729+config BLK_DEV_VROOT
730+ tristate "Virtual Root device support"
731+ depends on QUOTACTL
732+ ---help---
733+ Saying Y here will allow you to use quota/fs ioctls on a shared
734+ partition within a virtual server without compromising security.
735+
736 config BLK_DEV_NBD
737 tristate "Network block device support"
738 depends on NET
cef7ea10
AM
739diff -NurpP --minimal linux-4.9.82/drivers/block/Makefile linux-4.9.82-vs2.3.9.7/drivers/block/Makefile
740--- linux-4.9.82/drivers/block/Makefile 2016-12-11 19:17:54.000000000 +0000
741+++ linux-4.9.82-vs2.3.9.7/drivers/block/Makefile 2018-01-10 02:50:49.000000000 +0000
cc23e853 742@@ -31,6 +31,7 @@ obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o
bb20add7 743
d33d7b00 744 obj-$(CONFIG_BLK_DEV_SX8) += sx8.o
d33d7b00
AM
745 obj-$(CONFIG_BLK_DEV_HD) += hd.o
746+obj-$(CONFIG_BLK_DEV_VROOT) += vroot.o
747
748 obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o
763640ca 749 obj-$(CONFIG_XEN_BLKDEV_BACKEND) += xen-blkback/
cef7ea10
AM
750diff -NurpP --minimal linux-4.9.82/drivers/block/loop.c linux-4.9.82-vs2.3.9.7/drivers/block/loop.c
751--- linux-4.9.82/drivers/block/loop.c 2018-02-22 21:18:20.000000000 +0000
752+++ linux-4.9.82-vs2.3.9.7/drivers/block/loop.c 2018-02-10 15:15:43.000000000 +0000
cc23e853 753@@ -76,6 +76,7 @@
a168f21d 754 #include <linux/miscdevice.h>
f6c5ef8b 755 #include <linux/falloc.h>
cc23e853 756 #include <linux/uio.h>
d337f35e 757+#include <linux/vs_context.h>
c2e5f7c8 758 #include "loop.h"
f6c5ef8b 759
d337f35e 760 #include <asm/uaccess.h>
cc23e853 761@@ -924,6 +925,7 @@ static int loop_set_fd(struct loop_devic
d337f35e
JR
762 lo->lo_blocksize = lo_blocksize;
763 lo->lo_device = bdev;
764 lo->lo_flags = lo_flags;
765+ lo->lo_xid = vx_current_xid();
766 lo->lo_backing_file = file;
cc23e853 767 lo->transfer = NULL;
d337f35e 768 lo->ioctl = NULL;
cc23e853
AM
769@@ -1044,6 +1046,7 @@ static int loop_clr_fd(struct loop_devic
770 lo->lo_offset = 0;
f6c5ef8b 771 lo->lo_sizelimit = 0;
2380c486 772 lo->lo_encrypt_key_size = 0;
2380c486
JR
773+ lo->lo_xid = 0;
774 memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
775 memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
776 memset(lo->lo_file_name, 0, LO_NAME_SIZE);
cc23e853 777@@ -1090,7 +1093,7 @@ loop_set_status(struct loop_device *lo,
2380c486 778
ec22aa5c 779 if (lo->lo_encrypt_key_size &&
537831f9 780 !uid_eq(lo->lo_key_owner, uid) &&
d337f35e
JR
781- !capable(CAP_SYS_ADMIN))
782+ !vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP))
783 return -EPERM;
784 if (lo->lo_state != Lo_bound)
785 return -ENXIO;
cc23e853 786@@ -1191,7 +1194,8 @@ loop_get_status(struct loop_device *lo,
d337f35e
JR
787 memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE);
788 info->lo_encrypt_type =
789 lo->lo_encryption ? lo->lo_encryption->number : 0;
790- if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
791+ if (lo->lo_encrypt_key_size &&
792+ vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP)) {
793 info->lo_encrypt_key_size = lo->lo_encrypt_key_size;
794 memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
795 lo->lo_encrypt_key_size);
cc23e853 796@@ -1552,6 +1556,11 @@ static int lo_open(struct block_device *
a168f21d
AM
797 goto out;
798 }
d337f35e 799
dd5f3080 800+ if (!vx_check(lo->lo_xid, VS_IDENT|VS_HOSTID|VS_ADMIN_P)) {
801+ err = -EACCES;
802+ goto out;
803+ }
d337f35e 804+
cc23e853
AM
805 atomic_inc(&lo->lo_refcnt);
806 out:
807 mutex_unlock(&loop_index_mutex);
cef7ea10
AM
808diff -NurpP --minimal linux-4.9.82/drivers/block/loop.h linux-4.9.82-vs2.3.9.7/drivers/block/loop.h
809--- linux-4.9.82/drivers/block/loop.h 2016-12-11 19:17:54.000000000 +0000
810+++ linux-4.9.82-vs2.3.9.7/drivers/block/loop.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 811@@ -43,6 +43,7 @@ struct loop_device {
c2e5f7c8
JR
812 struct loop_func_table *lo_encryption;
813 __u32 lo_init[2];
814 kuid_t lo_key_owner; /* Who set the key */
815+ vxid_t lo_xid;
816 int (*ioctl)(struct loop_device *, int cmd,
817 unsigned long arg);
818
cef7ea10
AM
819diff -NurpP --minimal linux-4.9.82/drivers/block/vroot.c linux-4.9.82-vs2.3.9.7/drivers/block/vroot.c
820--- linux-4.9.82/drivers/block/vroot.c 1970-01-01 00:00:00.000000000 +0000
821+++ linux-4.9.82-vs2.3.9.7/drivers/block/vroot.c 2018-01-13 22:00:41.000000000 +0000
cc23e853 822@@ -0,0 +1,291 @@
d337f35e
JR
823+/*
824+ * linux/drivers/block/vroot.c
825+ *
cc23e853
AM
826+ * written by Herbert P?tzl, 9/11/2002
827+ * ported to 2.6.10 by Herbert P?tzl, 30/12/2004
d337f35e
JR
828+ *
829+ * based on the loop.c code by Theodore Ts'o.
830+ *
cc23e853 831+ * Copyright (C) 2002-2007 by Herbert P?tzl.
d337f35e
JR
832+ * Redistribution of this file is permitted under the
833+ * GNU General Public License.
834+ *
835+ */
836+
837+#include <linux/module.h>
838+#include <linux/moduleparam.h>
839+#include <linux/file.h>
840+#include <linux/major.h>
841+#include <linux/blkdev.h>
76514441 842+#include <linux/slab.h>
d337f35e
JR
843+
844+#include <linux/vroot.h>
845+#include <linux/vs_context.h>
846+
847+
848+static int max_vroot = 8;
849+
850+static struct vroot_device *vroot_dev;
851+static struct gendisk **disks;
852+
853+
854+static int vroot_set_dev(
855+ struct vroot_device *vr,
d337f35e
JR
856+ struct block_device *bdev,
857+ unsigned int arg)
858+{
859+ struct block_device *real_bdev;
860+ struct file *file;
861+ struct inode *inode;
862+ int error;
863+
864+ error = -EBUSY;
865+ if (vr->vr_state != Vr_unbound)
866+ goto out;
867+
868+ error = -EBADF;
869+ file = fget(arg);
870+ if (!file)
871+ goto out;
872+
873+ error = -EINVAL;
cc23e853 874+ inode = file->f_path.dentry->d_inode;
d337f35e
JR
875+
876+
877+ if (S_ISBLK(inode->i_mode)) {
878+ real_bdev = inode->i_bdev;
879+ vr->vr_device = real_bdev;
880+ __iget(real_bdev->bd_inode);
881+ } else
882+ goto out_fput;
883+
884+ vxdprintk(VXD_CBIT(misc, 0),
885+ "vroot[%d]_set_dev: dev=" VXF_DEV,
886+ vr->vr_number, VXD_DEV(real_bdev));
887+
888+ vr->vr_state = Vr_bound;
889+ error = 0;
890+
891+ out_fput:
892+ fput(file);
893+ out:
894+ return error;
895+}
896+
897+static int vroot_clr_dev(
898+ struct vroot_device *vr,
d337f35e
JR
899+ struct block_device *bdev)
900+{
901+ struct block_device *real_bdev;
902+
903+ if (vr->vr_state != Vr_bound)
904+ return -ENXIO;
905+ if (vr->vr_refcnt > 1) /* we needed one fd for the ioctl */
906+ return -EBUSY;
907+
908+ real_bdev = vr->vr_device;
909+
910+ vxdprintk(VXD_CBIT(misc, 0),
911+ "vroot[%d]_clr_dev: dev=" VXF_DEV,
912+ vr->vr_number, VXD_DEV(real_bdev));
913+
914+ bdput(real_bdev);
915+ vr->vr_state = Vr_unbound;
916+ vr->vr_device = NULL;
917+ return 0;
918+}
919+
920+
ec22aa5c 921+static int vr_ioctl(struct block_device *bdev, fmode_t mode,
d337f35e
JR
922+ unsigned int cmd, unsigned long arg)
923+{
ec22aa5c 924+ struct vroot_device *vr = bdev->bd_disk->private_data;
d337f35e
JR
925+ int err;
926+
927+ down(&vr->vr_ctl_mutex);
928+ switch (cmd) {
929+ case VROOT_SET_DEV:
ec22aa5c 930+ err = vroot_set_dev(vr, bdev, arg);
d337f35e
JR
931+ break;
932+ case VROOT_CLR_DEV:
ec22aa5c 933+ err = vroot_clr_dev(vr, bdev);
d337f35e
JR
934+ break;
935+ default:
936+ err = -EINVAL;
937+ break;
938+ }
939+ up(&vr->vr_ctl_mutex);
940+ return err;
941+}
942+
ec22aa5c 943+static int vr_open(struct block_device *bdev, fmode_t mode)
d337f35e 944+{
ec22aa5c 945+ struct vroot_device *vr = bdev->bd_disk->private_data;
d337f35e
JR
946+
947+ down(&vr->vr_ctl_mutex);
948+ vr->vr_refcnt++;
949+ up(&vr->vr_ctl_mutex);
950+ return 0;
951+}
952+
09be7631 953+static void vr_release(struct gendisk *disk, fmode_t mode)
d337f35e 954+{
ec22aa5c 955+ struct vroot_device *vr = disk->private_data;
d337f35e
JR
956+
957+ down(&vr->vr_ctl_mutex);
958+ --vr->vr_refcnt;
959+ up(&vr->vr_ctl_mutex);
d337f35e
JR
960+}
961+
962+static struct block_device_operations vr_fops = {
963+ .owner = THIS_MODULE,
964+ .open = vr_open,
965+ .release = vr_release,
966+ .ioctl = vr_ioctl,
967+};
968+
cc23e853 969+static blk_qc_t vroot_make_request(struct request_queue *q, struct bio *bio)
b3b0d4fd
AM
970+{
971+ printk("vroot_make_request %p, %p\n", q, bio);
972+ bio_io_error(bio);
cc23e853 973+ return BLK_QC_T_NONE;
b3b0d4fd
AM
974+}
975+
d337f35e
JR
976+struct block_device *__vroot_get_real_bdev(struct block_device *bdev)
977+{
978+ struct inode *inode = bdev->bd_inode;
979+ struct vroot_device *vr;
980+ struct block_device *real_bdev;
981+ int minor = iminor(inode);
982+
983+ vr = &vroot_dev[minor];
984+ real_bdev = vr->vr_device;
985+
986+ vxdprintk(VXD_CBIT(misc, 0),
987+ "vroot[%d]_get_real_bdev: dev=" VXF_DEV,
988+ vr->vr_number, VXD_DEV(real_bdev));
989+
990+ if (vr->vr_state != Vr_bound)
991+ return ERR_PTR(-ENXIO);
992+
993+ __iget(real_bdev->bd_inode);
994+ return real_bdev;
995+}
996+
b3b0d4fd
AM
997+
998+
d337f35e
JR
999+/*
1000+ * And now the modules code and kernel interface.
1001+ */
1002+
1003+module_param(max_vroot, int, 0);
1004+
1005+MODULE_PARM_DESC(max_vroot, "Maximum number of vroot devices (1-256)");
1006+MODULE_LICENSE("GPL");
1007+MODULE_ALIAS_BLOCKDEV_MAJOR(VROOT_MAJOR);
1008+
cc23e853 1009+MODULE_AUTHOR ("Herbert P?tzl");
d337f35e
JR
1010+MODULE_DESCRIPTION ("Virtual Root Device Mapper");
1011+
1012+
1013+int __init vroot_init(void)
1014+{
1015+ int err, i;
1016+
1017+ if (max_vroot < 1 || max_vroot > 256) {
1018+ max_vroot = MAX_VROOT_DEFAULT;
1019+ printk(KERN_WARNING "vroot: invalid max_vroot "
1020+ "(must be between 1 and 256), "
1021+ "using default (%d)\n", max_vroot);
1022+ }
1023+
1024+ if (register_blkdev(VROOT_MAJOR, "vroot"))
1025+ return -EIO;
1026+
1027+ err = -ENOMEM;
1028+ vroot_dev = kmalloc(max_vroot * sizeof(struct vroot_device), GFP_KERNEL);
1029+ if (!vroot_dev)
1030+ goto out_mem1;
1031+ memset(vroot_dev, 0, max_vroot * sizeof(struct vroot_device));
1032+
1033+ disks = kmalloc(max_vroot * sizeof(struct gendisk *), GFP_KERNEL);
1034+ if (!disks)
1035+ goto out_mem2;
1036+
1037+ for (i = 0; i < max_vroot; i++) {
1038+ disks[i] = alloc_disk(1);
1039+ if (!disks[i])
1040+ goto out_mem3;
2380c486
JR
1041+ disks[i]->queue = blk_alloc_queue(GFP_KERNEL);
1042+ if (!disks[i]->queue)
1043+ goto out_mem3;
b3b0d4fd 1044+ blk_queue_make_request(disks[i]->queue, vroot_make_request);
d337f35e
JR
1045+ }
1046+
1047+ for (i = 0; i < max_vroot; i++) {
1048+ struct vroot_device *vr = &vroot_dev[i];
1049+ struct gendisk *disk = disks[i];
1050+
1051+ memset(vr, 0, sizeof(*vr));
5a9fc8e8 1052+ sema_init(&vr->vr_ctl_mutex, 1);
d337f35e
JR
1053+ vr->vr_number = i;
1054+ disk->major = VROOT_MAJOR;
1055+ disk->first_minor = i;
1056+ disk->fops = &vr_fops;
1057+ sprintf(disk->disk_name, "vroot%d", i);
1058+ disk->private_data = vr;
1059+ }
1060+
1061+ err = register_vroot_grb(&__vroot_get_real_bdev);
1062+ if (err)
1063+ goto out_mem3;
1064+
1065+ for (i = 0; i < max_vroot; i++)
1066+ add_disk(disks[i]);
1067+ printk(KERN_INFO "vroot: loaded (max %d devices)\n", max_vroot);
1068+ return 0;
1069+
1070+out_mem3:
1071+ while (i--)
1072+ put_disk(disks[i]);
1073+ kfree(disks);
1074+out_mem2:
1075+ kfree(vroot_dev);
1076+out_mem1:
1077+ unregister_blkdev(VROOT_MAJOR, "vroot");
1078+ printk(KERN_ERR "vroot: ran out of memory\n");
1079+ return err;
1080+}
1081+
1082+void vroot_exit(void)
1083+{
1084+ int i;
1085+
1086+ if (unregister_vroot_grb(&__vroot_get_real_bdev))
1087+ printk(KERN_WARNING "vroot: cannot unregister grb\n");
1088+
1089+ for (i = 0; i < max_vroot; i++) {
1090+ del_gendisk(disks[i]);
1091+ put_disk(disks[i]);
1092+ }
2380c486 1093+ unregister_blkdev(VROOT_MAJOR, "vroot");
d337f35e
JR
1094+
1095+ kfree(disks);
1096+ kfree(vroot_dev);
1097+}
1098+
1099+module_init(vroot_init);
1100+module_exit(vroot_exit);
1101+
1102+#ifndef MODULE
1103+
1104+static int __init max_vroot_setup(char *str)
1105+{
1106+ max_vroot = simple_strtol(str, NULL, 0);
1107+ return 1;
1108+}
1109+
1110+__setup("max_vroot=", max_vroot_setup);
1111+
1112+#endif
1113+
cef7ea10
AM
1114diff -NurpP --minimal linux-4.9.82/drivers/md/dm-core.h linux-4.9.82-vs2.3.9.7/drivers/md/dm-core.h
1115--- linux-4.9.82/drivers/md/dm-core.h 2018-02-22 21:18:28.000000000 +0000
1116+++ linux-4.9.82-vs2.3.9.7/drivers/md/dm-core.h 2018-01-10 08:35:10.000000000 +0000
cc23e853
AM
1117@@ -52,6 +52,7 @@ struct mapped_device {
1118
1119 atomic_t holders;
1120 atomic_t open_count;
1121+ vxid_t xid;
1122
1123 struct dm_target *immutable_target;
1124 struct target_type *immutable_target_type;
cef7ea10
AM
1125diff -NurpP --minimal linux-4.9.82/drivers/md/dm-ioctl.c linux-4.9.82-vs2.3.9.7/drivers/md/dm-ioctl.c
1126--- linux-4.9.82/drivers/md/dm-ioctl.c 2018-02-22 21:18:28.000000000 +0000
1127+++ linux-4.9.82-vs2.3.9.7/drivers/md/dm-ioctl.c 2018-01-10 02:50:49.000000000 +0000
3bac966d
AM
1128@@ -16,6 +16,7 @@
1129 #include <linux/dm-ioctl.h>
1130 #include <linux/hdreg.h>
1131 #include <linux/compat.h>
1132+#include <linux/vs_context.h>
1133
1134 #include <asm/uaccess.h>
1135
c2e5f7c8 1136@@ -114,7 +115,8 @@ static struct hash_cell *__get_name_cell
3bac966d
AM
1137 unsigned int h = hash_str(str);
1138
1139 list_for_each_entry (hc, _name_buckets + h, name_list)
1140- if (!strcmp(hc->name, str)) {
1141+ if (vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT) &&
1142+ !strcmp(hc->name, str)) {
1143 dm_get(hc->md);
1144 return hc;
1145 }
c2e5f7c8 1146@@ -128,7 +130,8 @@ static struct hash_cell *__get_uuid_cell
3bac966d
AM
1147 unsigned int h = hash_str(str);
1148
1149 list_for_each_entry (hc, _uuid_buckets + h, uuid_list)
1150- if (!strcmp(hc->uuid, str)) {
1151+ if (vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT) &&
1152+ !strcmp(hc->uuid, str)) {
1153 dm_get(hc->md);
1154 return hc;
1155 }
c2e5f7c8 1156@@ -139,13 +142,15 @@ static struct hash_cell *__get_uuid_cell
a168f21d
AM
1157 static struct hash_cell *__get_dev_cell(uint64_t dev)
1158 {
1159 struct mapped_device *md;
1160- struct hash_cell *hc;
1161+ struct hash_cell *hc = NULL;
1162
1163 md = dm_get_md(huge_decode_dev(dev));
1164 if (!md)
1165 return NULL;
1166
1167- hc = dm_get_mdptr(md);
1168+ if (vx_check(dm_get_xid(md), VS_WATCH_P | VS_IDENT))
1169+ hc = dm_get_mdptr(md);
1170+
1171 if (!hc) {
1172 dm_put(md);
1173 return NULL;
c2e5f7c8 1174@@ -467,6 +472,9 @@ typedef int (*ioctl_fn)(struct dm_ioctl
3bac966d
AM
1175
1176 static int remove_all(struct dm_ioctl *param, size_t param_size)
1177 {
1178+ if (!vx_check(0, VS_ADMIN))
1179+ return -EPERM;
1180+
c2e5f7c8 1181 dm_hash_remove_all(true, !!(param->flags & DM_DEFERRED_REMOVE), false);
3bac966d
AM
1182 param->data_size = 0;
1183 return 0;
c2e5f7c8 1184@@ -514,6 +522,8 @@ static int list_devices(struct dm_ioctl
3bac966d
AM
1185 */
1186 for (i = 0; i < NUM_BUCKETS; i++) {
1187 list_for_each_entry (hc, _name_buckets + i, name_list) {
1188+ if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT))
1189+ continue;
1190 needed += sizeof(struct dm_name_list);
1191 needed += strlen(hc->name) + 1;
1192 needed += ALIGN_MASK;
c2e5f7c8 1193@@ -537,6 +547,8 @@ static int list_devices(struct dm_ioctl
3bac966d
AM
1194 */
1195 for (i = 0; i < NUM_BUCKETS; i++) {
1196 list_for_each_entry (hc, _name_buckets + i, name_list) {
1197+ if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT))
1198+ continue;
1199 if (old_nl)
1200 old_nl->next = (uint32_t) ((void *) nl -
1201 (void *) old_nl);
cc23e853 1202@@ -1805,8 +1817,8 @@ static int ctl_ioctl(uint command, struc
763640ca 1203 size_t input_param_size;
b00e13aa 1204 struct dm_ioctl param_kernel;
3bac966d
AM
1205
1206- /* only root can play with this */
1207- if (!capable(CAP_SYS_ADMIN))
1208+ /* only root and certain contexts can play with this */
1209+ if (!vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_MAPPER))
1210 return -EACCES;
1211
1212 if (_IOC_TYPE(command) != DM_IOCTL)
cef7ea10
AM
1213diff -NurpP --minimal linux-4.9.82/drivers/md/dm.c linux-4.9.82-vs2.3.9.7/drivers/md/dm.c
1214--- linux-4.9.82/drivers/md/dm.c 2018-02-22 21:18:28.000000000 +0000
1215+++ linux-4.9.82-vs2.3.9.7/drivers/md/dm.c 2018-01-10 08:32:35.000000000 +0000
cc23e853
AM
1216@@ -22,6 +22,7 @@
1217 #include <linux/wait.h>
1218 #include <linux/pr.h>
1219 #include <linux/vmalloc.h>
d33d7b00
AM
1220+#include <linux/vs_base.h>
1221
cc23e853 1222 #define DM_MSG_PREFIX "core"
d33d7b00 1223
cc23e853 1224@@ -300,6 +301,7 @@ int dm_deleting_md(struct mapped_device
d33d7b00
AM
1225 static int dm_blk_open(struct block_device *bdev, fmode_t mode)
1226 {
1227 struct mapped_device *md;
1228+ int ret = -ENXIO;
1229
1230 spin_lock(&_minor_lock);
1231
cc23e853 1232@@ -308,17 +310,19 @@ static int dm_blk_open(struct block_devi
d33d7b00
AM
1233 goto out;
1234
1235 if (test_bit(DMF_FREEING, &md->flags) ||
1236- dm_deleting_md(md)) {
1237- md = NULL;
1238+ dm_deleting_md(md))
1239+ goto out;
1240+
1241+ ret = -EACCES;
1242+ if (!vx_check(md->xid, VS_IDENT|VS_HOSTID))
1243 goto out;
1244- }
1245
1246 dm_get(md);
1247 atomic_inc(&md->open_count);
d33d7b00
AM
1248+ ret = 0;
1249 out:
1250 spin_unlock(&_minor_lock);
1251-
1252- return md ? 0 : -ENXIO;
1253+ return ret;
1254 }
1255
09be7631 1256 static void dm_blk_close(struct gendisk *disk, fmode_t mode)
cc23e853 1257@@ -744,6 +748,14 @@ int dm_set_geometry(struct mapped_device
d33d7b00
AM
1258 return 0;
1259 }
1260
1261+/*
1262+ * Get the xid associated with a dm device
1263+ */
61333608 1264+vxid_t dm_get_xid(struct mapped_device *md)
d33d7b00
AM
1265+{
1266+ return md->xid;
1267+}
1268+
1269 /*-----------------------------------------------------------------
1270 * CRUD START:
1271 * A more elegant soln is in the works that uses the queue
cc23e853
AM
1272@@ -1548,6 +1560,7 @@ static struct mapped_device *alloc_dev(i
1273 INIT_LIST_HEAD(&md->uevent_list);
bb20add7 1274 INIT_LIST_HEAD(&md->table_devices);
d33d7b00 1275 spin_lock_init(&md->uevent_lock);
d33d7b00 1276+ md->xid = vx_current_xid();
cc23e853
AM
1277
1278 md->queue = blk_alloc_queue_node(GFP_KERNEL, numa_node_id);
d33d7b00 1279 if (!md->queue)
cef7ea10
AM
1280diff -NurpP --minimal linux-4.9.82/drivers/md/dm.h linux-4.9.82-vs2.3.9.7/drivers/md/dm.h
1281--- linux-4.9.82/drivers/md/dm.h 2016-12-11 19:17:54.000000000 +0000
1282+++ linux-4.9.82-vs2.3.9.7/drivers/md/dm.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 1283@@ -45,6 +45,8 @@ struct dm_dev_internal {
d33d7b00
AM
1284 struct dm_table;
1285 struct dm_md_mempools;
1286
61333608 1287+vxid_t dm_get_xid(struct mapped_device *md);
d33d7b00
AM
1288+
1289 /*-----------------------------------------------------------------
1290 * Internal table functions.
1291 *---------------------------------------------------------------*/
cef7ea10
AM
1292diff -NurpP --minimal linux-4.9.82/drivers/net/tun.c linux-4.9.82-vs2.3.9.7/drivers/net/tun.c
1293--- linux-4.9.82/drivers/net/tun.c 2018-02-22 21:18:32.000000000 +0000
1294+++ linux-4.9.82-vs2.3.9.7/drivers/net/tun.c 2018-02-10 15:15:43.000000000 +0000
c2e5f7c8 1295@@ -65,6 +65,7 @@
d33d7b00
AM
1296 #include <linux/nsproxy.h>
1297 #include <linux/virtio_net.h>
1298 #include <linux/rcupdate.h>
1299+#include <linux/vs_network.h>
1300 #include <net/net_namespace.h>
1301 #include <net/netns/generic.h>
cc23e853
AM
1302 #include <net/rtnetlink.h>
1303@@ -194,6 +195,7 @@ struct tun_struct {
d33d7b00 1304 unsigned int flags;
537831f9
AM
1305 kuid_t owner;
1306 kgid_t group;
61333608 1307+ vnid_t nid;
d33d7b00
AM
1308
1309 struct net_device *dev;
db55b927 1310 netdev_features_t set_features;
cc23e853 1311@@ -490,6 +492,7 @@ static inline bool tun_not_capable(struc
b00e13aa
AM
1312 return ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) ||
1313 (gid_valid(tun->group) && !in_egroup_p(tun->group))) &&
1314 !ns_capable(net->user_ns, CAP_NET_ADMIN);
1315+ /* !cap_raised(current_cap(), CAP_NET_ADMIN) */
1316 }
1317
1318 static void tun_set_real_num_queues(struct tun_struct *tun)
5ba7a31c 1319@@ -1558,6 +1561,7 @@ static void tun_setup(struct net_device
2380c486 1320
537831f9
AM
1321 tun->owner = INVALID_UID;
1322 tun->group = INVALID_GID;
1323+ tun->nid = nx_current_nid();
2380c486 1324
ec22aa5c
AM
1325 dev->ethtool_ops = &tun_ethtool_ops;
1326 dev->destructor = tun_free_netdev;
5ba7a31c 1327@@ -1769,7 +1773,7 @@ static int tun_set_iff(struct net *net,
b00e13aa
AM
1328 int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ?
1329 MAX_TAP_QUEUES : 1;
1330
1331- if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
c2e5f7c8 1332+ if (!nx_ns_capable(net->user_ns, CAP_NET_ADMIN, NXC_TUN_CREATE))
b00e13aa
AM
1333 return -EPERM;
1334 err = security_tun_dev_create();
1335 if (err < 0)
5ba7a31c 1336@@ -2134,6 +2138,16 @@ static long __tun_chr_ioctl(struct file
537831f9 1337 from_kgid(&init_user_ns, tun->group));
2380c486 1338 break;
d337f35e 1339
2380c486
JR
1340+ case TUNSETNID:
1341+ if (!capable(CAP_CONTEXT))
1342+ return -EPERM;
d337f35e 1343+
2380c486 1344+ /* Set nid owner of the device */
61333608 1345+ tun->nid = (vnid_t) arg;
d337f35e 1346+
763640ca 1347+ tun_debug(KERN_INFO, tun, "nid owner set to %u\n", tun->nid);
2380c486 1348+ break;
d337f35e 1349+
2380c486
JR
1350 case TUNSETLINK:
1351 /* Only allow setting the type when the interface is down */
ec22aa5c 1352 if (tun->dev->flags & IFF_UP) {
cef7ea10
AM
1353diff -NurpP --minimal linux-4.9.82/drivers/scsi/cxgbi/libcxgbi.c linux-4.9.82-vs2.3.9.7/drivers/scsi/cxgbi/libcxgbi.c
1354--- linux-4.9.82/drivers/scsi/cxgbi/libcxgbi.c 2016-12-11 19:17:54.000000000 +0000
1355+++ linux-4.9.82-vs2.3.9.7/drivers/scsi/cxgbi/libcxgbi.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 1356@@ -772,7 +772,8 @@ static struct cxgbi_sock *cxgbi_check_ro
bb20add7
AM
1357 struct inet6_dev *idev = ip6_dst_idev((struct dst_entry *)rt);
1358
1359 err = ipv6_dev_get_saddr(&init_net, idev ? idev->dev : NULL,
1360- &daddr6->sin6_addr, 0, &pref_saddr);
1361+ &daddr6->sin6_addr, 0, &pref_saddr,
1362+ NULL);
1363 if (err) {
1364 pr_info("failed to get source address to reach %pI6\n",
1365 &daddr6->sin6_addr);
cef7ea10
AM
1366diff -NurpP --minimal linux-4.9.82/drivers/tty/sysrq.c linux-4.9.82-vs2.3.9.7/drivers/tty/sysrq.c
1367--- linux-4.9.82/drivers/tty/sysrq.c 2018-02-22 21:18:37.000000000 +0000
1368+++ linux-4.9.82-vs2.3.9.7/drivers/tty/sysrq.c 2018-01-10 02:50:49.000000000 +0000
bb20add7 1369@@ -47,6 +47,7 @@
c2e5f7c8
JR
1370 #include <linux/syscalls.h>
1371 #include <linux/of.h>
bb20add7 1372 #include <linux/rcupdate.h>
ab30d09f
AM
1373+#include <linux/vserver/debug.h>
1374
1375 #include <asm/ptrace.h>
1376 #include <asm/irq_regs.h>
cc23e853 1377@@ -428,6 +429,21 @@ static struct sysrq_key_op sysrq_unrt_op
ab30d09f
AM
1378 .enable_mask = SYSRQ_ENABLE_RTNICE,
1379 };
1380
1381+
1382+#ifdef CONFIG_VSERVER_DEBUG
1383+static void sysrq_handle_vxinfo(int key)
1384+{
1385+ dump_vx_info_inactive((key == 'x') ? 0 : 1);
1386+}
1387+
1388+static struct sysrq_key_op sysrq_showvxinfo_op = {
1389+ .handler = sysrq_handle_vxinfo,
1390+ .help_msg = "conteXt",
1391+ .action_msg = "Show Context Info",
1392+ .enable_mask = SYSRQ_ENABLE_DUMP,
1393+};
1394+#endif
1395+
1396 /* Key Operations table and lock */
1397 static DEFINE_SPINLOCK(sysrq_key_table_lock);
1398
cc23e853
AM
1399@@ -484,7 +500,11 @@ static struct sysrq_key_op *sysrq_key_ta
1400 /* x: May be registered on mips for TLB dump */
ab30d09f 1401 /* x: May be registered on ppc/powerpc for xmon */
537831f9 1402 /* x: May be registered on sparc64 for global PMU dump */
ab30d09f
AM
1403+#ifdef CONFIG_VSERVER_DEBUG
1404+ &sysrq_showvxinfo_op, /* x */
1405+#else
4bf69007 1406 NULL, /* x */
ab30d09f
AM
1407+#endif
1408 /* y: May be registered on sparc64 for global register dump */
1409 NULL, /* y */
1410 &sysrq_ftrace_dump_op, /* z */
cc23e853 1411@@ -499,6 +519,8 @@ static int sysrq_key_table_key2index(int
ab30d09f
AM
1412 retval = key - '0';
1413 else if ((key >= 'a') && (key <= 'z'))
1414 retval = key + 10 - 'a';
1415+ else if ((key >= 'A') && (key <= 'Z'))
1416+ retval = key + 10 - 'A';
1417 else
1418 retval = -1;
1419 return retval;
cef7ea10
AM
1420diff -NurpP --minimal linux-4.9.82/drivers/tty/tty_io.c linux-4.9.82-vs2.3.9.7/drivers/tty/tty_io.c
1421--- linux-4.9.82/drivers/tty/tty_io.c 2018-02-22 21:18:37.000000000 +0000
1422+++ linux-4.9.82-vs2.3.9.7/drivers/tty/tty_io.c 2018-02-10 15:15:43.000000000 +0000
1e8b8f9b 1423@@ -104,6 +104,7 @@
ab30d09f
AM
1424
1425 #include <linux/kmod.h>
1426 #include <linux/nsproxy.h>
1427+#include <linux/vs_pid.h>
1428
1429 #undef TTY_DEBUG_HANGUP
cc23e853 1430 #ifdef TTY_DEBUG_HANGUP
5ba7a31c 1431@@ -2292,7 +2293,8 @@ static int tiocsti(struct tty_struct *tt
ab30d09f
AM
1432 char ch, mbz = 0;
1433 struct tty_ldisc *ld;
1434
1435- if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN))
1436+ if (((current->signal->tty != tty) &&
1437+ !vx_capable(CAP_SYS_ADMIN, VXC_TIOCSTI)))
1438 return -EPERM;
1439 if (get_user(ch, p))
1440 return -EFAULT;
5ba7a31c 1441@@ -2607,6 +2609,7 @@ static int tiocspgrp(struct tty_struct *
ab30d09f
AM
1442 return -ENOTTY;
1443 if (get_user(pgrp_nr, p))
1444 return -EFAULT;
1445+ pgrp_nr = vx_rmap_pid(pgrp_nr);
1446 if (pgrp_nr < 0)
1447 return -EINVAL;
1448 rcu_read_lock();
cef7ea10
AM
1449diff -NurpP --minimal linux-4.9.82/fs/attr.c linux-4.9.82-vs2.3.9.7/fs/attr.c
1450--- linux-4.9.82/fs/attr.c 2016-12-11 19:17:54.000000000 +0000
1451+++ linux-4.9.82-vs2.3.9.7/fs/attr.c 2018-01-10 02:50:49.000000000 +0000
537831f9 1452@@ -15,6 +15,9 @@
d337f35e 1453 #include <linux/security.h>
f6c5ef8b 1454 #include <linux/evm.h>
537831f9 1455 #include <linux/ima.h>
d337f35e
JR
1456+#include <linux/proc_fs.h>
1457+#include <linux/devpts_fs.h>
2380c486 1458+#include <linux/vs_tag.h>
d337f35e 1459
93de0823 1460 /**
cc23e853
AM
1461 * setattr_prepare - check if attribute changes to a dentry are allowed
1462@@ -90,6 +93,10 @@ kill_priv:
1463 return error;
d337f35e 1464 }
93de0823
AM
1465
1466+ /* check for inode tag permission */
2380c486 1467+ if (dx_permission(inode, MAY_WRITE))
93de0823 1468+ return -EACCES;
2380c486 1469+
93de0823
AM
1470 return 0;
1471 }
cc23e853
AM
1472 EXPORT_SYMBOL(setattr_prepare);
1473@@ -160,6 +167,8 @@ void setattr_copy(struct inode *inode, c
d337f35e
JR
1474 inode->i_uid = attr->ia_uid;
1475 if (ia_valid & ATTR_GID)
1476 inode->i_gid = attr->ia_gid;
1477+ if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode))
1478+ inode->i_tag = attr->ia_tag;
1479 if (ia_valid & ATTR_ATIME)
1480 inode->i_atime = timespec_trunc(attr->ia_atime,
1481 inode->i_sb->s_time_gran);
cc23e853 1482@@ -210,7 +219,8 @@ int notify_change(struct dentry * dentry
92598135 1483
cc23e853 1484 WARN_ON_ONCE(!inode_is_locked(inode));
78865d5b
AM
1485
1486- if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
1487+ if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
1488+ ATTR_TAG | ATTR_TIMES_SET)) {
1489 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1490 return -EPERM;
1491 }
cef7ea10
AM
1492diff -NurpP --minimal linux-4.9.82/fs/block_dev.c linux-4.9.82-vs2.3.9.7/fs/block_dev.c
1493--- linux-4.9.82/fs/block_dev.c 2018-02-22 21:18:42.000000000 +0000
1494+++ linux-4.9.82-vs2.3.9.7/fs/block_dev.c 2018-01-13 00:48:31.000000000 +0000
cc23e853
AM
1495@@ -31,6 +31,7 @@
1496 #include <linux/dax.h>
1497 #include <linux/badblocks.h>
1498 #include <linux/falloc.h>
2380c486
JR
1499+#include <linux/vs_device.h>
1500 #include <asm/uaccess.h>
1501 #include "internal.h"
1502
cc23e853 1503@@ -720,6 +721,7 @@ struct block_device *bdget(dev_t dev)
2380c486
JR
1504 bdev->bd_invalidated = 0;
1505 inode->i_mode = S_IFBLK;
1506 inode->i_rdev = dev;
1507+ inode->i_mdev = dev;
1508 inode->i_bdev = bdev;
1509 inode->i_data.a_ops = &def_blk_aops;
1510 mapping_set_gfp_mask(&inode->i_data, GFP_USER);
cc23e853 1511@@ -766,6 +768,11 @@ EXPORT_SYMBOL(bdput);
2380c486
JR
1512 static struct block_device *bd_acquire(struct inode *inode)
1513 {
1514 struct block_device *bdev;
1515+ dev_t mdev;
1516+
1517+ if (!vs_map_blkdev(inode->i_rdev, &mdev, DATTR_OPEN))
1518+ return NULL;
1519+ inode->i_mdev = mdev;
1520
1521 spin_lock(&bdev_lock);
1522 bdev = inode->i_bdev;
cc23e853 1523@@ -776,7 +783,7 @@ static struct block_device *bd_acquire(s
2380c486
JR
1524 }
1525 spin_unlock(&bdev_lock);
1526
1527- bdev = bdget(inode->i_rdev);
1528+ bdev = bdget(mdev);
1529 if (bdev) {
1530 spin_lock(&bdev_lock);
1531 if (!inode->i_bdev) {
cef7ea10
AM
1532diff -NurpP --minimal linux-4.9.82/fs/btrfs/ctree.h linux-4.9.82-vs2.3.9.7/fs/btrfs/ctree.h
1533--- linux-4.9.82/fs/btrfs/ctree.h 2018-02-22 21:18:43.000000000 +0000
1534+++ linux-4.9.82-vs2.3.9.7/fs/btrfs/ctree.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 1535@@ -1321,6 +1321,8 @@ static inline u32 BTRFS_MAX_XATTR_SIZE(c
c2e5f7c8 1536 #define BTRFS_DEFAULT_COMMIT_INTERVAL (30)
cc23e853 1537 #define BTRFS_DEFAULT_MAX_INLINE (2048)
e22b5178
AM
1538
1539+#define BTRFS_MOUNT_TAGGED (1 << 24)
1540+
1541 #define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt)
1542 #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt)
b00e13aa 1543 #define btrfs_raw_test_opt(o, opt) ((o) & BTRFS_MOUNT_##opt)
cc23e853 1544@@ -1668,6 +1670,7 @@ BTRFS_SETGET_FUNCS(inode_block_group, st
e22b5178
AM
1545 BTRFS_SETGET_FUNCS(inode_nlink, struct btrfs_inode_item, nlink, 32);
1546 BTRFS_SETGET_FUNCS(inode_uid, struct btrfs_inode_item, uid, 32);
1547 BTRFS_SETGET_FUNCS(inode_gid, struct btrfs_inode_item, gid, 32);
1548+BTRFS_SETGET_FUNCS(inode_tag, struct btrfs_inode_item, tag, 16);
1549 BTRFS_SETGET_FUNCS(inode_mode, struct btrfs_inode_item, mode, 32);
1550 BTRFS_SETGET_FUNCS(inode_rdev, struct btrfs_inode_item, rdev, 64);
1551 BTRFS_SETGET_FUNCS(inode_flags, struct btrfs_inode_item, flags, 64);
cc23e853 1552@@ -1715,6 +1718,10 @@ BTRFS_SETGET_FUNCS(extent_flags, struct
78865d5b
AM
1553
1554 BTRFS_SETGET_FUNCS(extent_refs_v0, struct btrfs_extent_item_v0, refs, 32);
1555
1556+#define BTRFS_INODE_IXUNLINK (1 << 24)
1557+#define BTRFS_INODE_BARRIER (1 << 25)
1558+#define BTRFS_INODE_COW (1 << 26)
1559+
1560
1561 BTRFS_SETGET_FUNCS(tree_block_level, struct btrfs_tree_block_info, level, 8);
1562
cc23e853 1563@@ -3197,6 +3204,7 @@ int btrfs_ioctl_get_supported_features(v
d4263eb0
JR
1564 void btrfs_update_iflags(struct inode *inode);
1565 void btrfs_inherit_iflags(struct inode *inode, struct inode *dir);
c2e5f7c8 1566 int btrfs_is_empty_uuid(u8 *uuid);
d4263eb0 1567+int btrfs_sync_flags(struct inode *inode, int, int);
763640ca
JR
1568 int btrfs_defrag_file(struct inode *inode, struct file *file,
1569 struct btrfs_ioctl_defrag_range_args *range,
1570 u64 newer_than, unsigned long max_pages);
cef7ea10
AM
1571diff -NurpP --minimal linux-4.9.82/fs/btrfs/disk-io.c linux-4.9.82-vs2.3.9.7/fs/btrfs/disk-io.c
1572--- linux-4.9.82/fs/btrfs/disk-io.c 2018-02-22 21:18:43.000000000 +0000
1573+++ linux-4.9.82-vs2.3.9.7/fs/btrfs/disk-io.c 2018-01-13 05:55:56.000000000 +0000
cc23e853 1574@@ -2850,6 +2850,9 @@ int open_ctree(struct super_block *sb,
763640ca 1575 goto fail_alloc;
e22b5178
AM
1576 }
1577
cc23e853 1578+ if (btrfs_test_opt(fs_info, TAGGED))
e22b5178
AM
1579+ sb->s_flags |= MS_TAGGED;
1580+
1581 features = btrfs_super_incompat_flags(disk_super) &
1582 ~BTRFS_FEATURE_INCOMPAT_SUPP;
1583 if (features) {
cef7ea10
AM
1584diff -NurpP --minimal linux-4.9.82/fs/btrfs/inode.c linux-4.9.82-vs2.3.9.7/fs/btrfs/inode.c
1585--- linux-4.9.82/fs/btrfs/inode.c 2018-02-22 21:18:43.000000000 +0000
1586+++ linux-4.9.82-vs2.3.9.7/fs/btrfs/inode.c 2018-02-22 21:31:40.000000000 +0000
c2e5f7c8 1587@@ -43,6 +43,7 @@
b00e13aa 1588 #include <linux/blkdev.h>
c2e5f7c8 1589 #include <linux/posix_acl_xattr.h>
cc23e853 1590 #include <linux/uio.h>
e22b5178 1591+#include <linux/vs_tag.h>
e22b5178
AM
1592 #include "ctree.h"
1593 #include "disk-io.h"
c2e5f7c8 1594 #include "transaction.h"
cef7ea10 1595@@ -3669,6 +3670,9 @@ static int btrfs_read_locked_inode(struc
bb20add7 1596 unsigned long ptr;
e22b5178 1597 int maybe_acls;
e22b5178 1598 u32 rdev;
a4a22af8
AM
1599+ kuid_t kuid;
1600+ kgid_t kgid;
1601+ ktag_t ktag;
e22b5178 1602 int ret;
763640ca 1603 bool filled = false;
bb20add7 1604 int first_xattr_slot;
cef7ea10 1605@@ -3701,8 +3705,14 @@ static int btrfs_read_locked_inode(struc
a168f21d 1606 struct btrfs_inode_item);
e22b5178 1607 inode->i_mode = btrfs_inode_mode(leaf, inode_item);
f6c5ef8b 1608 set_nlink(inode, btrfs_inode_nlink(leaf, inode_item));
537831f9
AM
1609- i_uid_write(inode, btrfs_inode_uid(leaf, inode_item));
1610- i_gid_write(inode, btrfs_inode_gid(leaf, inode_item));
e22b5178 1611+
a4a22af8
AM
1612+ kuid = make_kuid(&init_user_ns, btrfs_inode_uid(leaf, inode_item));
1613+ kgid = make_kgid(&init_user_ns, btrfs_inode_gid(leaf, inode_item));
1614+ ktag = make_ktag(&init_user_ns, btrfs_inode_tag(leaf, inode_item));
1615+
1616+ inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
1617+ inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
1618+ inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, ktag);
e22b5178
AM
1619 btrfs_i_size_write(inode, btrfs_inode_size(leaf, inode_item));
1620
cc23e853 1621 inode->i_atime.tv_sec = btrfs_timespec_sec(leaf, &inode_item->atime);
cef7ea10 1622@@ -3857,11 +3867,18 @@ static void fill_inode_item(struct btrfs
e22b5178
AM
1623 struct inode *inode)
1624 {
b00e13aa 1625 struct btrfs_map_token token;
a4a22af8
AM
1626+ uid_t uid = from_kuid(&init_user_ns,
1627+ TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
1628+ gid_t gid = from_kgid(&init_user_ns,
1629+ TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
b00e13aa
AM
1630
1631 btrfs_init_map_token(&token);
1632
1633- btrfs_set_token_inode_uid(leaf, item, i_uid_read(inode), &token);
1634- btrfs_set_token_inode_gid(leaf, item, i_gid_read(inode), &token);
1635+ btrfs_set_token_inode_uid(leaf, item, uid, &token);
1636+ btrfs_set_token_inode_gid(leaf, item, gid, &token);
e22b5178 1637+#ifdef CONFIG_TAGGING_INTERN
b00e13aa 1638+ btrfs_set_token_inode_tag(leaf, item, i_tag_read(inode), &token);
e22b5178 1639+#endif
b00e13aa
AM
1640 btrfs_set_token_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size,
1641 &token);
1642 btrfs_set_token_inode_mode(leaf, item, inode->i_mode, &token);
cef7ea10 1643@@ -10620,6 +10637,7 @@ static const struct inode_operations btr
cc23e853 1644 .mknod = btrfs_mknod,
d4263eb0 1645 .listxattr = btrfs_listxattr,
d4263eb0
JR
1646 .permission = btrfs_permission,
1647+ .sync_flags = btrfs_sync_flags,
a168f21d 1648 .get_acl = btrfs_get_acl,
f15949f2 1649 .set_acl = btrfs_set_acl,
c2e5f7c8 1650 .update_time = btrfs_update_time,
cef7ea10 1651@@ -10628,6 +10646,7 @@ static const struct inode_operations btr
7e46296a 1652 static const struct inode_operations btrfs_dir_ro_inode_operations = {
d4263eb0 1653 .lookup = btrfs_lookup,
d4263eb0 1654 .permission = btrfs_permission,
d4263eb0 1655+ .sync_flags = btrfs_sync_flags,
c2e5f7c8 1656 .update_time = btrfs_update_time,
cc23e853
AM
1657 };
1658
cef7ea10 1659@@ -10693,6 +10712,7 @@ static const struct inode_operations btr
cc23e853 1660 .listxattr = btrfs_listxattr,
c2e5f7c8
JR
1661 .permission = btrfs_permission,
1662 .fiemap = btrfs_fiemap,
1663+ .sync_flags = btrfs_sync_flags,
1664 .get_acl = btrfs_get_acl,
bb20add7 1665 .set_acl = btrfs_set_acl,
c2e5f7c8 1666 .update_time = btrfs_update_time,
cef7ea10
AM
1667diff -NurpP --minimal linux-4.9.82/fs/btrfs/ioctl.c linux-4.9.82-vs2.3.9.7/fs/btrfs/ioctl.c
1668--- linux-4.9.82/fs/btrfs/ioctl.c 2018-02-22 21:18:43.000000000 +0000
1669+++ linux-4.9.82-vs2.3.9.7/fs/btrfs/ioctl.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 1670@@ -110,10 +110,13 @@ static unsigned int btrfs_flags_to_ioctl
d4263eb0
JR
1671 {
1672 unsigned int iflags = 0;
1673
1674- if (flags & BTRFS_INODE_SYNC)
1675- iflags |= FS_SYNC_FL;
1676 if (flags & BTRFS_INODE_IMMUTABLE)
1677 iflags |= FS_IMMUTABLE_FL;
1678+ if (flags & BTRFS_INODE_IXUNLINK)
1679+ iflags |= FS_IXUNLINK_FL;
1680+
1681+ if (flags & BTRFS_INODE_SYNC)
1682+ iflags |= FS_SYNC_FL;
1683 if (flags & BTRFS_INODE_APPEND)
1684 iflags |= FS_APPEND_FL;
1685 if (flags & BTRFS_INODE_NODUMP)
cc23e853
AM
1686@@ -130,34 +133,84 @@ static unsigned int btrfs_flags_to_ioctl
1687 else if (flags & BTRFS_INODE_COMPRESS)
1688 iflags |= FS_COMPR_FL;
d4263eb0
JR
1689
1690+ if (flags & BTRFS_INODE_BARRIER)
1691+ iflags |= FS_BARRIER_FL;
1692+ if (flags & BTRFS_INODE_COW)
1693+ iflags |= FS_COW_FL;
1694 return iflags;
1695 }
1696
1697 /*
1698- * Update inode->i_flags based on the btrfs internal flags.
1699+ * Update inode->i_(v)flags based on the btrfs internal flags.
1700 */
1701 void btrfs_update_iflags(struct inode *inode)
1702 {
1703 struct btrfs_inode *ip = BTRFS_I(inode);
bb20add7 1704 unsigned int new_fl = 0;
d4263eb0
JR
1705
1706- if (ip->flags & BTRFS_INODE_SYNC)
bb20add7 1707- new_fl |= S_SYNC;
d4263eb0 1708 if (ip->flags & BTRFS_INODE_IMMUTABLE)
bb20add7 1709 new_fl |= S_IMMUTABLE;
d4263eb0 1710+ if (ip->flags & BTRFS_INODE_IXUNLINK)
bb20add7 1711+ new_fl |= S_IXUNLINK;
d4263eb0
JR
1712+
1713+ if (ip->flags & BTRFS_INODE_SYNC)
bb20add7 1714+ new_fl |= S_SYNC;
d4263eb0 1715 if (ip->flags & BTRFS_INODE_APPEND)
bb20add7 1716 new_fl |= S_APPEND;
d4263eb0 1717 if (ip->flags & BTRFS_INODE_NOATIME)
bb20add7 1718 new_fl |= S_NOATIME;
d4263eb0 1719 if (ip->flags & BTRFS_INODE_DIRSYNC)
bb20add7
AM
1720 new_fl |= S_DIRSYNC;
1721-
1722 set_mask_bits(&inode->i_flags,
1723- S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC,
1724+ S_SYNC | S_APPEND | S_IMMUTABLE | S_IXUNLINK | S_NOATIME | S_DIRSYNC,
1725 new_fl);
d4263eb0 1726+
bb20add7 1727+ new_fl = 0;
d4263eb0 1728+ if (ip->flags & BTRFS_INODE_BARRIER)
bb20add7 1729+ new_fl |= V_BARRIER;
d4263eb0 1730+ if (ip->flags & BTRFS_INODE_COW)
bb20add7 1731+ new_fl |= V_COW;
d4263eb0 1732+
bb20add7
AM
1733+ set_mask_bits(&inode->i_vflags,
1734+ V_BARRIER | V_COW, new_fl);
1735 }
1736
1737 /*
d4263eb0
JR
1738+ * Update btrfs internal flags from inode->i_(v)flags.
1739+ */
1740+void btrfs_update_flags(struct inode *inode)
1741+{
1742+ struct btrfs_inode *ip = BTRFS_I(inode);
1743+
1744+ unsigned int flags = inode->i_flags;
1745+ unsigned int vflags = inode->i_vflags;
1746+
1747+ ip->flags &= ~(BTRFS_INODE_SYNC | BTRFS_INODE_APPEND |
1748+ BTRFS_INODE_IMMUTABLE | BTRFS_INODE_IXUNLINK |
1749+ BTRFS_INODE_NOATIME | BTRFS_INODE_DIRSYNC |
1750+ BTRFS_INODE_BARRIER | BTRFS_INODE_COW);
1751+
1752+ if (flags & S_IMMUTABLE)
1753+ ip->flags |= BTRFS_INODE_IMMUTABLE;
1754+ if (flags & S_IXUNLINK)
1755+ ip->flags |= BTRFS_INODE_IXUNLINK;
1756+
1757+ if (flags & S_SYNC)
1758+ ip->flags |= BTRFS_INODE_SYNC;
1759+ if (flags & S_APPEND)
1760+ ip->flags |= BTRFS_INODE_APPEND;
1761+ if (flags & S_NOATIME)
1762+ ip->flags |= BTRFS_INODE_NOATIME;
1763+ if (flags & S_DIRSYNC)
1764+ ip->flags |= BTRFS_INODE_DIRSYNC;
1765+
1766+ if (vflags & V_BARRIER)
1767+ ip->flags |= BTRFS_INODE_BARRIER;
1768+ if (vflags & V_COW)
1769+ ip->flags |= BTRFS_INODE_COW;
bb20add7
AM
1770+ }
1771+
1772+/*
1773 * Inherit flags from the parent inode.
1774 *
1775 * Currently only the compression flags and the cow flags are inherited.
cc23e853 1776@@ -170,6 +223,7 @@ void btrfs_inherit_iflags(struct inode *
f6c5ef8b 1777 return;
d4263eb0 1778
f6c5ef8b
AM
1779 flags = BTRFS_I(dir)->flags;
1780+ flags &= ~BTRFS_INODE_BARRIER;
d4263eb0 1781
f6c5ef8b
AM
1782 if (flags & BTRFS_INODE_NOCOMPRESS) {
1783 BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS;
cc23e853 1784@@ -188,6 +242,30 @@ void btrfs_inherit_iflags(struct inode *
d4263eb0
JR
1785 btrfs_update_iflags(inode);
1786 }
1787
1788+int btrfs_sync_flags(struct inode *inode, int flags, int vflags)
1789+{
1790+ struct btrfs_inode *ip = BTRFS_I(inode);
1791+ struct btrfs_root *root = ip->root;
1792+ struct btrfs_trans_handle *trans;
1793+ int ret;
1794+
763640ca 1795+ trans = btrfs_join_transaction(root);
d4263eb0
JR
1796+ BUG_ON(!trans);
1797+
d4263eb0
JR
1798+ inode->i_flags = flags;
1799+ inode->i_vflags = vflags;
1800+ btrfs_update_flags(inode);
e22b5178
AM
1801+
1802+ ret = btrfs_update_inode(trans, root, inode);
1803+ BUG_ON(ret);
1804+
1805+ btrfs_update_iflags(inode);
d4263eb0
JR
1806+ inode->i_ctime = CURRENT_TIME;
1807+ btrfs_end_transaction(trans, root);
1808+
1809+ return 0;
1810+}
1811+
1812 static int btrfs_ioctl_getflags(struct file *file, void __user *arg)
1813 {
b00e13aa 1814 struct btrfs_inode *ip = BTRFS_I(file_inode(file));
cc23e853 1815@@ -250,21 +328,27 @@ static int btrfs_ioctl_setflags(struct f
d4263eb0
JR
1816
1817 flags = btrfs_mask_flags(inode->i_mode, flags);
1818 oldflags = btrfs_flags_to_ioctl(ip->flags);
1819- if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) {
1820+ if ((flags ^ oldflags) & (FS_APPEND_FL |
1821+ FS_IMMUTABLE_FL | FS_IXUNLINK_FL)) {
1822 if (!capable(CAP_LINUX_IMMUTABLE)) {
1823 ret = -EPERM;
1824 goto out_unlock;
92598135
AM
1825 }
1826 }
d4263eb0
JR
1827
1828- if (flags & FS_SYNC_FL)
1829- ip->flags |= BTRFS_INODE_SYNC;
1830- else
1831- ip->flags &= ~BTRFS_INODE_SYNC;
1832 if (flags & FS_IMMUTABLE_FL)
1833 ip->flags |= BTRFS_INODE_IMMUTABLE;
1834 else
1835 ip->flags &= ~BTRFS_INODE_IMMUTABLE;
1836+ if (flags & FS_IXUNLINK_FL)
1837+ ip->flags |= BTRFS_INODE_IXUNLINK;
1838+ else
1839+ ip->flags &= ~BTRFS_INODE_IXUNLINK;
1840+
1841+ if (flags & FS_SYNC_FL)
1842+ ip->flags |= BTRFS_INODE_SYNC;
1843+ else
1844+ ip->flags &= ~BTRFS_INODE_SYNC;
1845 if (flags & FS_APPEND_FL)
1846 ip->flags |= BTRFS_INODE_APPEND;
1847 else
cef7ea10
AM
1848diff -NurpP --minimal linux-4.9.82/fs/btrfs/super.c linux-4.9.82-vs2.3.9.7/fs/btrfs/super.c
1849--- linux-4.9.82/fs/btrfs/super.c 2018-02-22 21:18:43.000000000 +0000
1850+++ linux-4.9.82-vs2.3.9.7/fs/btrfs/super.c 2018-01-13 05:51:52.000000000 +0000
cc23e853
AM
1851@@ -327,7 +327,7 @@ enum {
1852 #ifdef CONFIG_BTRFS_DEBUG
1853 Opt_fragment_data, Opt_fragment_metadata, Opt_fragment_all,
1854 #endif
db55b927 1855- Opt_err,
f6c5ef8b 1856+ Opt_tag, Opt_notag, Opt_tagid, Opt_err,
e22b5178
AM
1857 };
1858
cc23e853
AM
1859 static const match_table_t tokens = {
1860@@ -388,6 +388,9 @@ static const match_table_t tokens = {
1861 {Opt_fragment_metadata, "fragment=metadata"},
1862 {Opt_fragment_all, "fragment=all"},
1863 #endif
e22b5178
AM
1864+ {Opt_tag, "tag"},
1865+ {Opt_notag, "notag"},
1866+ {Opt_tagid, "tagid=%u"},
1867 {Opt_err, NULL},
1868 };
1869
cc23e853
AM
1870@@ -833,6 +836,22 @@ int btrfs_parse_options(struct btrfs_roo
1871 btrfs_set_opt(info->mount_opt, FRAGMENT_DATA);
1e8b8f9b 1872 break;
cc23e853 1873 #endif
e22b5178
AM
1874+#ifndef CONFIG_TAGGING_NONE
1875+ case Opt_tag:
1876+ printk(KERN_INFO "btrfs: use tagging\n");
1877+ btrfs_set_opt(info->mount_opt, TAGGED);
1878+ break;
1879+ case Opt_notag:
1880+ printk(KERN_INFO "btrfs: disabled tagging\n");
1881+ btrfs_clear_opt(info->mount_opt, TAGGED);
1882+ break;
1883+#endif
1884+#ifdef CONFIG_PROPAGATE
1885+ case Opt_tagid:
1886+ /* use args[0] */
1887+ btrfs_set_opt(info->mount_opt, TAGGED);
1888+ break;
1889+#endif
2bf5ad28 1890 case Opt_err:
cc23e853
AM
1891 btrfs_info(root->fs_info,
1892 "unrecognized mount option '%s'", p);
1893@@ -1754,6 +1773,12 @@ static int btrfs_remount(struct super_bl
42bc425c
AM
1894 btrfs_resize_thread_pool(fs_info,
1895 fs_info->thread_pool_size, old_thread_pool_size);
e22b5178 1896
cc23e853 1897+ if (btrfs_test_opt(fs_info, TAGGED) && !(sb->s_flags & MS_TAGGED)) {
e22b5178
AM
1898+ printk("btrfs: %s: tagging not permitted on remount.\n",
1899+ sb->s_id);
1900+ return -EINVAL;
1901+ }
1902+
1903 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
b00e13aa 1904 goto out;
e22b5178 1905
cef7ea10
AM
1906diff -NurpP --minimal linux-4.9.82/fs/char_dev.c linux-4.9.82-vs2.3.9.7/fs/char_dev.c
1907--- linux-4.9.82/fs/char_dev.c 2016-12-11 19:17:54.000000000 +0000
1908+++ linux-4.9.82-vs2.3.9.7/fs/char_dev.c 2018-01-10 02:50:49.000000000 +0000
4744a4b1 1909@@ -21,6 +21,8 @@
2380c486
JR
1910 #include <linux/mutex.h>
1911 #include <linux/backing-dev.h>
7942c842 1912 #include <linux/tty.h>
2380c486
JR
1913+#include <linux/vs_context.h>
1914+#include <linux/vs_device.h>
1915
ec22aa5c
AM
1916 #include "internal.h"
1917
cc23e853 1918@@ -354,14 +356,21 @@ static int chrdev_open(struct inode *ino
2380c486
JR
1919 struct cdev *p;
1920 struct cdev *new = NULL;
1921 int ret = 0;
1922+ dev_t mdev;
1923+
1924+ if (!vs_map_chrdev(inode->i_rdev, &mdev, DATTR_OPEN))
1925+ return -EPERM;
1926+ inode->i_mdev = mdev;
1927
1928 spin_lock(&cdev_lock);
1929 p = inode->i_cdev;
1930 if (!p) {
1931 struct kobject *kobj;
1932 int idx;
1933+
1934 spin_unlock(&cdev_lock);
1935- kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
1936+
1937+ kobj = kobj_lookup(cdev_map, mdev, &idx);
1938 if (!kobj)
1939 return -ENXIO;
1940 new = container_of(kobj, struct cdev, kobj);
cef7ea10
AM
1941diff -NurpP --minimal linux-4.9.82/fs/dcache.c linux-4.9.82-vs2.3.9.7/fs/dcache.c
1942--- linux-4.9.82/fs/dcache.c 2018-02-22 21:18:45.000000000 +0000
1943+++ linux-4.9.82-vs2.3.9.7/fs/dcache.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 1944@@ -39,6 +39,7 @@
f6c5ef8b 1945 #include <linux/ratelimit.h>
c2e5f7c8 1946 #include <linux/list_lru.h>
cc23e853 1947 #include <linux/kasan.h>
d337f35e 1948+#include <linux/vs_limit.h>
cc23e853 1949
d337f35e 1950 #include "internal.h"
db55b927 1951 #include "mount.h"
cc23e853
AM
1952@@ -680,6 +681,7 @@ static inline bool fast_dput(struct dent
1953 spin_lock(&dentry->d_lock);
1954 if (dentry->d_lockref.count > 1) {
1955 dentry->d_lockref.count--;
1956+ vx_dentry_dec(dentry);
1957 spin_unlock(&dentry->d_lock);
1958 return 1;
1959 }
1960@@ -811,6 +813,7 @@ repeat:
1961 dentry_lru_add(dentry);
d337f35e 1962
cc23e853
AM
1963 dentry->d_lockref.count--;
1964+ vx_dentry_dec(dentry);
1965 spin_unlock(&dentry->d_lock);
1966 return;
1967
1968@@ -828,6 +831,7 @@ EXPORT_SYMBOL(dput);
d33d7b00 1969 static inline void __dget_dlock(struct dentry *dentry)
2380c486 1970 {
c2e5f7c8 1971 dentry->d_lockref.count++;
2380c486 1972+ vx_dentry_inc(dentry);
d337f35e 1973 }
2380c486 1974
d33d7b00 1975 static inline void __dget(struct dentry *dentry)
cc23e853 1976@@ -840,6 +844,8 @@ struct dentry *dget_parent(struct dentry
bb20add7
AM
1977 int gotref;
1978 struct dentry *ret;
1979
1980+ vx_dentry_dec(dentry);
1981+
1982 /*
1983 * Do optimistic parent lookup without any
1984 * locking.
cc23e853
AM
1985@@ -870,6 +876,7 @@ repeat:
1986 rcu_read_unlock();
1987 BUG_ON(!ret->d_lockref.count);
1988 ret->d_lockref.count++;
1989+ vx_dentry_inc(ret);
1990 spin_unlock(&ret->d_lock);
1991 return ret;
1992 }
1993@@ -1024,6 +1031,7 @@ static void shrink_dentry_list(struct li
1994 parent = lock_parent(dentry);
1995 if (dentry->d_lockref.count != 1) {
1996 dentry->d_lockref.count--;
1997+ vx_dentry_dec(dentry);
1998 spin_unlock(&dentry->d_lock);
1999 if (parent)
2000 spin_unlock(&parent->d_lock);
2001@@ -1590,6 +1598,9 @@ struct dentry *__d_alloc(struct super_bl
d337f35e 2002 char *dname;
cc23e853 2003 int err;
d337f35e
JR
2004
2005+ if (!vx_dentry_avail(1))
2006+ return NULL;
2007+
2380c486 2008 dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
d337f35e
JR
2009 if (!dentry)
2010 return NULL;
cc23e853 2011@@ -1633,6 +1644,7 @@ struct dentry *__d_alloc(struct super_bl
d337f35e 2012
c2e5f7c8 2013 dentry->d_lockref.count = 1;
763640ca 2014 dentry->d_flags = 0;
ab30d09f 2015+ vx_dentry_inc(dentry);
ab30d09f 2016 spin_lock_init(&dentry->d_lock);
d33d7b00 2017 seqcount_init(&dentry->d_seq);
763640ca 2018 dentry->d_inode = NULL;
cc23e853
AM
2019@@ -2282,6 +2294,7 @@ struct dentry *__d_lookup(const struct d
2020 goto next;
2380c486 2021
c2e5f7c8 2022 dentry->d_lockref.count++;
2380c486
JR
2023+ vx_dentry_inc(dentry);
2024 found = dentry;
d337f35e 2025 spin_unlock(&dentry->d_lock);
2380c486 2026 break;
cc23e853
AM
2027@@ -3532,6 +3545,7 @@ static enum d_walk_ret d_genocide_kill(v
2028 if (!(dentry->d_flags & DCACHE_GENOCIDE)) {
2029 dentry->d_flags |= DCACHE_GENOCIDE;
2030 dentry->d_lockref.count--;
2031+ vx_dentry_dec(dentry);
2032 }
2033 }
2034 return D_WALK_CONTINUE;
cef7ea10
AM
2035diff -NurpP --minimal linux-4.9.82/fs/devpts/inode.c linux-4.9.82-vs2.3.9.7/fs/devpts/inode.c
2036--- linux-4.9.82/fs/devpts/inode.c 2016-12-11 19:17:54.000000000 +0000
2037+++ linux-4.9.82-vs2.3.9.7/fs/devpts/inode.c 2018-01-13 01:06:29.000000000 +0000
bb20add7 2038@@ -27,6 +27,7 @@
d337f35e 2039 #include <linux/parser.h>
2380c486
JR
2040 #include <linux/fsnotify.h>
2041 #include <linux/seq_file.h>
d337f35e
JR
2042+#include <linux/vs_base.h>
2043
2380c486 2044 #define DEVPTS_DEFAULT_MODE 0600
ec22aa5c 2045 /*
bb20add7 2046@@ -38,6 +39,21 @@
ec22aa5c
AM
2047 #define DEVPTS_DEFAULT_PTMX_MODE 0000
2048 #define PTMX_MINOR 2
2380c486 2049
a168f21d 2050+static int devpts_permission(struct inode *inode, int mask)
d337f35e
JR
2051+{
2052+ int ret = -EACCES;
2053+
2054+ /* devpts is xid tagged */
61333608 2055+ if (vx_check((vxid_t)i_tag_read(inode), VS_WATCH_P | VS_IDENT))
a168f21d 2056+ ret = generic_permission(inode, mask);
d337f35e
JR
2057+ return ret;
2058+}
2059+
2060+static struct inode_operations devpts_file_inode_operations = {
2061+ .permission = devpts_permission,
2062+};
2380c486 2063+
1e8b8f9b
AM
2064+
2065 /*
2066 * sysctl support for setting limits on the number of Unix98 ptys allocated.
2067 * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly.
cc23e853 2068@@ -363,6 +379,34 @@ static int devpts_show_options(struct se
d337f35e
JR
2069 return 0;
2070 }
2071
2072+static int devpts_filter(struct dentry *de)
2073+{
61333608 2074+ vxid_t xid = 0;
b3b0d4fd 2075+
d337f35e 2076+ /* devpts is xid tagged */
b3b0d4fd 2077+ if (de && de->d_inode)
61333608 2078+ xid = (vxid_t)i_tag_read(de->d_inode);
b3b0d4fd
AM
2079+#ifdef CONFIG_VSERVER_WARN_DEVPTS
2080+ else
2081+ vxwprintk_task(1, "devpts " VS_Q("%.*s") " without inode.",
2082+ de->d_name.len, de->d_name.name);
2083+#endif
2084+ return vx_check(xid, VS_WATCH_P | VS_IDENT);
d337f35e
JR
2085+}
2086+
c2e5f7c8 2087+static int devpts_readdir(struct file * filp, struct dir_context *ctx)
d337f35e 2088+{
c2e5f7c8 2089+ return dcache_readdir_filter(filp, ctx, devpts_filter);
d337f35e
JR
2090+}
2091+
2092+static struct file_operations devpts_dir_operations = {
2093+ .open = dcache_dir_open,
2094+ .release = dcache_dir_close,
2095+ .llseek = dcache_dir_lseek,
2096+ .read = generic_read_dir,
c2e5f7c8 2097+ .iterate = devpts_readdir,
d337f35e
JR
2098+};
2099+
2380c486 2100 static const struct super_operations devpts_sops = {
d337f35e
JR
2101 .statfs = simple_statfs,
2102 .remount_fs = devpts_remount,
cc23e853
AM
2103@@ -415,8 +459,10 @@ devpts_fill_super(struct super_block *s,
2104 inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
d337f35e
JR
2105 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
2106 inode->i_op = &simple_dir_inode_operations;
2107- inode->i_fop = &simple_dir_operations;
2108+ inode->i_fop = &devpts_dir_operations;
f6c5ef8b 2109 set_nlink(inode, 2);
d337f35e 2110+ /* devpts is xid tagged */
61333608 2111+ i_tag_write(inode, (vtag_t)vx_current_xid());
d337f35e 2112
1e8b8f9b 2113 s->s_root = d_make_root(inode);
cc23e853
AM
2114 if (!s->s_root) {
2115@@ -542,6 +588,9 @@ struct dentry *devpts_pty_new(struct pts
ec22aa5c 2116 inode->i_gid = opts->setgid ? opts->gid : current_fsgid();
cc23e853
AM
2117 inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
2118 init_special_inode(inode, S_IFCHR|opts->mode, MKDEV(UNIX98_PTY_SLAVE_MAJOR, index));
d337f35e 2119+ /* devpts is xid tagged */
61333608 2120+ i_tag_write(inode, (vtag_t)vx_current_xid());
d337f35e 2121+ inode->i_op = &devpts_file_inode_operations;
d337f35e 2122
b00e13aa 2123 sprintf(s, "%d", index);
cc23e853 2124
cef7ea10
AM
2125diff -NurpP --minimal linux-4.9.82/fs/ext2/balloc.c linux-4.9.82-vs2.3.9.7/fs/ext2/balloc.c
2126--- linux-4.9.82/fs/ext2/balloc.c 2016-12-11 19:17:54.000000000 +0000
2127+++ linux-4.9.82-vs2.3.9.7/fs/ext2/balloc.c 2018-01-10 02:50:49.000000000 +0000
b00e13aa 2128@@ -693,7 +693,6 @@ ext2_try_to_allocate(struct super_block
2380c486
JR
2129 start = 0;
2130 end = EXT2_BLOCKS_PER_GROUP(sb);
d337f35e 2131 }
2380c486
JR
2132-
2133 BUG_ON(start > EXT2_BLOCKS_PER_GROUP(sb));
2134
2135 repeat:
cef7ea10
AM
2136diff -NurpP --minimal linux-4.9.82/fs/ext2/ext2.h linux-4.9.82-vs2.3.9.7/fs/ext2/ext2.h
2137--- linux-4.9.82/fs/ext2/ext2.h 2016-12-11 19:17:54.000000000 +0000
2138+++ linux-4.9.82-vs2.3.9.7/fs/ext2/ext2.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 2139@@ -247,8 +247,12 @@ struct ext2_group_desc
1e8b8f9b
AM
2140 #define EXT2_NOTAIL_FL FS_NOTAIL_FL /* file tail should not be merged */
2141 #define EXT2_DIRSYNC_FL FS_DIRSYNC_FL /* dirsync behaviour (directories only) */
2142 #define EXT2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/
2143+#define EXT2_IXUNLINK_FL FS_IXUNLINK_FL /* Immutable invert on unlink */
2144 #define EXT2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */
2145
2146+#define EXT2_BARRIER_FL FS_BARRIER_FL /* Barrier for chroot() */
2147+#define EXT2_COW_FL FS_COW_FL /* Copy on Write marker */
2148+
2149 #define EXT2_FL_USER_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */
2150 #define EXT2_FL_USER_MODIFIABLE FS_FL_USER_MODIFIABLE /* User modifiable flags */
2151
cc23e853 2152@@ -332,7 +336,8 @@ struct ext2_inode {
1e8b8f9b
AM
2153 __u16 i_pad1;
2154 __le16 l_i_uid_high; /* these 2 fields */
2155 __le16 l_i_gid_high; /* were reserved2[0] */
2156- __u32 l_i_reserved2;
2157+ __le16 l_i_tag; /* Context Tag */
2158+ __u16 l_i_reserved2;
2159 } linux2;
2160 struct {
2161 __u8 h_i_frag; /* Fragment number */
cc23e853 2162@@ -360,6 +365,7 @@ struct ext2_inode {
1e8b8f9b
AM
2163 #define i_gid_low i_gid
2164 #define i_uid_high osd2.linux2.l_i_uid_high
2165 #define i_gid_high osd2.linux2.l_i_gid_high
2166+#define i_raw_tag osd2.linux2.l_i_tag
2167 #define i_reserved2 osd2.linux2.l_i_reserved2
2168
2169 /*
cc23e853
AM
2170@@ -393,6 +399,7 @@ struct ext2_inode {
2171 #else
2172 #define EXT2_MOUNT_DAX 0
2173 #endif
2174+#define EXT2_MOUNT_TAGGED 0x200000 /* Enable Context Tags */
1e8b8f9b
AM
2175
2176
2177 #define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
cc23e853 2178@@ -782,6 +789,7 @@ extern void ext2_set_inode_flags(struct
93de0823
AM
2179 extern void ext2_get_inode_flags(struct ext2_inode_info *);
2180 extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
2181 u64 start, u64 len);
d4263eb0
JR
2182+extern int ext2_sync_flags(struct inode *, int, int);
2183
2184 /* ioctl.c */
2185 extern long ext2_ioctl(struct file *, unsigned int, unsigned long);
cef7ea10
AM
2186diff -NurpP --minimal linux-4.9.82/fs/ext2/file.c linux-4.9.82-vs2.3.9.7/fs/ext2/file.c
2187--- linux-4.9.82/fs/ext2/file.c 2016-12-11 19:17:54.000000000 +0000
2188+++ linux-4.9.82-vs2.3.9.7/fs/ext2/file.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 2189@@ -247,4 +247,5 @@ const struct inode_operations ext2_file_
a168f21d 2190 .get_acl = ext2_get_acl,
bb20add7 2191 .set_acl = ext2_set_acl,
ec22aa5c 2192 .fiemap = ext2_fiemap,
d337f35e
JR
2193+ .sync_flags = ext2_sync_flags,
2194 };
cef7ea10
AM
2195diff -NurpP --minimal linux-4.9.82/fs/ext2/ialloc.c linux-4.9.82-vs2.3.9.7/fs/ext2/ialloc.c
2196--- linux-4.9.82/fs/ext2/ialloc.c 2016-12-11 19:17:54.000000000 +0000
2197+++ linux-4.9.82-vs2.3.9.7/fs/ext2/ialloc.c 2018-01-10 02:50:49.000000000 +0000
e22b5178
AM
2198@@ -17,6 +17,7 @@
2199 #include <linux/backing-dev.h>
2200 #include <linux/buffer_head.h>
2201 #include <linux/random.h>
2202+#include <linux/vs_tag.h>
2203 #include "ext2.h"
2204 #include "xattr.h"
2205 #include "acl.h"
cc23e853 2206@@ -551,6 +552,7 @@ got:
76514441
AM
2207 inode->i_mode = mode;
2208 inode->i_uid = current_fsuid();
2209 inode->i_gid = dir->i_gid;
a4a22af8 2210+ i_tag_write(inode, dx_current_fstag(sb));
e22b5178 2211 } else
76514441 2212 inode_init_owner(inode, dir, mode);
e22b5178 2213
cef7ea10
AM
2214diff -NurpP --minimal linux-4.9.82/fs/ext2/inode.c linux-4.9.82-vs2.3.9.7/fs/ext2/inode.c
2215--- linux-4.9.82/fs/ext2/inode.c 2016-12-11 19:17:54.000000000 +0000
2216+++ linux-4.9.82-vs2.3.9.7/fs/ext2/inode.c 2018-01-13 01:19:54.000000000 +0000
cc23e853
AM
2217@@ -35,6 +35,7 @@
2218 #include <linux/iomap.h>
ec22aa5c 2219 #include <linux/namei.h>
cc23e853 2220 #include <linux/uio.h>
d337f35e
JR
2221+#include <linux/vs_tag.h>
2222 #include "ext2.h"
2223 #include "acl.h"
cc23e853
AM
2224 #include "xattr.h"
2225@@ -1271,7 +1272,7 @@ static void ext2_truncate_blocks(struct
d337f35e
JR
2226 return;
2227 if (ext2_inode_is_fast_symlink(inode))
2228 return;
2229- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
2230+ if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
2231 return;
cc23e853
AM
2232
2233 dax_sem_down_write(EXT2_I(inode));
2234@@ -1367,39 +1368,61 @@ void ext2_set_inode_flags(struct inode *
d337f35e
JR
2235 {
2236 unsigned int flags = EXT2_I(inode)->i_flags;
2237
cc23e853
AM
2238- inode->i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME |
2239- S_DIRSYNC | S_DAX);
2240+ inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK | S_DAX |
d337f35e
JR
2241+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
2242+
2243+ if (flags & EXT2_IMMUTABLE_FL)
2244+ inode->i_flags |= S_IMMUTABLE;
2380c486
JR
2245+ if (flags & EXT2_IXUNLINK_FL)
2246+ inode->i_flags |= S_IXUNLINK;
d337f35e
JR
2247 if (flags & EXT2_SYNC_FL)
2248 inode->i_flags |= S_SYNC;
2249 if (flags & EXT2_APPEND_FL)
2250 inode->i_flags |= S_APPEND;
2251- if (flags & EXT2_IMMUTABLE_FL)
2252- inode->i_flags |= S_IMMUTABLE;
2253 if (flags & EXT2_NOATIME_FL)
2254 inode->i_flags |= S_NOATIME;
2255 if (flags & EXT2_DIRSYNC_FL)
2256 inode->i_flags |= S_DIRSYNC;
cc23e853
AM
2257 if (test_opt(inode->i_sb, DAX) && S_ISREG(inode->i_mode))
2258 inode->i_flags |= S_DAX;
2380c486
JR
2259+
2260+ inode->i_vflags &= ~(V_BARRIER | V_COW);
2261+
2262+ if (flags & EXT2_BARRIER_FL)
2263+ inode->i_vflags |= V_BARRIER;
2264+ if (flags & EXT2_COW_FL)
2265+ inode->i_vflags |= V_COW;
2266 }
2267
2268 /* Propagate flags from i_flags to EXT2_I(inode)->i_flags */
2269 void ext2_get_inode_flags(struct ext2_inode_info *ei)
2270 {
2271 unsigned int flags = ei->vfs_inode.i_flags;
2272+ unsigned int vflags = ei->vfs_inode.i_vflags;
2273+
2274+ ei->i_flags &= ~(EXT2_SYNC_FL | EXT2_APPEND_FL |
2275+ EXT2_IMMUTABLE_FL | EXT2_IXUNLINK_FL |
2276+ EXT2_NOATIME_FL | EXT2_DIRSYNC_FL |
2277+ EXT2_BARRIER_FL | EXT2_COW_FL);
2278+
2279+ if (flags & S_IMMUTABLE)
2280+ ei->i_flags |= EXT2_IMMUTABLE_FL;
2281+ if (flags & S_IXUNLINK)
2282+ ei->i_flags |= EXT2_IXUNLINK_FL;
2283
2284- ei->i_flags &= ~(EXT2_SYNC_FL|EXT2_APPEND_FL|
2285- EXT2_IMMUTABLE_FL|EXT2_NOATIME_FL|EXT2_DIRSYNC_FL);
2286 if (flags & S_SYNC)
2287 ei->i_flags |= EXT2_SYNC_FL;
2288 if (flags & S_APPEND)
2289 ei->i_flags |= EXT2_APPEND_FL;
2290- if (flags & S_IMMUTABLE)
2291- ei->i_flags |= EXT2_IMMUTABLE_FL;
2292 if (flags & S_NOATIME)
2293 ei->i_flags |= EXT2_NOATIME_FL;
2294 if (flags & S_DIRSYNC)
2295 ei->i_flags |= EXT2_DIRSYNC_FL;
2296+
2297+ if (vflags & V_BARRIER)
2298+ ei->i_flags |= EXT2_BARRIER_FL;
2299+ if (vflags & V_COW)
2300+ ei->i_flags |= EXT2_COW_FL;
d337f35e
JR
2301 }
2302
2380c486 2303 struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
cc23e853 2304@@ -1435,8 +1458,10 @@ struct inode *ext2_iget (struct super_bl
42bc425c
AM
2305 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
2306 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
d337f35e 2307 }
42bc425c
AM
2308- i_uid_write(inode, i_uid);
2309- i_gid_write(inode, i_gid);
2310+ i_uid_write(inode, INOTAG_UID(DX_TAG(inode), i_uid, i_gid));
2311+ i_gid_write(inode, INOTAG_GID(DX_TAG(inode), i_uid, i_gid));
537831f9
AM
2312+ i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
2313+ le16_to_cpu(raw_inode->i_raw_tag)));
f6c5ef8b 2314 set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
d337f35e 2315 inode->i_size = le32_to_cpu(raw_inode->i_size);
2380c486 2316 inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
cc23e853 2317@@ -1543,8 +1568,10 @@ static int __ext2_write_inode(struct ino
d337f35e
JR
2318 struct ext2_inode_info *ei = EXT2_I(inode);
2319 struct super_block *sb = inode->i_sb;
2320 ino_t ino = inode->i_ino;
42bc425c
AM
2321- uid_t uid = i_uid_read(inode);
2322- gid_t gid = i_gid_read(inode);
a4a22af8
AM
2323+ uid_t uid = from_kuid(&init_user_ns,
2324+ TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
2325+ gid_t gid = from_kgid(&init_user_ns,
2326+ TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
d337f35e
JR
2327 struct buffer_head * bh;
2328 struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh);
2329 int n;
cc23e853 2330@@ -1580,6 +1607,9 @@ static int __ext2_write_inode(struct ino
d337f35e
JR
2331 raw_inode->i_uid_high = 0;
2332 raw_inode->i_gid_high = 0;
2333 }
2334+#ifdef CONFIG_TAGGING_INTERN
537831f9 2335+ raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
d337f35e
JR
2336+#endif
2337 raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
2338 raw_inode->i_size = cpu_to_le32(inode->i_size);
2339 raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
cc23e853
AM
2340@@ -1663,7 +1693,8 @@ int ext2_setattr(struct dentry *dentry,
2341 return error;
2342 }
42bc425c
AM
2343 if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) ||
2344- (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) {
2345+ (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid)) ||
537831f9 2346+ (iattr->ia_valid & ATTR_TAG && !tag_eq(iattr->ia_tag, inode->i_tag))) {
78865d5b 2347 error = dquot_transfer(inode, iattr);
d337f35e
JR
2348 if (error)
2349 return error;
cef7ea10
AM
2350diff -NurpP --minimal linux-4.9.82/fs/ext2/ioctl.c linux-4.9.82-vs2.3.9.7/fs/ext2/ioctl.c
2351--- linux-4.9.82/fs/ext2/ioctl.c 2016-12-11 19:17:54.000000000 +0000
2352+++ linux-4.9.82-vs2.3.9.7/fs/ext2/ioctl.c 2018-01-13 01:20:40.000000000 +0000
d4263eb0
JR
2353@@ -17,6 +17,16 @@
2354 #include <asm/uaccess.h>
2355
2356
2357+int ext2_sync_flags(struct inode *inode, int flags, int vflags)
2358+{
2359+ inode->i_flags = flags;
2360+ inode->i_vflags = vflags;
2361+ ext2_get_inode_flags(EXT2_I(inode));
2362+ inode->i_ctime = CURRENT_TIME_SEC;
2363+ mark_inode_dirty(inode);
2364+ return 0;
2365+}
2366+
2367 long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
2368 {
b00e13aa 2369 struct inode *inode = file_inode(filp);
d4263eb0 2370@@ -51,6 +61,11 @@ long ext2_ioctl(struct file *filp, unsig
d337f35e 2371
ec22aa5c 2372 flags = ext2_mask_flags(inode->i_mode, flags);
d337f35e 2373
2380c486
JR
2374+ if (IS_BARRIER(inode)) {
2375+ vxwprintk_task(1, "messing with the barrier.");
2376+ return -EACCES;
2377+ }
2378+
cc23e853 2379 inode_lock(inode);
2380c486
JR
2380 /* Is it quota file? Do not allow user to mess with it */
2381 if (IS_NOQUOTA(inode)) {
d4263eb0 2382@@ -66,7 +81,9 @@ long ext2_ioctl(struct file *filp, unsig
d337f35e
JR
2383 *
2384 * This test looks nicer. Thanks to Pauline Middelink
2385 */
2386- if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {
2387+ if ((oldflags & EXT2_IMMUTABLE_FL) ||
2388+ ((flags ^ oldflags) & (EXT2_APPEND_FL |
2380c486
JR
2389+ EXT2_IMMUTABLE_FL | EXT2_IXUNLINK_FL))) {
2390 if (!capable(CAP_LINUX_IMMUTABLE)) {
cc23e853 2391 inode_unlock(inode);
2380c486 2392 ret = -EPERM;
d4263eb0
JR
2393@@ -74,7 +91,7 @@ long ext2_ioctl(struct file *filp, unsig
2394 }
2395 }
2396
2397- flags = flags & EXT2_FL_USER_MODIFIABLE;
2398+ flags &= EXT2_FL_USER_MODIFIABLE;
2399 flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE;
2400 ei->i_flags = flags;
db55b927 2401
cef7ea10
AM
2402diff -NurpP --minimal linux-4.9.82/fs/ext2/namei.c linux-4.9.82-vs2.3.9.7/fs/ext2/namei.c
2403--- linux-4.9.82/fs/ext2/namei.c 2016-12-11 19:17:54.000000000 +0000
2404+++ linux-4.9.82-vs2.3.9.7/fs/ext2/namei.c 2018-01-10 02:50:49.000000000 +0000
78865d5b 2405@@ -32,6 +32,7 @@
d337f35e
JR
2406
2407 #include <linux/pagemap.h>
78865d5b 2408 #include <linux/quotaops.h>
d337f35e
JR
2409+#include <linux/vs_tag.h>
2410 #include "ext2.h"
2411 #include "xattr.h"
2412 #include "acl.h"
cc23e853 2413@@ -72,6 +73,7 @@ static struct dentry *ext2_lookup(struct
a168f21d
AM
2414 (unsigned long) ino);
2415 return ERR_PTR(-EIO);
ec22aa5c 2416 }
a168f21d 2417+ dx_propagate_tag(nd, inode);
d337f35e 2418 }
a168f21d
AM
2419 return d_splice_alias(inode, dentry);
2420 }
cc23e853
AM
2421@@ -445,6 +447,7 @@ const struct inode_operations ext2_speci
2422 .listxattr = ext2_listxattr,
d337f35e
JR
2423 #endif
2424 .setattr = ext2_setattr,
d337f35e 2425+ .sync_flags = ext2_sync_flags,
a168f21d 2426 .get_acl = ext2_get_acl,
bb20add7 2427 .set_acl = ext2_set_acl,
d337f35e 2428 };
cef7ea10
AM
2429diff -NurpP --minimal linux-4.9.82/fs/ext2/super.c linux-4.9.82-vs2.3.9.7/fs/ext2/super.c
2430--- linux-4.9.82/fs/ext2/super.c 2016-12-11 19:17:54.000000000 +0000
2431+++ linux-4.9.82-vs2.3.9.7/fs/ext2/super.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 2432@@ -411,7 +411,8 @@ enum {
d337f35e
JR
2433 Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
2434 Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
cc23e853 2435 Opt_acl, Opt_noacl, Opt_xip, Opt_dax, Opt_ignore, Opt_err, Opt_quota,
2380c486
JR
2436- Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation
2437+ Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation,
2438+ Opt_tag, Opt_notag, Opt_tagid
d337f35e
JR
2439 };
2440
ec22aa5c 2441 static const match_table_t tokens = {
cc23e853 2442@@ -439,6 +440,9 @@ static const match_table_t tokens = {
d337f35e
JR
2443 {Opt_acl, "acl"},
2444 {Opt_noacl, "noacl"},
2445 {Opt_xip, "xip"},
2446+ {Opt_tag, "tag"},
2447+ {Opt_notag, "notag"},
2448+ {Opt_tagid, "tagid=%u"},
cc23e853 2449 {Opt_dax, "dax"},
d337f35e
JR
2450 {Opt_grpquota, "grpquota"},
2451 {Opt_ignore, "noquota"},
cc23e853 2452@@ -523,6 +527,20 @@ static int parse_options(char *options,
d337f35e
JR
2453 case Opt_nouid32:
2454 set_opt (sbi->s_mount_opt, NO_UID32);
2455 break;
2456+#ifndef CONFIG_TAGGING_NONE
2457+ case Opt_tag:
2458+ set_opt (sbi->s_mount_opt, TAGGED);
2459+ break;
2460+ case Opt_notag:
2461+ clear_opt (sbi->s_mount_opt, TAGGED);
2462+ break;
2463+#endif
2464+#ifdef CONFIG_PROPAGATE
2465+ case Opt_tagid:
2466+ /* use args[0] */
2467+ set_opt (sbi->s_mount_opt, TAGGED);
2468+ break;
2469+#endif
2470 case Opt_nocheck:
2471 clear_opt (sbi->s_mount_opt, CHECK);
2472 break;
cc23e853 2473@@ -887,6 +905,8 @@ static int ext2_fill_super(struct super_
2bf5ad28 2474 if (!parse_options((char *) data, sb))
d337f35e
JR
2475 goto failed_mount;
2476
cc23e853
AM
2477+ if (EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_TAGGED)
2478+ sb->s_flags |= MS_TAGGED;
2479 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2480 ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
2481 MS_POSIXACL : 0);
2482@@ -1300,6 +1320,14 @@ static int ext2_remount (struct super_bl
2483 err = -EINVAL;
2484 goto restore_opts;
2485 }
2486+
2487+ if ((sbi->s_mount_opt & EXT2_MOUNT_TAGGED) &&
d337f35e 2488+ !(sb->s_flags & MS_TAGGED)) {
cc23e853
AM
2489+ printk("EXT2-fs: %s: tagging not permitted on remount.\n",
2490+ sb->s_id);
d4263eb0
JR
2491+ err = -EINVAL;
2492+ goto restore_opts;
d337f35e 2493+ }
78865d5b 2494
cc23e853
AM
2495 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2496 ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
cef7ea10
AM
2497diff -NurpP --minimal linux-4.9.82/fs/ext4/ext4.h linux-4.9.82-vs2.3.9.7/fs/ext4/ext4.h
2498--- linux-4.9.82/fs/ext4/ext4.h 2016-12-11 19:17:54.000000000 +0000
2499+++ linux-4.9.82-vs2.3.9.7/fs/ext4/ext4.h 2018-01-13 02:00:49.000000000 +0000
cc23e853 2500@@ -392,8 +392,11 @@ struct flex_groups {
2380c486 2501 #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
78865d5b
AM
2502 #define EXT4_EA_INODE_FL 0x00200000 /* Inode used for large EA */
2503 #define EXT4_EOFBLOCKS_FL 0x00400000 /* Blocks allocated beyond EOF */
b00e13aa 2504+#define EXT4_BARRIER_FL 0x04000000 /* Barrier for chroot() */
2380c486 2505+#define EXT4_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */
b00e13aa 2506 #define EXT4_INLINE_DATA_FL 0x10000000 /* Inode has inline data. */
cc23e853
AM
2507 #define EXT4_PROJINHERIT_FL 0x20000000 /* Create with parents projid */
2508+#define EXT4_COW_FL 0x40000000 /* Copy on Write marker */
2380c486 2509 #define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
d337f35e 2510
cc23e853
AM
2511 #define EXT4_FL_USER_VISIBLE 0x304BDFFF /* User visible flags */
2512@@ -735,7 +738,7 @@ struct ext4_inode {
ec22aa5c
AM
2513 __le16 l_i_uid_high; /* these 2 fields */
2514 __le16 l_i_gid_high; /* were reserved2[0] */
42bc425c
AM
2515 __le16 l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
2516- __le16 l_i_reserved;
ec22aa5c 2517+ __le16 l_i_tag; /* Context Tag */
ec22aa5c
AM
2518 } linux2;
2519 struct {
2520 __le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
cc23e853 2521@@ -892,6 +895,7 @@ do { \
ec22aa5c
AM
2522 #define i_gid_low i_gid
2523 #define i_uid_high osd2.linux2.l_i_uid_high
2524 #define i_gid_high osd2.linux2.l_i_gid_high
2525+#define i_raw_tag osd2.linux2.l_i_tag
42bc425c 2526 #define i_checksum_lo osd2.linux2.l_i_checksum_lo
d337f35e 2527
ec22aa5c 2528 #elif defined(__GNU__)
cc23e853
AM
2529@@ -1133,6 +1137,7 @@ struct ext4_inode_info {
2530 #define EXT4_MOUNT_DIOREAD_NOLOCK 0x400000 /* Enable support for dio read nolocking */
2531 #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */
2532 #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */
2533+#define EXT4_MOUNT_TAGGED 0x2000000 /* Enable Context Tags */
2534 #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */
2535 #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */
2536 #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */
2537@@ -2497,6 +2502,7 @@ extern int ext4_punch_hole(struct inode
2538 extern int ext4_truncate_restart_trans(handle_t *, struct inode *, int nblocks);
2539 extern void ext4_set_inode_flags(struct inode *);
2540 extern void ext4_get_inode_flags(struct ext4_inode_info *);
d4263eb0 2541+extern int ext4_sync_flags(struct inode *, int, int);
cc23e853
AM
2542 extern int ext4_alloc_da_blocks(struct inode *inode);
2543 extern void ext4_set_aops(struct inode *inode);
2544 extern int ext4_writepage_trans_blocks(struct inode *);
cef7ea10
AM
2545diff -NurpP --minimal linux-4.9.82/fs/ext4/file.c linux-4.9.82-vs2.3.9.7/fs/ext4/file.c
2546--- linux-4.9.82/fs/ext4/file.c 2018-02-22 21:18:46.000000000 +0000
2547+++ linux-4.9.82-vs2.3.9.7/fs/ext4/file.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 2548@@ -691,5 +691,6 @@ const struct inode_operations ext4_file_
a168f21d 2549 .get_acl = ext4_get_acl,
bb20add7 2550 .set_acl = ext4_set_acl,
ec22aa5c 2551 .fiemap = ext4_fiemap,
d337f35e
JR
2552+ .sync_flags = ext4_sync_flags,
2553 };
2554
cef7ea10
AM
2555diff -NurpP --minimal linux-4.9.82/fs/ext4/ialloc.c linux-4.9.82-vs2.3.9.7/fs/ext4/ialloc.c
2556--- linux-4.9.82/fs/ext4/ialloc.c 2018-02-22 21:18:46.000000000 +0000
2557+++ linux-4.9.82-vs2.3.9.7/fs/ext4/ialloc.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 2558@@ -21,6 +21,7 @@
e22b5178
AM
2559 #include <linux/random.h>
2560 #include <linux/bitops.h>
2561 #include <linux/blkdev.h>
2562+#include <linux/vs_tag.h>
2563 #include <asm/byteorder.h>
2564
2565 #include "ext4.h"
cc23e853 2566@@ -799,6 +800,7 @@ struct inode *__ext4_new_inode(handle_t
76514441
AM
2567 inode->i_mode = mode;
2568 inode->i_uid = current_fsuid();
2569 inode->i_gid = dir->i_gid;
a4a22af8 2570+ i_tag_write(inode, dx_current_fstag(sb));
e22b5178 2571 } else
76514441 2572 inode_init_owner(inode, dir, mode);
cc23e853 2573
cef7ea10
AM
2574diff -NurpP --minimal linux-4.9.82/fs/ext4/inode.c linux-4.9.82-vs2.3.9.7/fs/ext4/inode.c
2575--- linux-4.9.82/fs/ext4/inode.c 2018-02-22 21:18:46.000000000 +0000
2576+++ linux-4.9.82-vs2.3.9.7/fs/ext4/inode.c 2018-01-13 02:02:12.000000000 +0000
cc23e853
AM
2577@@ -37,6 +37,7 @@
2578 #include <linux/printk.h>
2579 #include <linux/slab.h>
52afa9bd 2580 #include <linux/bitops.h>
d337f35e 2581+#include <linux/vs_tag.h>
ec22aa5c 2582
2380c486 2583 #include "ext4_jbd2.h"
d337f35e 2584 #include "xattr.h"
cc23e853 2585@@ -4374,12 +4375,15 @@ void ext4_set_inode_flags(struct inode *
d337f35e 2586 unsigned int flags = EXT4_I(inode)->i_flags;
52afa9bd 2587 unsigned int new_fl = 0;
978063ce 2588
d337f35e 2589+ if (flags & EXT4_IMMUTABLE_FL)
52afa9bd 2590+ new_fl |= S_IMMUTABLE;
2380c486 2591+ if (flags & EXT4_IXUNLINK_FL)
52afa9bd 2592+ new_fl |= S_IXUNLINK;
978063ce 2593+
d337f35e 2594 if (flags & EXT4_SYNC_FL)
52afa9bd 2595 new_fl |= S_SYNC;
d337f35e 2596 if (flags & EXT4_APPEND_FL)
52afa9bd 2597 new_fl |= S_APPEND;
d337f35e 2598- if (flags & EXT4_IMMUTABLE_FL)
52afa9bd 2599- new_fl |= S_IMMUTABLE;
d337f35e 2600 if (flags & EXT4_NOATIME_FL)
52afa9bd 2601 new_fl |= S_NOATIME;
d337f35e 2602 if (flags & EXT4_DIRSYNC_FL)
cc23e853
AM
2603@@ -4387,31 +4391,52 @@ void ext4_set_inode_flags(struct inode *
2604 if (test_opt(inode->i_sb, DAX) && S_ISREG(inode->i_mode))
2605 new_fl |= S_DAX;
ca5d134c 2606 inode_set_flags(inode, new_fl,
cc23e853
AM
2607- S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX);
2608+ S_IXUNLINK | S_IMMUTABLE | S_DAX |
ca5d134c 2609+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
2380c486 2610+
978063ce 2611+ new_fl = 0;
2380c486 2612+ if (flags & EXT4_BARRIER_FL)
978063ce 2613+ new_fl |= V_BARRIER;
2380c486 2614+ if (flags & EXT4_COW_FL)
978063ce
JR
2615+ new_fl |= V_COW;
2616+
2617+ set_mask_bits(&inode->i_vflags,
2618+ V_BARRIER | V_COW, new_fl);
d337f35e
JR
2619 }
2620
2380c486
JR
2621 /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */
2622 void ext4_get_inode_flags(struct ext4_inode_info *ei)
2623 {
76514441
AM
2624- unsigned int vfs_fl;
2625+ unsigned int vfs_fl, vfs_vf;
2626 unsigned long old_fl, new_fl;
2380c486 2627
76514441
AM
2628 do {
2629 vfs_fl = ei->vfs_inode.i_flags;
2630+ vfs_vf = ei->vfs_inode.i_vflags;
2631 old_fl = ei->i_flags;
2632 new_fl = old_fl & ~(EXT4_SYNC_FL|EXT4_APPEND_FL|
2633 EXT4_IMMUTABLE_FL|EXT4_NOATIME_FL|
2634- EXT4_DIRSYNC_FL);
2635+ EXT4_DIRSYNC_FL|EXT4_BARRIER_FL|
2636+ EXT4_COW_FL);
2637+
2638+ if (vfs_fl & S_IMMUTABLE)
2639+ new_fl |= EXT4_IMMUTABLE_FL;
2640+ if (vfs_fl & S_IXUNLINK)
2641+ new_fl |= EXT4_IXUNLINK_FL;
2642+
2643 if (vfs_fl & S_SYNC)
2644 new_fl |= EXT4_SYNC_FL;
2645 if (vfs_fl & S_APPEND)
2646 new_fl |= EXT4_APPEND_FL;
2647- if (vfs_fl & S_IMMUTABLE)
2648- new_fl |= EXT4_IMMUTABLE_FL;
2649 if (vfs_fl & S_NOATIME)
2650 new_fl |= EXT4_NOATIME_FL;
2651 if (vfs_fl & S_DIRSYNC)
2652 new_fl |= EXT4_DIRSYNC_FL;
2653+
2654+ if (vfs_vf & V_BARRIER)
2655+ new_fl |= EXT4_BARRIER_FL;
2656+ if (vfs_vf & V_COW)
2657+ new_fl |= EXT4_COW_FL;
2658 } while (cmpxchg(&ei->i_flags, old_fl, new_fl) != old_fl);
ec22aa5c
AM
2659 }
2660
cc23e853 2661@@ -4531,8 +4556,10 @@ struct inode *ext4_iget(struct super_blo
42bc425c
AM
2662 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
2663 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
d337f35e 2664 }
42bc425c
AM
2665- i_uid_write(inode, i_uid);
2666- i_gid_write(inode, i_gid);
2667+ i_uid_write(inode, INOTAG_UID(DX_TAG(inode), i_uid, i_gid));
2668+ i_gid_write(inode, INOTAG_GID(DX_TAG(inode), i_uid, i_gid));
537831f9
AM
2669+ i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
2670+ le16_to_cpu(raw_inode->i_raw_tag)));
cc23e853 2671 ei->i_projid = make_kprojid(&init_user_ns, i_projid);
f6c5ef8b 2672 set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
2380c486 2673
cc23e853 2674@@ -4848,8 +4875,10 @@ static int ext4_do_update_inode(handle_t
d337f35e 2675
2380c486 2676 ext4_get_inode_flags(ei);
d337f35e 2677 raw_inode->i_mode = cpu_to_le16(inode->i_mode);
42bc425c
AM
2678- i_uid = i_uid_read(inode);
2679- i_gid = i_gid_read(inode);
a4a22af8
AM
2680+ i_uid = from_kuid(&init_user_ns,
2681+ TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
2682+ i_gid = from_kgid(&init_user_ns,
2683+ TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
cc23e853 2684 i_projid = from_kprojid(&init_user_ns, ei->i_projid);
ec22aa5c 2685 if (!(test_opt(inode->i_sb, NO_UID32))) {
42bc425c 2686 raw_inode->i_uid_low = cpu_to_le16(low_16_bits(i_uid));
cc23e853 2687@@ -4873,6 +4902,9 @@ static int ext4_do_update_inode(handle_t
d337f35e
JR
2688 raw_inode->i_uid_high = 0;
2689 raw_inode->i_gid_high = 0;
2690 }
2691+#ifdef CONFIG_TAGGING_INTERN
537831f9 2692+ raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
d337f35e
JR
2693+#endif
2694 raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
2380c486
JR
2695
2696 EXT4_INODE_SET_XTIME(i_ctime, inode, raw_inode);
cc23e853
AM
2697@@ -5126,7 +5158,8 @@ int ext4_setattr(struct dentry *dentry,
2698 return error;
2699 }
42bc425c
AM
2700 if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) ||
2701- (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) {
2702+ (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid)) ||
537831f9 2703+ (ia_valid & ATTR_TAG && !tag_eq(attr->ia_tag, inode->i_tag))) {
d337f35e
JR
2704 handle_t *handle;
2705
2706 /* (user+group)*(old+new) structure, inode write (sb,
cc23e853 2707@@ -5149,6 +5182,8 @@ int ext4_setattr(struct dentry *dentry,
d337f35e
JR
2708 inode->i_uid = attr->ia_uid;
2709 if (attr->ia_valid & ATTR_GID)
2710 inode->i_gid = attr->ia_gid;
2711+ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
2712+ inode->i_tag = attr->ia_tag;
2713 error = ext4_mark_inode_dirty(handle, inode);
2714 ext4_journal_stop(handle);
2715 }
cef7ea10
AM
2716diff -NurpP --minimal linux-4.9.82/fs/ext4/ioctl.c linux-4.9.82-vs2.3.9.7/fs/ext4/ioctl.c
2717--- linux-4.9.82/fs/ext4/ioctl.c 2016-12-11 19:17:54.000000000 +0000
2718+++ linux-4.9.82-vs2.3.9.7/fs/ext4/ioctl.c 2018-01-13 02:03:59.000000000 +0000
cc23e853 2719@@ -15,6 +15,7 @@
ec22aa5c 2720 #include <linux/file.h>
cc23e853
AM
2721 #include <linux/quotaops.h>
2722 #include <linux/uuid.h>
d337f35e
JR
2723+#include <linux/vs_tag.h>
2724 #include <asm/uaccess.h>
2380c486
JR
2725 #include "ext4_jbd2.h"
2726 #include "ext4.h"
cc23e853
AM
2727@@ -226,7 +227,9 @@ static int ext4_ioctl_setflags(struct in
2728 *
2729 * This test looks nicer. Thanks to Pauline Middelink
2730 */
2731- if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
2732+ if ((oldflags & EXT4_IMMUTABLE_FL) ||
2733+ ((flags ^ oldflags) & (EXT4_APPEND_FL |
2734+ EXT4_IMMUTABLE_FL | EXT4_IXUNLINK_FL))) {
2735 if (!capable(CAP_LINUX_IMMUTABLE))
2736 goto flags_out;
2737 }
2738@@ -430,6 +433,33 @@ static inline unsigned long ext4_xflags_
2739 return iflags;
09be7631 2740 }
db55b927 2741
d4263eb0
JR
2742+int ext4_sync_flags(struct inode *inode, int flags, int vflags)
2743+{
2744+ handle_t *handle = NULL;
2745+ struct ext4_iloc iloc;
2746+ int err;
2747+
b00e13aa 2748+ handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
d4263eb0
JR
2749+ if (IS_ERR(handle))
2750+ return PTR_ERR(handle);
2751+
2752+ if (IS_SYNC(inode))
2753+ ext4_handle_sync(handle);
2754+ err = ext4_reserve_inode_write(handle, inode, &iloc);
2755+ if (err)
2756+ goto flags_err;
2757+
2758+ inode->i_flags = flags;
2759+ inode->i_vflags = vflags;
2760+ ext4_get_inode_flags(EXT4_I(inode));
2761+ inode->i_ctime = ext4_current_time(inode);
2762+
2763+ err = ext4_mark_iloc_dirty(handle, inode, &iloc);
2764+flags_err:
2765+ ext4_journal_stop(handle);
2766+ return err;
2767+}
2768+
2769 long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
2770 {
b00e13aa 2771 struct inode *inode = file_inode(filp);
cc23e853 2772@@ -459,6 +489,11 @@ long ext4_ioctl(struct file *filp, unsig
ec22aa5c
AM
2773
2774 flags = ext4_mask_flags(inode->i_mode, flags);
2380c486
JR
2775
2776+ if (IS_BARRIER(inode)) {
2777+ vxwprintk_task(1, "messing with the barrier.");
2778+ return -EACCES;
2779+ }
2780+
cc23e853
AM
2781 inode_lock(inode);
2782 err = ext4_ioctl_setflags(inode, flags);
2783 inode_unlock(inode);
cef7ea10
AM
2784diff -NurpP --minimal linux-4.9.82/fs/ext4/namei.c linux-4.9.82-vs2.3.9.7/fs/ext4/namei.c
2785--- linux-4.9.82/fs/ext4/namei.c 2018-02-22 21:18:46.000000000 +0000
2786+++ linux-4.9.82-vs2.3.9.7/fs/ext4/namei.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 2787@@ -33,6 +33,7 @@
2380c486 2788 #include <linux/quotaops.h>
d337f35e
JR
2789 #include <linux/buffer_head.h>
2790 #include <linux/bio.h>
d337f35e 2791+#include <linux/vs_tag.h>
2380c486
JR
2792 #include "ext4.h"
2793 #include "ext4_jbd2.h"
d337f35e 2794
cc23e853
AM
2795@@ -1459,6 +1460,7 @@ restart:
2796 REQ_META | REQ_PRIO,
a168f21d 2797 1, &bh);
2380c486 2798 }
d337f35e 2799+ dx_propagate_tag(nd, inode);
2380c486
JR
2800 }
2801 if ((bh = bh_use[ra_ptr++]) == NULL)
2802 goto next;
cc23e853 2803@@ -3906,6 +3908,7 @@ const struct inode_operations ext4_dir_i
a168f21d 2804 .get_acl = ext4_get_acl,
bb20add7 2805 .set_acl = ext4_set_acl,
d4263eb0 2806 .fiemap = ext4_fiemap,
d337f35e
JR
2807+ .sync_flags = ext4_sync_flags,
2808 };
d4263eb0
JR
2809
2810 const struct inode_operations ext4_special_inode_operations = {
cef7ea10
AM
2811diff -NurpP --minimal linux-4.9.82/fs/ext4/super.c linux-4.9.82-vs2.3.9.7/fs/ext4/super.c
2812--- linux-4.9.82/fs/ext4/super.c 2018-02-22 21:18:46.000000000 +0000
2813+++ linux-4.9.82-vs2.3.9.7/fs/ext4/super.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 2814@@ -1280,6 +1280,7 @@ enum {
78865d5b 2815 Opt_dioread_nolock, Opt_dioread_lock,
dd5f3080 2816 Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
cc23e853
AM
2817 Opt_max_dir_size_kb, Opt_nojournal_checksum,
2818+ Opt_tag, Opt_notag, Opt_tagid
d337f35e
JR
2819 };
2820
ec22aa5c 2821 static const match_table_t tokens = {
cc23e853 2822@@ -1366,6 +1367,9 @@ static const match_table_t tokens = {
1e8b8f9b
AM
2823 {Opt_removed, "reservation"}, /* mount option from ext2/3 */
2824 {Opt_removed, "noreservation"}, /* mount option from ext2/3 */
2825 {Opt_removed, "journal=%u"}, /* mount option from ext2/3 */
d337f35e
JR
2826+ {Opt_tag, "tag"},
2827+ {Opt_notag, "notag"},
2828+ {Opt_tagid, "tagid=%u"},
d337f35e 2829 {Opt_err, NULL},
d337f35e 2830 };
2380c486 2831
cc23e853
AM
2832@@ -1611,6 +1615,20 @@ static int handle_mount_opt(struct super
2833 case Opt_nolazytime:
2834 sb->s_flags &= ~MS_LAZYTIME;
1e8b8f9b 2835 return 1;
d337f35e 2836+#ifndef CONFIG_TAGGING_NONE
1e8b8f9b
AM
2837+ case Opt_tag:
2838+ set_opt(sb, TAGGED);
2839+ return 1;
2840+ case Opt_notag:
2841+ clear_opt(sb, TAGGED);
2842+ return 1;
d337f35e
JR
2843+#endif
2844+#ifdef CONFIG_PROPAGATE
1e8b8f9b
AM
2845+ case Opt_tagid:
2846+ /* use args[0] */
2847+ set_opt(sb, TAGGED);
2848+ return 1;
d337f35e 2849+#endif
1e8b8f9b
AM
2850 }
2851
b00e13aa 2852 for (m = ext4_mount_opts; m->token != Opt_err; m++)
cc23e853
AM
2853@@ -3550,6 +3568,9 @@ static int ext4_fill_super(struct super_
2854 sb->s_iflags |= SB_I_CGROUPWB;
f6c5ef8b 2855 }
d337f35e
JR
2856
2857+ if (EXT4_SB(sb)->s_mount_opt & EXT4_MOUNT_TAGGED)
2858+ sb->s_flags |= MS_TAGGED;
2859+
2860 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
78865d5b 2861 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
d337f35e 2862
cc23e853 2863@@ -4917,6 +4938,14 @@ static int ext4_remount(struct super_blo
ec22aa5c 2864 if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED)
93de0823 2865 ext4_abort(sb, "Abort forced by user");
2380c486 2866
d337f35e
JR
2867+ if ((sbi->s_mount_opt & EXT4_MOUNT_TAGGED) &&
2868+ !(sb->s_flags & MS_TAGGED)) {
2869+ printk("EXT4-fs: %s: tagging not permitted on remount.\n",
2870+ sb->s_id);
d4263eb0
JR
2871+ err = -EINVAL;
2872+ goto restore_opts;
d337f35e 2873+ }
2380c486 2874+
d337f35e 2875 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
78865d5b 2876 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
d337f35e 2877
cef7ea10
AM
2878diff -NurpP --minimal linux-4.9.82/fs/fcntl.c linux-4.9.82-vs2.3.9.7/fs/fcntl.c
2879--- linux-4.9.82/fs/fcntl.c 2018-02-22 21:18:46.000000000 +0000
2880+++ linux-4.9.82-vs2.3.9.7/fs/fcntl.c 2018-02-10 15:15:43.000000000 +0000
bb20add7 2881@@ -22,6 +22,7 @@
2380c486 2882 #include <linux/pid_namespace.h>
92598135 2883 #include <linux/user_namespace.h>
bb20add7 2884 #include <linux/shmem_fs.h>
d337f35e
JR
2885+#include <linux/vs_limit.h>
2886
2887 #include <asm/poll.h>
2888 #include <asm/siginfo.h>
5ba7a31c 2889@@ -390,6 +391,8 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, f
d337f35e 2890
537831f9 2891 if (!f.file)
2380c486
JR
2892 goto out;
2893+ if (!vx_files_avail(1))
2894+ goto out;
2895
537831f9 2896 if (unlikely(f.file->f_mode & FMODE_PATH)) {
42bc425c 2897 if (!check_fcntl_cmd(cmd))
cef7ea10
AM
2898diff -NurpP --minimal linux-4.9.82/fs/file.c linux-4.9.82-vs2.3.9.7/fs/file.c
2899--- linux-4.9.82/fs/file.c 2016-12-11 19:17:54.000000000 +0000
2900+++ linux-4.9.82-vs2.3.9.7/fs/file.c 2018-01-10 02:50:49.000000000 +0000
537831f9 2901@@ -22,6 +22,7 @@
2380c486
JR
2902 #include <linux/spinlock.h>
2903 #include <linux/rcupdate.h>
2904 #include <linux/workqueue.h>
2905+#include <linux/vs_limit.h>
2906
cc23e853
AM
2907 unsigned int sysctl_nr_open __read_mostly = 1024*1024;
2908 unsigned int sysctl_nr_open_min = BITS_PER_LONG;
2909@@ -357,6 +358,8 @@ struct files_struct *dup_fd(struct files
2380c486
JR
2910 struct file *f = *old_fds++;
2911 if (f) {
2912 get_file(f);
2913+ /* TODO: sum it first for check and performance */
2914+ vx_openfd_inc(open_files - i);
2915 } else {
2916 /*
2917 * The fd may be claimed in the fd bitmap but not yet
cc23e853 2918@@ -406,9 +409,11 @@ static struct fdtable *close_files(struc
537831f9 2919 filp_close(file, files);
bb20add7 2920 cond_resched_rcu_qs();
537831f9
AM
2921 }
2922+ vx_openfd_dec(i);
2923 }
2924 i++;
2925 set >>= 1;
2926+ cond_resched();
2927 }
2928 }
bb20add7 2929
cc23e853 2930@@ -539,6 +544,7 @@ repeat:
2380c486 2931 else
1e8b8f9b 2932 __clear_close_on_exec(fd, fdt);
2380c486
JR
2933 error = fd;
2934+ vx_openfd_inc(fd);
2935 #if 1
2936 /* Sanity check */
bb20add7 2937 if (rcu_access_pointer(fdt->fd[fd]) != NULL) {
cc23e853 2938@@ -569,6 +575,7 @@ static void __put_unused_fd(struct files
537831f9
AM
2939 __clear_open_fd(fd, fdt);
2940 if (fd < files->next_fd)
2941 files->next_fd = fd;
2942+ vx_openfd_dec(fd);
2943 }
2944
2945 void put_unused_fd(unsigned int fd)
cc23e853 2946@@ -856,6 +863,8 @@ __releases(&files->file_lock)
537831f9
AM
2947
2948 if (tofree)
2949 filp_close(tofree, files);
2950+ else
2951+ vx_openfd_inc(fd); /* fd was unused */
2952
2953 return fd;
2954
cef7ea10
AM
2955diff -NurpP --minimal linux-4.9.82/fs/file_table.c linux-4.9.82-vs2.3.9.7/fs/file_table.c
2956--- linux-4.9.82/fs/file_table.c 2016-12-11 19:17:54.000000000 +0000
2957+++ linux-4.9.82-vs2.3.9.7/fs/file_table.c 2018-01-10 02:50:49.000000000 +0000
92598135 2958@@ -26,6 +26,8 @@
92598135 2959 #include <linux/task_work.h>
2bf5ad28 2960 #include <linux/ima.h>
cc23e853 2961 #include <linux/swap.h>
d337f35e
JR
2962+#include <linux/vs_limit.h>
2963+#include <linux/vs_context.h>
2964
a168f21d 2965 #include <linux/atomic.h>
d337f35e 2966
c2e5f7c8 2967@@ -137,6 +139,8 @@ struct file *get_empty_filp(void)
bb20add7 2968 mutex_init(&f->f_pos_lock);
d337f35e
JR
2969 eventpoll_init_file(f);
2970 /* f->f_version: 0 */
2971+ f->f_xid = vx_current_xid();
2972+ vx_files_inc(f);
2973 return f;
2974
2975 over:
bb20add7 2976@@ -219,6 +223,8 @@ static void __fput(struct file *file)
265de2f7
JR
2977 put_write_access(inode);
2978 __mnt_drop_write(mnt);
2979 }
d337f35e
JR
2980+ vx_files_dec(file);
2981+ file->f_xid = 0;
92598135
AM
2982 file->f_path.dentry = NULL;
2983 file->f_path.mnt = NULL;
b00e13aa 2984 file->f_inode = NULL;
bb20add7 2985@@ -305,6 +311,8 @@ void put_filp(struct file *file)
d337f35e 2986 {
2380c486 2987 if (atomic_long_dec_and_test(&file->f_count)) {
d337f35e
JR
2988 security_file_free(file);
2989+ vx_files_dec(file);
2990+ file->f_xid = 0;
d337f35e
JR
2991 file_free(file);
2992 }
c2e5f7c8 2993 }
cef7ea10
AM
2994diff -NurpP --minimal linux-4.9.82/fs/fs_struct.c linux-4.9.82-vs2.3.9.7/fs/fs_struct.c
2995--- linux-4.9.82/fs/fs_struct.c 2016-12-11 19:17:54.000000000 +0000
2996+++ linux-4.9.82-vs2.3.9.7/fs/fs_struct.c 2018-01-10 02:50:49.000000000 +0000
ec22aa5c
AM
2997@@ -4,6 +4,7 @@
2998 #include <linux/path.h>
2999 #include <linux/slab.h>
3000 #include <linux/fs_struct.h>
3001+#include <linux/vserver/global.h>
d33d7b00 3002 #include "internal.h"
ec22aa5c 3003
92598135
AM
3004 /*
3005@@ -87,6 +88,7 @@ void free_fs_struct(struct fs_struct *fs
ec22aa5c 3006 {
92598135
AM
3007 path_put(&fs->root);
3008 path_put(&fs->pwd);
ec22aa5c
AM
3009+ atomic_dec(&vs_global_fs);
3010 kmem_cache_free(fs_cachep, fs);
3011 }
3012
537831f9 3013@@ -124,6 +126,7 @@ struct fs_struct *copy_fs_struct(struct
d33d7b00 3014 fs->pwd = old->pwd;
92598135 3015 path_get(&fs->pwd);
d33d7b00 3016 spin_unlock(&old->lock);
ec22aa5c
AM
3017+ atomic_inc(&vs_global_fs);
3018 }
3019 return fs;
3020 }
cef7ea10
AM
3021diff -NurpP --minimal linux-4.9.82/fs/gfs2/file.c linux-4.9.82-vs2.3.9.7/fs/gfs2/file.c
3022--- linux-4.9.82/fs/gfs2/file.c 2018-02-22 21:18:47.000000000 +0000
3023+++ linux-4.9.82-vs2.3.9.7/fs/gfs2/file.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 3024@@ -137,6 +137,9 @@ static const u32 fsflags_to_gfs2[32] = {
e22b5178
AM
3025 [12] = GFS2_DIF_EXHASH,
3026 [14] = GFS2_DIF_INHERIT_JDATA,
92598135 3027 [17] = GFS2_DIF_TOPDIR,
e22b5178
AM
3028+ [27] = GFS2_DIF_IXUNLINK,
3029+ [26] = GFS2_DIF_BARRIER,
3030+ [29] = GFS2_DIF_COW,
3031 };
3032
3033 static const u32 gfs2_to_fsflags[32] = {
cc23e853 3034@@ -147,6 +150,9 @@ static const u32 gfs2_to_fsflags[32] = {
e22b5178 3035 [gfs2fl_ExHash] = FS_INDEX_FL,
92598135 3036 [gfs2fl_TopLevel] = FS_TOPDIR_FL,
e22b5178
AM
3037 [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL,
3038+ [gfs2fl_IXUnlink] = FS_IXUNLINK_FL,
3039+ [gfs2fl_Barrier] = FS_BARRIER_FL,
3040+ [gfs2fl_Cow] = FS_COW_FL,
3041 };
3042
3043 static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
cc23e853 3044@@ -178,12 +184,17 @@ void gfs2_set_inode_flags(struct inode *
e22b5178
AM
3045 {
3046 struct gfs2_inode *ip = GFS2_I(inode);
3047 unsigned int flags = inode->i_flags;
3048+ unsigned int vflags = inode->i_vflags;
3049+
3050+ flags &= ~(S_IMMUTABLE | S_IXUNLINK |
a168f21d 3051+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC | S_NOSEC);
e22b5178 3052
a168f21d
AM
3053- flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_NOSEC);
3054 if ((ip->i_eattr == 0) && !is_sxid(inode->i_mode))
cc23e853 3055 flags |= S_NOSEC;
e22b5178
AM
3056 if (ip->i_diskflags & GFS2_DIF_IMMUTABLE)
3057 flags |= S_IMMUTABLE;
3058+ if (ip->i_diskflags & GFS2_DIF_IXUNLINK)
3059+ flags |= S_IXUNLINK;
e22b5178
AM
3060 if (ip->i_diskflags & GFS2_DIF_APPENDONLY)
3061 flags |= S_APPEND;
3062 if (ip->i_diskflags & GFS2_DIF_NOATIME)
cc23e853 3063@@ -191,6 +202,43 @@ void gfs2_set_inode_flags(struct inode *
e22b5178
AM
3064 if (ip->i_diskflags & GFS2_DIF_SYNC)
3065 flags |= S_SYNC;
3066 inode->i_flags = flags;
3067+
3068+ vflags &= ~(V_BARRIER | V_COW);
3069+
3070+ if (ip->i_diskflags & GFS2_DIF_BARRIER)
3071+ vflags |= V_BARRIER;
3072+ if (ip->i_diskflags & GFS2_DIF_COW)
3073+ vflags |= V_COW;
3074+ inode->i_vflags = vflags;
3075+}
3076+
3077+void gfs2_get_inode_flags(struct inode *inode)
3078+{
3079+ struct gfs2_inode *ip = GFS2_I(inode);
3080+ unsigned int flags = inode->i_flags;
3081+ unsigned int vflags = inode->i_vflags;
3082+
3083+ ip->i_diskflags &= ~(GFS2_DIF_APPENDONLY |
3084+ GFS2_DIF_NOATIME | GFS2_DIF_SYNC |
3085+ GFS2_DIF_IMMUTABLE | GFS2_DIF_IXUNLINK |
3086+ GFS2_DIF_BARRIER | GFS2_DIF_COW);
3087+
3088+ if (flags & S_IMMUTABLE)
3089+ ip->i_diskflags |= GFS2_DIF_IMMUTABLE;
3090+ if (flags & S_IXUNLINK)
3091+ ip->i_diskflags |= GFS2_DIF_IXUNLINK;
3092+
3093+ if (flags & S_APPEND)
3094+ ip->i_diskflags |= GFS2_DIF_APPENDONLY;
3095+ if (flags & S_NOATIME)
3096+ ip->i_diskflags |= GFS2_DIF_NOATIME;
3097+ if (flags & S_SYNC)
3098+ ip->i_diskflags |= GFS2_DIF_SYNC;
3099+
3100+ if (vflags & V_BARRIER)
3101+ ip->i_diskflags |= GFS2_DIF_BARRIER;
3102+ if (vflags & V_COW)
3103+ ip->i_diskflags |= GFS2_DIF_COW;
3104 }
3105
3106 /* Flags that can be set by user space */
cc23e853
AM
3107@@ -306,6 +354,37 @@ static int gfs2_set_flags(struct file *f
3108 return do_gfs2_set_flags(filp, gfsflags, ~(GFS2_DIF_SYSTEM | GFS2_DIF_JDATA));
e22b5178
AM
3109 }
3110
3111+int gfs2_sync_flags(struct inode *inode, int flags, int vflags)
3112+{
3113+ struct gfs2_inode *ip = GFS2_I(inode);
3114+ struct gfs2_sbd *sdp = GFS2_SB(inode);
3115+ struct buffer_head *bh;
3116+ struct gfs2_holder gh;
3117+ int error;
3118+
3119+ error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
3120+ if (error)
3121+ return error;
3122+ error = gfs2_trans_begin(sdp, RES_DINODE, 0);
3123+ if (error)
3124+ goto out;
3125+ error = gfs2_meta_inode_buffer(ip, &bh);
3126+ if (error)
3127+ goto out_trans_end;
b00e13aa 3128+ gfs2_trans_add_meta(ip->i_gl, bh);
e22b5178
AM
3129+ inode->i_flags = flags;
3130+ inode->i_vflags = vflags;
3131+ gfs2_get_inode_flags(inode);
3132+ gfs2_dinode_out(ip, bh->b_data);
3133+ brelse(bh);
3134+ gfs2_set_aops(inode);
3135+out_trans_end:
3136+ gfs2_trans_end(sdp);
3137+out:
3138+ gfs2_glock_dq_uninit(&gh);
3139+ return error;
3140+}
3141+
3142 static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
3143 {
3144 switch(cmd) {
cef7ea10
AM
3145diff -NurpP --minimal linux-4.9.82/fs/gfs2/inode.h linux-4.9.82-vs2.3.9.7/fs/gfs2/inode.h
3146--- linux-4.9.82/fs/gfs2/inode.h 2016-12-11 19:17:54.000000000 +0000
3147+++ linux-4.9.82-vs2.3.9.7/fs/gfs2/inode.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 3148@@ -117,6 +117,7 @@ extern const struct file_operations gfs2
e22b5178
AM
3149 extern const struct file_operations gfs2_dir_fops_nolock;
3150
3151 extern void gfs2_set_inode_flags(struct inode *inode);
3152+extern int gfs2_sync_flags(struct inode *inode, int flags, int vflags);
3153
3154 #ifdef CONFIG_GFS2_FS_LOCKING_DLM
3155 extern const struct file_operations gfs2_file_fops;
cef7ea10
AM
3156diff -NurpP --minimal linux-4.9.82/fs/hostfs/hostfs.h linux-4.9.82-vs2.3.9.7/fs/hostfs/hostfs.h
3157--- linux-4.9.82/fs/hostfs/hostfs.h 2016-12-11 19:17:54.000000000 +0000
3158+++ linux-4.9.82-vs2.3.9.7/fs/hostfs/hostfs.h 2018-01-10 02:50:49.000000000 +0000
537831f9
AM
3159@@ -42,6 +42,7 @@ struct hostfs_iattr {
3160 unsigned short ia_mode;
3161 uid_t ia_uid;
3162 gid_t ia_gid;
61333608 3163+ vtag_t ia_tag;
537831f9
AM
3164 loff_t ia_size;
3165 struct timespec ia_atime;
3166 struct timespec ia_mtime;
cef7ea10
AM
3167diff -NurpP --minimal linux-4.9.82/fs/inode.c linux-4.9.82-vs2.3.9.7/fs/inode.c
3168--- linux-4.9.82/fs/inode.c 2018-02-22 21:18:47.000000000 +0000
3169+++ linux-4.9.82-vs2.3.9.7/fs/inode.c 2018-01-10 02:50:49.000000000 +0000
c2e5f7c8 3170@@ -18,6 +18,7 @@
763640ca 3171 #include <linux/buffer_head.h> /* for inode_has_buffers */
db55b927 3172 #include <linux/ratelimit.h>
c2e5f7c8 3173 #include <linux/list_lru.h>
76514441 3174+#include <linux/vs_tag.h>
cc23e853 3175 #include <trace/events/writeback.h>
763640ca 3176 #include "internal.h"
76514441 3177
cc23e853 3178@@ -133,6 +134,8 @@ int inode_init_always(struct super_block
ec22aa5c
AM
3179 struct address_space *const mapping = &inode->i_data;
3180
3181 inode->i_sb = sb;
3182+
3183+ /* essential because of inode slab reuse */
ec22aa5c
AM
3184 inode->i_blkbits = sb->s_blocksize_bits;
3185 inode->i_flags = 0;
3186 atomic_set(&inode->i_count, 1);
cc23e853
AM
3187@@ -144,6 +147,7 @@ int inode_init_always(struct super_block
3188 inode->i_opflags |= IOP_XATTR;
537831f9
AM
3189 i_uid_write(inode, 0);
3190 i_gid_write(inode, 0);
3191+ i_tag_write(inode, 0);
3192 atomic_set(&inode->i_writecount, 0);
3193 inode->i_size = 0;
3194 inode->i_blocks = 0;
cc23e853
AM
3195@@ -155,6 +159,7 @@ int inode_init_always(struct super_block
3196 inode->i_link = NULL;
3197 inode->i_dir_seq = 0;
ec22aa5c
AM
3198 inode->i_rdev = 0;
3199+ inode->i_mdev = 0;
3200 inode->dirtied_when = 0;
3201
cc23e853
AM
3202 #ifdef CONFIG_CGROUP_WRITEBACK
3203@@ -479,6 +484,8 @@ void __insert_inode_hash(struct inode *i
d337f35e 3204 }
763640ca 3205 EXPORT_SYMBOL(__insert_inode_hash);
d337f35e
JR
3206
3207+EXPORT_SYMBOL_GPL(__iget);
3208+
3209 /**
a168f21d 3210 * __remove_inode_hash - remove an inode from the hash
ab30d09f 3211 * @inode: inode to unhash
cc23e853 3212@@ -1977,9 +1984,11 @@ void init_special_inode(struct inode *in
2380c486
JR
3213 if (S_ISCHR(mode)) {
3214 inode->i_fop = &def_chr_fops;
3215 inode->i_rdev = rdev;
3216+ inode->i_mdev = rdev;
3217 } else if (S_ISBLK(mode)) {
3218 inode->i_fop = &def_blk_fops;
3219 inode->i_rdev = rdev;
3220+ inode->i_mdev = rdev;
3221 } else if (S_ISFIFO(mode))
09be7631 3222 inode->i_fop = &pipefifo_fops;
2380c486 3223 else if (S_ISSOCK(mode))
cc23e853 3224@@ -2008,6 +2017,7 @@ void inode_init_owner(struct inode *inod
76514441
AM
3225 } else
3226 inode->i_gid = current_fsgid();
3227 inode->i_mode = mode;
8ce283e1 3228+ i_tag_write(inode, dx_current_fstag(inode->i_sb));
76514441
AM
3229 }
3230 EXPORT_SYMBOL(inode_init_owner);
763640ca 3231
cef7ea10
AM
3232diff -NurpP --minimal linux-4.9.82/fs/ioctl.c linux-4.9.82-vs2.3.9.7/fs/ioctl.c
3233--- linux-4.9.82/fs/ioctl.c 2016-12-11 19:17:54.000000000 +0000
3234+++ linux-4.9.82-vs2.3.9.7/fs/ioctl.c 2018-01-13 01:03:36.000000000 +0000
ab30d09f 3235@@ -15,6 +15,9 @@
ec22aa5c
AM
3236 #include <linux/writeback.h>
3237 #include <linux/buffer_head.h>
3238 #include <linux/falloc.h>
d337f35e
JR
3239+#include <linux/proc_fs.h>
3240+#include <linux/vserver/inode.h>
3241+#include <linux/vs_tag.h>
cc23e853 3242 #include "internal.h"
d337f35e 3243
d337f35e 3244 #include <asm/ioctls.h>
cef7ea10
AM
3245diff -NurpP --minimal linux-4.9.82/fs/jfs/file.c linux-4.9.82-vs2.3.9.7/fs/jfs/file.c
3246--- linux-4.9.82/fs/jfs/file.c 2016-12-11 19:17:54.000000000 +0000
3247+++ linux-4.9.82-vs2.3.9.7/fs/jfs/file.c 2018-01-10 02:50:49.000000000 +0000
cc23e853
AM
3248@@ -113,7 +113,8 @@ int jfs_setattr(struct dentry *dentry, s
3249 return rc;
3250 }
537831f9
AM
3251 if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) ||
3252- (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) {
3253+ (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid)) ||
3254+ (iattr->ia_valid & ATTR_TAG && !tag_eq(iattr->ia_tag, inode->i_tag))) {
78865d5b
AM
3255 rc = dquot_transfer(inode, iattr);
3256 if (rc)
3257 return rc;
bb20add7 3258@@ -146,6 +147,7 @@ const struct inode_operations jfs_file_i
a168f21d 3259 .get_acl = jfs_get_acl,
bb20add7 3260 .set_acl = jfs_set_acl,
d337f35e
JR
3261 #endif
3262+ .sync_flags = jfs_sync_flags,
3263 };
3264
3265 const struct file_operations jfs_file_operations = {
cef7ea10
AM
3266diff -NurpP --minimal linux-4.9.82/fs/jfs/ioctl.c linux-4.9.82-vs2.3.9.7/fs/jfs/ioctl.c
3267--- linux-4.9.82/fs/jfs/ioctl.c 2016-12-11 19:17:54.000000000 +0000
3268+++ linux-4.9.82-vs2.3.9.7/fs/jfs/ioctl.c 2018-01-10 02:50:49.000000000 +0000
537831f9 3269@@ -12,6 +12,7 @@
d337f35e 3270 #include <linux/time.h>
2380c486 3271 #include <linux/sched.h>
537831f9 3272 #include <linux/blkdev.h>
d337f35e
JR
3273+#include <linux/mount.h>
3274 #include <asm/current.h>
3275 #include <asm/uaccess.h>
3276
537831f9 3277@@ -56,6 +57,16 @@ static long jfs_map_ext2(unsigned long f
d4263eb0
JR
3278 }
3279
3280
3281+int jfs_sync_flags(struct inode *inode, int flags, int vflags)
3282+{
3283+ inode->i_flags = flags;
3284+ inode->i_vflags = vflags;
3285+ jfs_get_inode_flags(JFS_IP(inode));
3286+ inode->i_ctime = CURRENT_TIME_SEC;
3287+ mark_inode_dirty(inode);
3288+ return 0;
3289+}
3290+
3291 long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
3292 {
b00e13aa 3293 struct inode *inode = file_inode(filp);
537831f9 3294@@ -89,6 +100,11 @@ long jfs_ioctl(struct file *filp, unsign
2380c486
JR
3295 if (!S_ISDIR(inode->i_mode))
3296 flags &= ~JFS_DIRSYNC_FL;
d337f35e 3297
2380c486
JR
3298+ if (IS_BARRIER(inode)) {
3299+ vxwprintk_task(1, "messing with the barrier.");
3300+ return -EACCES;
3301+ }
3302+
3303 /* Is it quota file? Do not allow user to mess with it */
3304 if (IS_NOQUOTA(inode)) {
3305 err = -EPERM;
537831f9 3306@@ -106,8 +122,8 @@ long jfs_ioctl(struct file *filp, unsign
d337f35e
JR
3307 * the relevant capability.
3308 */
3309 if ((oldflags & JFS_IMMUTABLE_FL) ||
3310- ((flags ^ oldflags) &
3311- (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
3312+ ((flags ^ oldflags) & (JFS_APPEND_FL |
2380c486
JR
3313+ JFS_IMMUTABLE_FL | JFS_IXUNLINK_FL))) {
3314 if (!capable(CAP_LINUX_IMMUTABLE)) {
cc23e853 3315 inode_unlock(inode);
2380c486 3316 err = -EPERM;
537831f9 3317@@ -115,7 +131,7 @@ long jfs_ioctl(struct file *filp, unsign
d4263eb0
JR
3318 }
3319 }
3320
3321- flags = flags & JFS_FL_USER_MODIFIABLE;
3322+ flags &= JFS_FL_USER_MODIFIABLE;
3323 flags |= oldflags & ~JFS_FL_USER_MODIFIABLE;
3324 jfs_inode->mode2 = flags;
3325
cef7ea10
AM
3326diff -NurpP --minimal linux-4.9.82/fs/jfs/jfs_dinode.h linux-4.9.82-vs2.3.9.7/fs/jfs/jfs_dinode.h
3327--- linux-4.9.82/fs/jfs/jfs_dinode.h 2016-12-11 19:17:54.000000000 +0000
3328+++ linux-4.9.82-vs2.3.9.7/fs/jfs/jfs_dinode.h 2018-01-10 02:50:49.000000000 +0000
2380c486
JR
3329@@ -161,9 +161,13 @@ struct dinode {
3330
d337f35e
JR
3331 #define JFS_APPEND_FL 0x01000000 /* writes to file may only append */
3332 #define JFS_IMMUTABLE_FL 0x02000000 /* Immutable file */
2380c486 3333+#define JFS_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */
d337f35e
JR
3334
3335-#define JFS_FL_USER_VISIBLE 0x03F80000
2380c486 3336-#define JFS_FL_USER_MODIFIABLE 0x03F80000
d337f35e 3337+#define JFS_BARRIER_FL 0x04000000 /* Barrier for chroot() */
2380c486 3338+#define JFS_COW_FL 0x20000000 /* Copy on Write marker */
d337f35e 3339+
2380c486
JR
3340+#define JFS_FL_USER_VISIBLE 0x07F80000
3341+#define JFS_FL_USER_MODIFIABLE 0x07F80000
3342 #define JFS_FL_INHERIT 0x03C80000
d337f35e
JR
3343
3344 /* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */
cef7ea10
AM
3345diff -NurpP --minimal linux-4.9.82/fs/jfs/jfs_filsys.h linux-4.9.82-vs2.3.9.7/fs/jfs/jfs_filsys.h
3346--- linux-4.9.82/fs/jfs/jfs_filsys.h 2016-12-11 19:17:54.000000000 +0000
3347+++ linux-4.9.82-vs2.3.9.7/fs/jfs/jfs_filsys.h 2018-01-10 02:50:49.000000000 +0000
537831f9 3348@@ -266,6 +266,7 @@
ec22aa5c
AM
3349 #define JFS_NAME_MAX 255
3350 #define JFS_PATH_MAX BPSIZE
bd427b06 3351
ec22aa5c 3352+#define JFS_TAGGED 0x00800000 /* Context Tagging */
bd427b06 3353
ec22aa5c
AM
3354 /*
3355 * file system state (superblock state)
cef7ea10
AM
3356diff -NurpP --minimal linux-4.9.82/fs/jfs/jfs_imap.c linux-4.9.82-vs2.3.9.7/fs/jfs/jfs_imap.c
3357--- linux-4.9.82/fs/jfs/jfs_imap.c 2016-12-11 19:17:54.000000000 +0000
3358+++ linux-4.9.82-vs2.3.9.7/fs/jfs/jfs_imap.c 2018-01-10 02:50:49.000000000 +0000
78865d5b 3359@@ -46,6 +46,7 @@
ec22aa5c
AM
3360 #include <linux/pagemap.h>
3361 #include <linux/quotaops.h>
78865d5b 3362 #include <linux/slab.h>
ec22aa5c 3363+#include <linux/vs_tag.h>
bd427b06 3364
ec22aa5c
AM
3365 #include "jfs_incore.h"
3366 #include "jfs_inode.h"
cc23e853 3367@@ -3046,6 +3047,8 @@ static int copy_from_dinode(struct dinod
ec22aa5c
AM
3368 {
3369 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3370 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
a4a22af8
AM
3371+ kuid_t kuid;
3372+ kgid_t kgid;
bd427b06 3373
ec22aa5c
AM
3374 jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
3375 jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
cc23e853 3376@@ -3066,14 +3069,18 @@ static int copy_from_dinode(struct dinod
d337f35e 3377 }
f6c5ef8b 3378 set_nlink(ip, le32_to_cpu(dip->di_nlink));
bd427b06 3379
537831f9 3380- jfs_ip->saved_uid = make_kuid(&init_user_ns, le32_to_cpu(dip->di_uid));
a4a22af8
AM
3381+ kuid = make_kuid(&init_user_ns, le32_to_cpu(dip->di_uid));
3382+ kgid = make_kgid(&init_user_ns, le32_to_cpu(dip->di_gid));
3383+ ip->i_tag = INOTAG_KTAG(DX_TAG(ip), kuid, kgid, GLOBAL_ROOT_TAG);
ec22aa5c 3384+
a4a22af8 3385+ jfs_ip->saved_uid = INOTAG_KUID(DX_TAG(ip), kuid, kgid);
537831f9 3386 if (!uid_valid(sbi->uid))
ec22aa5c
AM
3387 ip->i_uid = jfs_ip->saved_uid;
3388 else {
3389 ip->i_uid = sbi->uid;
bd427b06
AM
3390 }
3391
537831f9 3392- jfs_ip->saved_gid = make_kgid(&init_user_ns, le32_to_cpu(dip->di_gid));
a4a22af8 3393+ jfs_ip->saved_gid = INOTAG_KGID(DX_TAG(ip), kuid, kgid);
537831f9 3394 if (!gid_valid(sbi->gid))
d337f35e
JR
3395 ip->i_gid = jfs_ip->saved_gid;
3396 else {
cc23e853 3397@@ -3138,16 +3145,14 @@ static void copy_to_dinode(struct dinode
d337f35e
JR
3398 dip->di_size = cpu_to_le64(ip->i_size);
3399 dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
3400 dip->di_nlink = cpu_to_le32(ip->i_nlink);
537831f9
AM
3401- if (!uid_valid(sbi->uid))
3402- dip->di_uid = cpu_to_le32(i_uid_read(ip));
d337f35e 3403- else
537831f9
AM
3404- dip->di_uid =cpu_to_le32(from_kuid(&init_user_ns,
3405- jfs_ip->saved_uid));
3406- if (!gid_valid(sbi->gid))
3407- dip->di_gid = cpu_to_le32(i_gid_read(ip));
d337f35e 3408- else
537831f9
AM
3409- dip->di_gid = cpu_to_le32(from_kgid(&init_user_ns,
3410- jfs_ip->saved_gid));
3411+ dip->di_uid = cpu_to_le32(from_kuid(&init_user_ns,
a4a22af8 3412+ TAGINO_KUID(DX_TAG(ip),
537831f9
AM
3413+ !uid_valid(sbi->uid) ? ip->i_uid : jfs_ip->saved_uid,
3414+ ip->i_tag)));
a4a22af8
AM
3415+ dip->di_gid = cpu_to_le32(from_kgid(&init_user_ns,
3416+ TAGINO_KGID(DX_TAG(ip),
537831f9
AM
3417+ !gid_valid(sbi->gid) ? ip->i_gid : jfs_ip->saved_gid,
3418+ ip->i_tag)));
2380c486 3419 jfs_get_inode_flags(jfs_ip);
d337f35e
JR
3420 /*
3421 * mode2 is only needed for storing the higher order bits.
cef7ea10
AM
3422diff -NurpP --minimal linux-4.9.82/fs/jfs/jfs_inode.c linux-4.9.82-vs2.3.9.7/fs/jfs/jfs_inode.c
3423--- linux-4.9.82/fs/jfs/jfs_inode.c 2016-12-11 19:17:54.000000000 +0000
3424+++ linux-4.9.82-vs2.3.9.7/fs/jfs/jfs_inode.c 2018-01-14 06:01:31.000000000 +0000
e22b5178
AM
3425@@ -18,6 +18,7 @@
3426
3427 #include <linux/fs.h>
3428 #include <linux/quotaops.h>
3429+#include <linux/vs_tag.h>
3430 #include "jfs_incore.h"
3431 #include "jfs_inode.h"
3432 #include "jfs_filsys.h"
cc23e853 3433@@ -33,6 +34,9 @@ void jfs_set_inode_flags(struct inode *i
d337f35e
JR
3434
3435 if (flags & JFS_IMMUTABLE_FL)
bb20add7 3436 new_fl |= S_IMMUTABLE;
2380c486 3437+ if (flags & JFS_IXUNLINK_FL)
cc23e853 3438+ new_fl |= S_IXUNLINK;
d337f35e 3439+
d337f35e 3440 if (flags & JFS_APPEND_FL)
bb20add7 3441 new_fl |= S_APPEND;
d337f35e 3442 if (flags & JFS_NOATIME_FL)
cc23e853 3443@@ -41,18 +45,35 @@ void jfs_set_inode_flags(struct inode *i
bb20add7 3444 new_fl |= S_DIRSYNC;
cc23e853
AM
3445 if (flags & JFS_SYNC_FL)
3446 new_fl |= S_SYNC;
bb20add7 3447- inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND | S_NOATIME |
cc23e853
AM
3448- S_DIRSYNC | S_SYNC);
3449+
3450+ inode_set_flags(inode, new_fl, S_IMMUTABLE | S_IXUNLINK |
3451+ S_APPEND | S_NOATIME | S_DIRSYNC | S_SYNC);
2380c486 3452+
bb20add7 3453+ new_fl = 0;
2380c486 3454+ if (flags & JFS_BARRIER_FL)
bb20add7 3455+ new_fl |= V_BARRIER;
2380c486 3456+ if (flags & JFS_COW_FL)
bb20add7
AM
3457+ new_fl |= V_COW;
3458+
3459+ set_mask_bits(&inode->i_vflags,
3460+ V_BARRIER | V_COW, new_fl);
2380c486
JR
3461 }
3462
3463 void jfs_get_inode_flags(struct jfs_inode_info *jfs_ip)
3464 {
3465 unsigned int flags = jfs_ip->vfs_inode.i_flags;
3466+ unsigned int vflags = jfs_ip->vfs_inode.i_vflags;
3467+
3468+ jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_IXUNLINK_FL |
3469+ JFS_APPEND_FL | JFS_NOATIME_FL |
3470+ JFS_DIRSYNC_FL | JFS_SYNC_FL |
3471+ JFS_BARRIER_FL | JFS_COW_FL);
3472
3473- jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_APPEND_FL | JFS_NOATIME_FL |
3474- JFS_DIRSYNC_FL | JFS_SYNC_FL);
3475 if (flags & S_IMMUTABLE)
3476 jfs_ip->mode2 |= JFS_IMMUTABLE_FL;
3477+ if (flags & S_IXUNLINK)
3478+ jfs_ip->mode2 |= JFS_IXUNLINK_FL;
3479+
3480 if (flags & S_APPEND)
3481 jfs_ip->mode2 |= JFS_APPEND_FL;
3482 if (flags & S_NOATIME)
cc23e853 3483@@ -61,6 +82,11 @@ void jfs_get_inode_flags(struct jfs_inod
2380c486
JR
3484 jfs_ip->mode2 |= JFS_DIRSYNC_FL;
3485 if (flags & S_SYNC)
3486 jfs_ip->mode2 |= JFS_SYNC_FL;
3487+
3488+ if (vflags & V_BARRIER)
3489+ jfs_ip->mode2 |= JFS_BARRIER_FL;
3490+ if (vflags & V_COW)
3491+ jfs_ip->mode2 |= JFS_COW_FL;
d337f35e
JR
3492 }
3493
3494 /*
cef7ea10
AM
3495diff -NurpP --minimal linux-4.9.82/fs/jfs/jfs_inode.h linux-4.9.82-vs2.3.9.7/fs/jfs/jfs_inode.h
3496--- linux-4.9.82/fs/jfs/jfs_inode.h 2016-12-11 19:17:54.000000000 +0000
3497+++ linux-4.9.82-vs2.3.9.7/fs/jfs/jfs_inode.h 2018-01-10 02:50:49.000000000 +0000
2380c486
JR
3498@@ -39,6 +39,7 @@ extern struct dentry *jfs_fh_to_dentry(s
3499 extern struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
3500 int fh_len, int fh_type);
d337f35e 3501 extern void jfs_set_inode_flags(struct inode *);
d4263eb0 3502+extern int jfs_sync_flags(struct inode *, int, int);
d337f35e 3503 extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
78865d5b 3504 extern int jfs_setattr(struct dentry *, struct iattr *);
d337f35e 3505
cef7ea10
AM
3506diff -NurpP --minimal linux-4.9.82/fs/jfs/namei.c linux-4.9.82-vs2.3.9.7/fs/jfs/namei.c
3507--- linux-4.9.82/fs/jfs/namei.c 2016-12-11 19:17:54.000000000 +0000
3508+++ linux-4.9.82-vs2.3.9.7/fs/jfs/namei.c 2018-01-10 02:50:49.000000000 +0000
d33d7b00 3509@@ -22,6 +22,7 @@
d337f35e
JR
3510 #include <linux/ctype.h>
3511 #include <linux/quotaops.h>
2380c486 3512 #include <linux/exportfs.h>
d337f35e
JR
3513+#include <linux/vs_tag.h>
3514 #include "jfs_incore.h"
3515 #include "jfs_superblock.h"
3516 #include "jfs_inode.h"
cc23e853 3517@@ -1484,6 +1485,7 @@ static struct dentry *jfs_lookup(struct
a168f21d 3518 jfs_err("jfs_lookup: iget failed on inum %d", (uint)inum);
d337f35e
JR
3519 }
3520
3521+ dx_propagate_tag(nd, ip);
d33d7b00
AM
3522 return d_splice_alias(ip, dentry);
3523 }
d337f35e 3524
cc23e853 3525@@ -1546,6 +1548,7 @@ const struct inode_operations jfs_dir_in
a168f21d 3526 .get_acl = jfs_get_acl,
bb20add7 3527 .set_acl = jfs_set_acl,
d337f35e
JR
3528 #endif
3529+ .sync_flags = jfs_sync_flags,
3530 };
3531
3532 const struct file_operations jfs_dir_operations = {
cef7ea10
AM
3533diff -NurpP --minimal linux-4.9.82/fs/jfs/super.c linux-4.9.82-vs2.3.9.7/fs/jfs/super.c
3534--- linux-4.9.82/fs/jfs/super.c 2018-02-22 21:18:47.000000000 +0000
3535+++ linux-4.9.82-vs2.3.9.7/fs/jfs/super.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 3536@@ -206,7 +206,8 @@ enum {
d337f35e
JR
3537 Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
3538 Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
537831f9
AM
3539 Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask,
3540- Opt_discard, Opt_nodiscard, Opt_discard_minblk
3541+ Opt_discard, Opt_nodiscard, Opt_discard_minblk,
d337f35e
JR
3542+ Opt_tag, Opt_notag, Opt_tagid
3543 };
3544
ec22aa5c 3545 static const match_table_t tokens = {
cc23e853 3546@@ -216,6 +217,10 @@ static const match_table_t tokens = {
d337f35e
JR
3547 {Opt_resize, "resize=%u"},
3548 {Opt_resize_nosize, "resize"},
3549 {Opt_errors, "errors=%s"},
3550+ {Opt_tag, "tag"},
3551+ {Opt_notag, "notag"},
3552+ {Opt_tagid, "tagid=%u"},
3553+ {Opt_tag, "tagxid"},
3554 {Opt_ignore, "noquota"},
3555 {Opt_ignore, "quota"},
3556 {Opt_usrquota, "usrquota"},
cc23e853 3557@@ -405,7 +410,20 @@ static int parse_options(char *options,
bb20add7 3558 pr_err("JFS: discard option not supported on device\n");
d337f35e
JR
3559 break;
3560 }
537831f9 3561-
d337f35e
JR
3562+#ifndef CONFIG_TAGGING_NONE
3563+ case Opt_tag:
3564+ *flag |= JFS_TAGGED;
3565+ break;
3566+ case Opt_notag:
3567+ *flag &= JFS_TAGGED;
3568+ break;
3569+#endif
3570+#ifdef CONFIG_PROPAGATE
3571+ case Opt_tagid:
3572+ /* use args[0] */
3573+ *flag |= JFS_TAGGED;
3574+ break;
3575+#endif
3576 default:
bb20add7
AM
3577 printk("jfs: Unrecognized mount option \"%s\" or missing value\n",
3578 p);
cc23e853 3579@@ -437,6 +455,12 @@ static int jfs_remount(struct super_bloc
bb20add7 3580 if (!parse_options(data, sb, &newLVSize, &flag))
d337f35e 3581 return -EINVAL;
ab30d09f 3582
d337f35e
JR
3583+ if ((flag & JFS_TAGGED) && !(sb->s_flags & MS_TAGGED)) {
3584+ printk(KERN_ERR "JFS: %s: tagging not permitted on remount.\n",
3585+ sb->s_id);
3586+ return -EINVAL;
3587+ }
3588+
3589 if (newLVSize) {
3590 if (sb->s_flags & MS_RDONLY) {
bb20add7
AM
3591 pr_err("JFS: resize requires volume to be mounted read-write\n");
3592@@ -517,6 +541,9 @@ static int jfs_fill_super(struct super_b
d337f35e
JR
3593 #ifdef CONFIG_JFS_POSIX_ACL
3594 sb->s_flags |= MS_POSIXACL;
3595 #endif
3596+ /* map mount option tagxid */
3597+ if (sbi->flag & JFS_TAGGED)
3598+ sb->s_flags |= MS_TAGGED;
3599
3600 if (newLVSize) {
537831f9 3601 pr_err("resize option for remount only\n");
cef7ea10
AM
3602diff -NurpP --minimal linux-4.9.82/fs/libfs.c linux-4.9.82-vs2.3.9.7/fs/libfs.c
3603--- linux-4.9.82/fs/libfs.c 2018-02-22 21:18:47.000000000 +0000
3604+++ linux-4.9.82-vs2.3.9.7/fs/libfs.c 2018-01-13 01:03:09.000000000 +0000
cc23e853 3605@@ -180,7 +180,8 @@ static inline unsigned char dt_type(stru
d337f35e
JR
3606 * both impossible due to the lock on directory.
3607 */
3608
c2e5f7c8 3609-int dcache_readdir(struct file *file, struct dir_context *ctx)
cc23e853 3610+static inline int do_dcache_readdir_filter(struct file *file,
c2e5f7c8 3611+ struct dir_context *ctx, int (*filter)(struct dentry *dentry))
d337f35e 3612 {
cc23e853
AM
3613 struct dentry *dentry = file->f_path.dentry;
3614 struct dentry *cursor = file->private_data;
3615@@ -194,9 +195,10 @@ int dcache_readdir(struct file *file, st
c2e5f7c8 3616 if (ctx->pos == 2)
cc23e853
AM
3617 p = &dentry->d_subdirs;
3618 while ((next = next_positive(dentry, p, 1)) != NULL) {
3619- if (!dir_emit(ctx, next->d_name.name, next->d_name.len,
3620+ if (!filter || filter(next))
3621+ if (!dir_emit(ctx, next->d_name.name, next->d_name.len,
3622 d_inode(next)->i_ino, dt_type(d_inode(next))))
3623- break;
3624+ break;
3625 moved = true;
3626 p = &next->d_child;
3627 ctx->pos++;
3628@@ -205,8 +207,22 @@ int dcache_readdir(struct file *file, st
3629 move_cursor(cursor, p);
d337f35e
JR
3630 return 0;
3631 }
c2e5f7c8
JR
3632+
3633 EXPORT_SYMBOL(dcache_readdir);
d337f35e 3634
c2e5f7c8 3635+int dcache_readdir(struct file *filp, struct dir_context *ctx)
d337f35e 3636+{
c2e5f7c8 3637+ return do_dcache_readdir_filter(filp, ctx, NULL);
d337f35e
JR
3638+}
3639+
c2e5f7c8
JR
3640+EXPORT_SYMBOL(dcache_readdir_filter);
3641+
3642+int dcache_readdir_filter(struct file *filp, struct dir_context *ctx,
d337f35e
JR
3643+ int (*filter)(struct dentry *))
3644+{
c2e5f7c8 3645+ return do_dcache_readdir_filter(filp, ctx, filter);
d337f35e 3646+}
d337f35e
JR
3647+
3648 ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
3649 {
3650 return -EISDIR;
cef7ea10
AM
3651diff -NurpP --minimal linux-4.9.82/fs/locks.c linux-4.9.82-vs2.3.9.7/fs/locks.c
3652--- linux-4.9.82/fs/locks.c 2016-12-11 19:17:54.000000000 +0000
3653+++ linux-4.9.82-vs2.3.9.7/fs/locks.c 2018-01-13 01:28:30.000000000 +0000
cc23e853
AM
3654@@ -127,6 +127,8 @@
3655 #include <linux/pid_namespace.h>
c2e5f7c8
JR
3656 #include <linux/hashtable.h>
3657 #include <linux/percpu.h>
d337f35e
JR
3658+#include <linux/vs_base.h>
3659+#include <linux/vs_limit.h>
3660
bb20add7
AM
3661 #define CREATE_TRACE_POINTS
3662 #include <trace/events/filelock.h>
cc23e853 3663@@ -292,11 +294,15 @@ static void locks_init_lock_heads(struct
d337f35e 3664 /* Allocate an empty lock structure. */
ab30d09f 3665 struct file_lock *locks_alloc_lock(void)
d337f35e 3666 {
a168f21d 3667- struct file_lock *fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
a0a3e0cf 3668+ struct file_lock *fl;
a168f21d
AM
3669
3670- if (fl)
3671- locks_init_lock_heads(fl);
a168f21d 3672+ fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
cc23e853 3673
a168f21d
AM
3674+ if (fl) {
3675+ locks_init_lock_heads(fl);
cc23e853 3676+ vx_locks_inc(fl);
a168f21d
AM
3677+ fl->fl_xid = -1;
3678+ }
3679 return fl;
3680 }
3681 EXPORT_SYMBOL_GPL(locks_alloc_lock);
cc23e853 3682@@ -348,6 +354,7 @@ void locks_init_lock(struct file_lock *f
a168f21d
AM
3683 {
3684 memset(fl, 0, sizeof(struct file_lock));
3685 locks_init_lock_heads(fl);
3686+ fl->fl_xid = -1;
3687 }
3688
3689 EXPORT_SYMBOL(locks_init_lock);
cc23e853 3690@@ -365,6 +372,7 @@ void locks_copy_conflock(struct file_loc
bb20add7
AM
3691 new->fl_start = fl->fl_start;
3692 new->fl_end = fl->fl_end;
d337f35e
JR
3693 new->fl_lmops = fl->fl_lmops;
3694+ new->fl_xid = fl->fl_xid;
bb20add7 3695 new->fl_ops = NULL;
d337f35e 3696
bb20add7 3697 if (fl->fl_lmops) {
cc23e853 3698@@ -426,7 +434,10 @@ flock_make_lock(struct file *filp, unsig
d337f35e
JR
3699 fl->fl_flags = FL_FLOCK;
3700 fl->fl_type = type;
3701 fl->fl_end = OFFSET_MAX;
cc23e853 3702-
d337f35e
JR
3703+
3704+ vxd_assert(filp->f_xid == vx_current_xid(),
3705+ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
3706+ fl->fl_xid = filp->f_xid;
bb20add7
AM
3707 return fl;
3708 }
cc23e853
AM
3709
3710@@ -548,6 +559,7 @@ static int lease_init(struct file *filp,
d337f35e 3711
bb20add7 3712 fl->fl_owner = filp;
d337f35e
JR
3713 fl->fl_pid = current->tgid;
3714+ fl->fl_xid = vx_current_xid();
3715
3716 fl->fl_file = filp;
3717 fl->fl_flags = FL_LEASE;
cc23e853 3718@@ -567,6 +579,10 @@ static struct file_lock *lease_alloc(str
d337f35e 3719 if (fl == NULL)
2380c486 3720 return ERR_PTR(error);
d337f35e
JR
3721
3722+ fl->fl_xid = vx_current_xid();
3723+ if (filp)
3724+ vxd_assert(filp->f_xid == fl->fl_xid,
3725+ "f_xid(%d) == fl_xid(%d)", filp->f_xid, fl->fl_xid);
d337f35e
JR
3726 error = lease_init(filp, type, fl);
3727 if (error) {
3728 locks_free_lock(fl);
cc23e853
AM
3729@@ -956,6 +972,7 @@ static int flock_lock_inode(struct inode
3730 goto out;
ab30d09f 3731 }
2380c486
JR
3732
3733+ new_fl->fl_xid = -1;
3734 find_conflict:
cc23e853
AM
3735 list_for_each_entry(fl, &ctx->flc_flock, fl_list) {
3736 if (!flock_locks_conflict(request, fl))
3737@@ -984,7 +1001,7 @@ out:
d337f35e
JR
3738 }
3739
cc23e853
AM
3740 static int posix_lock_inode(struct inode *inode, struct file_lock *request,
3741- struct file_lock *conflock)
3742+ struct file_lock *conflock, vxid_t xid)
d337f35e 3743 {
cc23e853 3744 struct file_lock *fl, *tmp;
d337f35e 3745 struct file_lock *new_fl = NULL;
cc23e853
AM
3746@@ -1000,6 +1017,9 @@ static int posix_lock_inode(struct inode
3747 if (!ctx)
3748 return (request->fl_type == F_UNLCK) ? 0 : -ENOMEM;
d337f35e 3749
cc23e853
AM
3750+ if (xid)
3751+ vxd_assert(xid == vx_current_xid(),
3752+ "xid(%d) == current(%d)", xid, vx_current_xid());
d337f35e
JR
3753 /*
3754 * We may need two file_lock structures for this operation,
3755 * so we get them in advance to avoid races.
cc23e853 3756@@ -1010,7 +1030,11 @@ static int posix_lock_inode(struct inode
d337f35e
JR
3757 (request->fl_type != F_UNLCK ||
3758 request->fl_start != 0 || request->fl_end != OFFSET_MAX)) {
3759 new_fl = locks_alloc_lock();
3760+ new_fl->fl_xid = xid;
cc23e853 3761+ // vx_locks_inc(new_fl);
d337f35e
JR
3762 new_fl2 = locks_alloc_lock();
3763+ new_fl2->fl_xid = xid;
cc23e853 3764+ // vx_locks_inc(new_fl2);
d337f35e
JR
3765 }
3766
cc23e853
AM
3767 percpu_down_read_preempt_disable(&file_rwsem);
3768@@ -1216,7 +1240,7 @@ static int posix_lock_inode(struct inode
2380c486 3769 int posix_lock_file(struct file *filp, struct file_lock *fl,
d337f35e
JR
3770 struct file_lock *conflock)
3771 {
cc23e853
AM
3772- return posix_lock_inode(locks_inode(filp), fl, conflock);
3773+ return posix_lock_inode(locks_inode(filp), fl, conflock, filp->f_xid);
d337f35e 3774 }
2380c486 3775 EXPORT_SYMBOL(posix_lock_file);
d337f35e 3776
cc23e853
AM
3777@@ -1232,7 +1256,7 @@ static int posix_lock_inode_wait(struct
3778 int error;
3779 might_sleep ();
3780 for (;;) {
3781- error = posix_lock_inode(inode, fl, NULL);
3782+ error = posix_lock_inode(inode, fl, NULL, 0);
3783 if (error != FILE_LOCK_DEFERRED)
3784 break;
3785 error = wait_event_interruptible(fl->fl_wait, !fl->fl_next);
3786@@ -1308,10 +1332,13 @@ int locks_mandatory_area(struct inode *i
3787 fl.fl_end = end;
3788
3789 for (;;) {
3790+ vxid_t f_xid = 0;
3791+
ca5d134c 3792 if (filp) {
bb20add7 3793 fl.fl_owner = filp;
ca5d134c 3794 fl.fl_flags &= ~FL_SLEEP;
cc23e853
AM
3795- error = posix_lock_inode(inode, &fl, NULL);
3796+ f_xid = filp->f_xid;
3797+ error = posix_lock_inode(inode, &fl, NULL, f_xid);
ca5d134c
JR
3798 if (!error)
3799 break;
3800 }
cc23e853 3801@@ -1319,7 +1346,7 @@ int locks_mandatory_area(struct inode *i
ca5d134c
JR
3802 if (sleep)
3803 fl.fl_flags |= FL_SLEEP;
3804 fl.fl_owner = current->files;
cc23e853
AM
3805- error = posix_lock_inode(inode, &fl, NULL);
3806+ error = posix_lock_inode(inode, &fl, NULL, f_xid);
2380c486 3807 if (error != FILE_LOCK_DEFERRED)
d337f35e 3808 break;
2380c486 3809 error = wait_event_interruptible(fl.fl_wait, !fl.fl_next);
cc23e853 3810@@ -2374,6 +2401,16 @@ int fcntl_setlk64(unsigned int fd, struc
d337f35e
JR
3811 if (file_lock == NULL)
3812 return -ENOLCK;
3813
3814+ vxd_assert(filp->f_xid == vx_current_xid(),
3815+ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
3816+ file_lock->fl_xid = filp->f_xid;
cc23e853 3817+ // vx_locks_inc(file_lock);
d337f35e 3818+
d337f35e
JR
3819+ vxd_assert(filp->f_xid == vx_current_xid(),
3820+ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
3821+ file_lock->fl_xid = filp->f_xid;
cc23e853 3822+ // vx_locks_inc(file_lock);
d337f35e
JR
3823+
3824 /*
3825 * This might block, so we do it before checking the inode.
3826 */
cc23e853 3827@@ -2710,8 +2747,11 @@ static int locks_show(struct seq_file *f
2380c486 3828
c2e5f7c8 3829 lock_get_status(f, fl, iter->li_pos, "");
2380c486
JR
3830
3831- list_for_each_entry(bfl, &fl->fl_block, fl_block)
3832+ list_for_each_entry(bfl, &fl->fl_block, fl_block) {
3833+ if (!vx_check(fl->fl_xid, VS_WATCH_P | VS_IDENT))
d337f35e 3834+ continue;
bb20add7 3835 lock_get_status(f, bfl, iter->li_pos, " ->");
2380c486 3836+ }
d337f35e 3837
2380c486 3838 return 0;
ab30d09f 3839 }
cef7ea10
AM
3840diff -NurpP --minimal linux-4.9.82/fs/mount.h linux-4.9.82-vs2.3.9.7/fs/mount.h
3841--- linux-4.9.82/fs/mount.h 2018-02-22 21:18:47.000000000 +0000
3842+++ linux-4.9.82-vs2.3.9.7/fs/mount.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 3843@@ -69,6 +69,7 @@ struct mount {
bb20add7 3844 struct hlist_head mnt_pins;
cc23e853
AM
3845 struct fs_pin mnt_umount;
3846 struct dentry *mnt_ex_mountpoint;
61333608 3847+ vtag_t mnt_tag; /* tagging used for vfsmount */
db55b927
AM
3848 };
3849
92598135 3850 #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
cef7ea10
AM
3851diff -NurpP --minimal linux-4.9.82/fs/namei.c linux-4.9.82-vs2.3.9.7/fs/namei.c
3852--- linux-4.9.82/fs/namei.c 2018-02-22 21:18:47.000000000 +0000
3853+++ linux-4.9.82-vs2.3.9.7/fs/namei.c 2018-01-13 05:43:43.000000000 +0000
cc23e853
AM
3854@@ -37,9 +37,19 @@
3855 #include <linux/hash.h>
3856 #include <linux/bitops.h>
3857 #include <linux/init_task.h>
d337f35e 3858+#include <linux/proc_fs.h>
09be7631 3859+#include <linux/magic.h>
d337f35e
JR
3860+#include <linux/vserver/inode.h>
3861+#include <linux/vs_base.h>
3862+#include <linux/vs_tag.h>
3863+#include <linux/vs_cowbl.h>
2380c486
JR
3864+#include <linux/vs_device.h>
3865+#include <linux/vs_context.h>
3866+#include <linux/pid_namespace.h>
d337f35e
JR
3867 #include <asm/uaccess.h>
3868
2bf5ad28 3869 #include "internal.h"
09be7631
JR
3870+#include "proc/internal.h"
3871 #include "mount.h"
3872
3873 /* [Feb-1997 T. Schoebel-Theuer]
cc23e853 3874@@ -285,6 +295,93 @@ static int check_acl(struct inode *inode
a168f21d
AM
3875 return -EAGAIN;
3876 }
d337f35e 3877
7e46296a 3878+static inline int dx_barrier(const struct inode *inode)
d337f35e 3879+{
2380c486
JR
3880+ if (IS_BARRIER(inode) && !vx_check(0, VS_ADMIN | VS_WATCH)) {
3881+ vxwprintk_task(1, "did hit the barrier.");
d337f35e
JR
3882+ return 1;
3883+ }
3884+ return 0;
3885+}
3886+
7e46296a 3887+static int __dx_permission(const struct inode *inode, int mask)
d337f35e
JR
3888+{
3889+ if (dx_barrier(inode))
3890+ return -EACCES;
d337f35e 3891+
2380c486
JR
3892+ if (inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) {
3893+ /* devpts is xid tagged */
3894+ if (S_ISDIR(inode->i_mode) ||
61333608 3895+ vx_check((vxid_t)i_tag_read(inode), VS_IDENT | VS_WATCH_P))
2380c486 3896+ return 0;
ba86f833 3897+
adc1caaa 3898+ /* just pretend we didn't find anything */
ba86f833 3899+ return -ENOENT;
2380c486
JR
3900+ }
3901+ else if (inode->i_sb->s_magic == PROC_SUPER_MAGIC) {
3902+ struct proc_dir_entry *de = PDE(inode);
3903+
bb20add7
AM
3904+ if (de && !vx_hide_check(0, de->vx_flags)) {
3905+ vxdprintk(VXD_CBIT(misc, 9),
3906+ VS_Q("%*s") " hidden by _dx_permission",
3907+ de->namelen, de->name);
2380c486 3908+ goto out;
bb20add7 3909+ }
2380c486
JR
3910+
3911+ if ((mask & (MAY_WRITE | MAY_APPEND))) {
3912+ struct pid *pid;
3913+ struct task_struct *tsk;
3914+
3915+ if (vx_check(0, VS_ADMIN | VS_WATCH_P) ||
3916+ vx_flags(VXF_STATE_SETUP, 0))
3917+ return 0;
3918+
3919+ pid = PROC_I(inode)->pid;
3920+ if (!pid)
3921+ goto out;
3922+
c6ceaf95 3923+ rcu_read_lock();
2380c486
JR
3924+ tsk = pid_task(pid, PIDTYPE_PID);
3925+ vxdprintk(VXD_CBIT(tag, 0), "accessing %p[#%u]",
3926+ tsk, (tsk ? vx_task_xid(tsk) : 0));
c6ceaf95
AM
3927+ if (tsk &&
3928+ vx_check(vx_task_xid(tsk), VS_IDENT | VS_WATCH_P)) {
3929+ rcu_read_unlock();
2380c486 3930+ return 0;
c6ceaf95
AM
3931+ }
3932+ rcu_read_unlock();
2380c486
JR
3933+ }
3934+ else {
3935+ /* FIXME: Should we block some entries here? */
3936+ return 0;
3937+ }
3938+ }
3939+ else {
3940+ if (dx_notagcheck(inode->i_sb) ||
61333608 3941+ dx_check((vxid_t)i_tag_read(inode),
537831f9 3942+ DX_HOSTID | DX_ADMIN | DX_WATCH | DX_IDENT))
2380c486
JR
3943+ return 0;
3944+ }
3945+
3946+out:
d337f35e
JR
3947+ return -EACCES;
3948+}
3949+
7e46296a 3950+int dx_permission(const struct inode *inode, int mask)
2380c486
JR
3951+{
3952+ int ret = __dx_permission(inode, mask);
3953+ if (unlikely(ret)) {
ba86f833
AM
3954+#ifndef CONFIG_VSERVER_WARN_DEVPTS
3955+ if (inode->i_sb->s_magic != DEVPTS_SUPER_MAGIC)
3956+#endif
3957+ vxwprintk_task(1,
3958+ "denied [0x%x] access to inode %s:%p[#%d,%lu]",
8ce283e1
AM
3959+ mask, inode->i_sb->s_id, inode,
3960+ i_tag_read(inode), inode->i_ino);
2380c486
JR
3961+ }
3962+ return ret;
3963+}
3964+
7e46296a 3965 /*
f6c5ef8b 3966 * This does the basic permission checking
7e46296a 3967 */
cc23e853 3968@@ -409,7 +506,7 @@ int __inode_permission(struct inode *ino
d337f35e
JR
3969 /*
3970 * Nobody gets write access to an immutable file.
3971 */
3972- if (IS_IMMUTABLE(inode))
3973+ if (IS_IMMUTABLE(inode) && !IS_COW(inode))
cc23e853
AM
3974 return -EPERM;
3975
3976 /*
3977@@ -421,6 +518,10 @@ int __inode_permission(struct inode *ino
d337f35e
JR
3978 return -EACCES;
3979 }
3980
2380c486
JR
3981+ retval = dx_permission(inode, mask);
3982+ if (retval)
d337f35e 3983+ return retval;
2380c486 3984+
a168f21d
AM
3985 retval = do_inode_permission(inode, mask);
3986 if (retval)
3987 return retval;
cc23e853 3988@@ -2781,7 +2882,7 @@ static int may_delete(struct inode *dir,
d337f35e 3989 return -EPERM;
c2e5f7c8
JR
3990
3991 if (check_sticky(dir, inode) || IS_APPEND(inode) ||
cc23e853
AM
3992- IS_IMMUTABLE(inode) || IS_SWAPFILE(inode) || HAS_UNMAPPED_ID(inode))
3993+ IS_IXORUNLINK(inode) || IS_SWAPFILE(inode) || HAS_UNMAPPED_ID(inode))
d337f35e
JR
3994 return -EPERM;
3995 if (isdir) {
bb20add7 3996 if (!d_is_dir(victim))
cc23e853 3997@@ -2869,19 +2970,25 @@ int vfs_create(struct inode *dir, struct
92598135 3998 bool want_excl)
a168f21d
AM
3999 {
4000 int error = may_create(dir, dentry);
a168f21d
AM
4001- if (error)
4002+ if (error) {
4003+ vxdprintk(VXD_CBIT(misc, 3), "may_create failed with %d", error);
537831f9 4004 return error;
a168f21d
AM
4005+ }
4006
4007 if (!dir->i_op->create)
4008 return -EACCES; /* shouldn't it be ENOSYS? */
4009 mode &= S_IALLUGO;
4010 mode |= S_IFREG;
4011 error = security_inode_create(dir, dentry, mode);
4012- if (error)
4013+ if (error) {
4014+ vxdprintk(VXD_CBIT(misc, 3), "security_inode_create failed with %d", error);
537831f9 4015 return error;
a168f21d 4016+ }
92598135 4017 error = dir->i_op->create(dir, dentry, mode, want_excl);
a168f21d
AM
4018 if (!error)
4019 fsnotify_create(dir, dentry);
4020+ else
4021+ vxdprintk(VXD_CBIT(misc, 3), "i_op->create failed with %d", error);
4022 return error;
4023 }
bb20add7 4024 EXPORT_SYMBOL(vfs_create);
cc23e853 4025@@ -2919,6 +3026,15 @@ static int may_open(struct path *path, i
ec22aa5c 4026 break;
2380c486 4027 }
d337f35e
JR
4028
4029+#ifdef CONFIG_VSERVER_COWBL
763640ca
JR
4030+ if (IS_COW(inode) &&
4031+ ((flag & O_ACCMODE) != O_RDONLY)) {
d337f35e
JR
4032+ if (IS_COW_LINK(inode))
4033+ return -EMLINK;
2380c486 4034+ inode->i_flags &= ~(S_IXUNLINK|S_IMMUTABLE);
d337f35e
JR
4035+ mark_inode_dirty(inode);
4036+ }
4037+#endif
cc23e853 4038 error = inode_permission(inode, MAY_OPEN | acc_mode);
d337f35e
JR
4039 if (error)
4040 return error;
cc23e853 4041@@ -3371,6 +3487,16 @@ finish_open:
7b17263b 4042 }
92598135 4043 finish_open_created:
7b17263b
AM
4044 error = may_open(&nd->path, acc_mode, open_flag);
4045+#ifdef CONFIG_VSERVER_COWBL
4046+ if (error == -EMLINK) {
4047+ struct dentry *dentry;
cc23e853 4048+ dentry = cow_break_link(nd->name->name);
7b17263b
AM
4049+ if (IS_ERR(dentry))
4050+ error = PTR_ERR(dentry);
4051+ else
4052+ dput(dentry);
4053+ }
4054+#endif
4055 if (error)
92598135 4056 goto out;
cc23e853
AM
4057 BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
4058@@ -3474,6 +3600,9 @@ static struct file *path_openat(struct n
92598135 4059 int opened = 0;
7b17263b
AM
4060 int error;
4061
cc23e853 4062+#ifdef CONFIG_VSERVER_COWBL
7b17263b 4063+restart:
cc23e853 4064+#endif
92598135 4065 file = get_empty_filp();
b00e13aa
AM
4066 if (IS_ERR(file))
4067 return file;
cc23e853
AM
4068@@ -3507,6 +3636,12 @@ static struct file *path_openat(struct n
4069 }
7b17263b 4070 }
cc23e853 4071 terminate_walk(nd);
7b17263b 4072+#ifdef CONFIG_VSERVER_COWBL
e915af4e 4073+ if (error == -EMLINK) {
cc23e853 4074+ // path_cleanup(nd);
7b17263b
AM
4075+ goto restart;
4076+ }
4077+#endif
cc23e853
AM
4078 out2:
4079 if (!(opened & FILE_OPENED)) {
4080 BUG_ON(!error);
4081@@ -3627,6 +3762,11 @@ static struct dentry *filename_create(in
a168f21d
AM
4082 goto fail;
4083 }
cc23e853
AM
4084 putname(name);
4085+ vxdprintk(VXD_CBIT(misc, 3), "filename_create path.dentry = %p (%.*s), dentry = %p (%.*s), d_inode = %p",
a168f21d
AM
4086+ path->dentry, path->dentry->d_name.len,
4087+ path->dentry->d_name.name, dentry,
4088+ dentry->d_name.len, dentry->d_name.name,
4089+ path->dentry->d_inode);
4090 return dentry;
92598135 4091 fail:
a168f21d 4092 dput(dentry);
cc23e853
AM
4093@@ -3745,6 +3885,7 @@ retry:
4094 error = vfs_mknod(path.dentry->d_inode,dentry,mode,0);
4095 break;
4096 }
4097+
4098 out:
4099 done_path_create(&path, dentry);
4100 if (retry_estale(error, lookup_flags)) {
4101@@ -4166,7 +4307,7 @@ int vfs_link(struct dentry *old_dentry,
d337f35e
JR
4102 /*
4103 * A link to an append-only or immutable file cannot be created.
4104 */
4105- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
4106+ if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
4107 return -EPERM;
cc23e853
AM
4108 /*
4109 * Updating the link count will likely cause i_uid and i_gid to
4110@@ -4696,6 +4837,326 @@ const char *vfs_get_link(struct dentry *
d337f35e 4111 }
cc23e853 4112 EXPORT_SYMBOL(vfs_get_link);
d337f35e
JR
4113
4114+
4115+#ifdef CONFIG_VSERVER_COWBL
4116+
2380c486 4117+static inline
cc23e853
AM
4118+void dump_path(const char *name, struct path *path)
4119+{
4120+ vxdprintk(VXD_CBIT(misc, 3),
4121+ "%s: path=%p mnt=%p dentry=%p", name, path,
4122+ path ? path->mnt : NULL,
4123+ path ? path->dentry : NULL);
4124+
4125+ if (path && path->mnt)
4126+ vxdprintk(VXD_CBIT(misc, 3),
4127+ "%s: path mnt_sb=%p[#%d,#%d] mnt_root=%p[#%d]", name,
4128+ path->mnt->mnt_sb,
4129+ path->mnt->mnt_sb ? path->mnt->mnt_sb->s_count : -1,
4130+ path->mnt->mnt_sb ? atomic_read(&path->mnt->mnt_sb->s_active) : -1,
4131+ path->mnt->mnt_root,
4132+ path->mnt->mnt_root ? path->mnt->mnt_root->d_lockref.count : -1);
4133+
4134+ if (path && path->dentry)
4135+ vxdprintk(VXD_CBIT(misc, 3),
4136+ "%s: path dentry=%p[#%d]", name,
4137+ path->dentry,
4138+ path->dentry ? path->dentry->d_lockref.count : -1);
4139+}
4140+
4141+static inline
2380c486
JR
4142+long do_cow_splice(struct file *in, struct file *out, size_t len)
4143+{
4144+ loff_t ppos = 0;
09be7631 4145+ loff_t opos = 0;
2380c486 4146+
09be7631 4147+ return do_splice_direct(in, &ppos, out, &opos, len, 0);
2380c486
JR
4148+}
4149+
d337f35e
JR
4150+struct dentry *cow_break_link(const char *pathname)
4151+{
b00e13aa 4152+ int ret, mode, pathlen, redo = 0, drop = 1;
cc23e853 4153+ struct path old_path = {}, par_path = {}, dir_path = {}, *new_path = NULL;
a168f21d 4154+ struct dentry *dir, *old_dentry, *new_dentry = NULL;
d337f35e
JR
4155+ struct file *old_file;
4156+ struct file *new_file;
cc23e853
AM
4157+ struct qstr new_qstr;
4158+ int new_type;
d337f35e
JR
4159+ char *to, *path, pad='\251';
4160+ loff_t size;
cc23e853
AM
4161+ struct filename *filename = getname_kernel(pathname);
4162+ struct filename *to_filename;
d337f35e 4163+
ba86f833
AM
4164+ vxdprintk(VXD_CBIT(misc, 1),
4165+ "cow_break_link(" VS_Q("%s") ")", pathname);
e915af4e 4166+
d337f35e 4167+ path = kmalloc(PATH_MAX, GFP_KERNEL);
2380c486 4168+ ret = -ENOMEM;
cc23e853 4169+ if (!path || IS_ERR(filename))
2380c486 4170+ goto out;
d337f35e 4171+
cc23e853
AM
4172+ /* old_path will have refs to dentry and mnt */
4173+ ret = filename_lookup(AT_FDCWD, filename, LOOKUP_FOLLOW, &old_path, NULL);
a168f21d 4174+ vxdprintk(VXD_CBIT(misc, 2),
e915af4e 4175+ "do_path_lookup(old): %d", ret);
2380c486
JR
4176+ if (ret < 0)
4177+ goto out_free_path;
d337f35e 4178+
cc23e853
AM
4179+ dump_path("cow (old)", &old_path);
4180+
e915af4e 4181+ /* no explicit reference for old_dentry here */
cc23e853 4182+ old_dentry = old_path.dentry;
2380c486 4183+
e915af4e 4184+ mode = old_dentry->d_inode->i_mode;
cc23e853 4185+ to = d_path(&old_path, path, PATH_MAX-2);
d337f35e 4186+ pathlen = strlen(to);
ba86f833 4187+ vxdprintk(VXD_CBIT(misc, 2),
a168f21d
AM
4188+ "old path " VS_Q("%s") " [%p:" VS_Q("%.*s") ":%d]", to,
4189+ old_dentry,
4190+ old_dentry->d_name.len, old_dentry->d_name.name,
4191+ old_dentry->d_name.len);
d337f35e 4192+
2380c486 4193+ to[pathlen + 1] = 0;
d337f35e 4194+retry:
a168f21d 4195+ new_dentry = NULL;
d337f35e 4196+ to[pathlen] = pad--;
a168f21d 4197+ ret = -ELOOP;
d337f35e
JR
4198+ if (pad <= '\240')
4199+ goto out_rel_old;
4200+
ba86f833 4201+ vxdprintk(VXD_CBIT(misc, 1), "temp copy " VS_Q("%s"), to);
e915af4e 4202+
cc23e853
AM
4203+ /* dir_path will have refs to dentry and mnt */
4204+ to_filename = getname_kernel(to);
4205+ to_filename = filename_parentat(AT_FDCWD, to_filename,
4206+ LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE, &par_path, &new_qstr, &new_type);
4207+ vxdprintk(VXD_CBIT(misc, 2), "filename_parentat(new): %p", to_filename);
4208+ dump_path("cow (par)", &par_path);
4209+ if (IS_ERR(to_filename))
2380c486
JR
4210+ goto retry;
4211+
cc23e853
AM
4212+ vxdprintk(VXD_CBIT(misc, 2), "to_filename refcnt=%d", to_filename->refcnt);
4213+
e915af4e
AM
4214+ /* this puppy downs the dir inode mutex if successful.
4215+ dir_path will hold refs to dentry and mnt and
b00e13aa 4216+ we'll have write access to the mnt */
cc23e853 4217+ new_dentry = filename_create(AT_FDCWD, to_filename, &dir_path, 0);
a168f21d 4218+ if (!new_dentry || IS_ERR(new_dentry)) {
cc23e853 4219+ path_put(&par_path);
a168f21d 4220+ vxdprintk(VXD_CBIT(misc, 2),
cc23e853 4221+ "filename_create(new) failed with %ld",
a168f21d 4222+ PTR_ERR(new_dentry));
d337f35e
JR
4223+ goto retry;
4224+ }
2380c486 4225+ vxdprintk(VXD_CBIT(misc, 2),
cc23e853 4226+ "filename_create(new): %p [" VS_Q("%.*s") ":%d]",
a168f21d
AM
4227+ new_dentry,
4228+ new_dentry->d_name.len, new_dentry->d_name.name,
4229+ new_dentry->d_name.len);
4230+
cc23e853
AM
4231+ dump_path("cow (dir)", &dir_path);
4232+
e915af4e
AM
4233+ /* take a reference on new_dentry */
4234+ dget(new_dentry);
4235+
4236+ /* dentry/mnt refs handed over to new_path */
4237+ new_path = &dir_path;
4238+
4239+ /* dentry for old/new dir */
cc23e853 4240+ dir = par_path.dentry;
d337f35e 4241+
e915af4e
AM
4242+ /* give up reference on dir */
4243+ dput(new_path->dentry);
4244+
4245+ /* new_dentry already has a reference */
4246+ new_path->dentry = new_dentry;
4247+
4248+ ret = vfs_create(dir->d_inode, new_dentry, mode, 1);
d337f35e
JR
4249+ vxdprintk(VXD_CBIT(misc, 2),
4250+ "vfs_create(new): %d", ret);
4251+ if (ret == -EEXIST) {
cc23e853
AM
4252+ path_put(&par_path);
4253+ inode_unlock(dir->d_inode);
e915af4e
AM
4254+ mnt_drop_write(new_path->mnt);
4255+ path_put(new_path);
4256+ new_dentry = NULL;
d337f35e
JR
4257+ goto retry;
4258+ }
2380c486
JR
4259+ else if (ret < 0)
4260+ goto out_unlock_new;
4261+
cc23e853 4262+ /* the old file went away */
2380c486 4263+ ret = -ENOENT;
a168f21d 4264+ if ((redo = d_unhashed(old_dentry)))
2380c486
JR
4265+ goto out_unlock_new;
4266+
e915af4e 4267+ /* doesn't change refs for old_path */
cc23e853 4268+ old_file = dentry_open(&old_path, O_RDONLY, current_cred());
d337f35e
JR
4269+ vxdprintk(VXD_CBIT(misc, 2),
4270+ "dentry_open(old): %p", old_file);
a168f21d
AM
4271+ if (IS_ERR(old_file)) {
4272+ ret = PTR_ERR(old_file);
2380c486
JR
4273+ goto out_unlock_new;
4274+ }
d337f35e 4275+
e915af4e
AM
4276+ /* doesn't change refs for new_path */
4277+ new_file = dentry_open(new_path, O_WRONLY, current_cred());
d337f35e
JR
4278+ vxdprintk(VXD_CBIT(misc, 2),
4279+ "dentry_open(new): %p", new_file);
a168f21d
AM
4280+ if (IS_ERR(new_file)) {
4281+ ret = PTR_ERR(new_file);
d337f35e 4282+ goto out_fput_old;
a168f21d 4283+ }
d337f35e 4284+
cc23e853
AM
4285+ /* unlock the inode from filename_create() */
4286+ inode_unlock(dir->d_inode);
b00e13aa
AM
4287+
4288+ /* drop write access to mnt */
4289+ mnt_drop_write(new_path->mnt);
4290+
4291+ drop = 0;
4292+
cc23e853 4293+ size = i_size_read(old_file->f_path.dentry->d_inode);
2380c486
JR
4294+ ret = do_cow_splice(old_file, new_file, size);
4295+ vxdprintk(VXD_CBIT(misc, 2), "do_splice_direct: %d", ret);
4296+ if (ret < 0) {
d337f35e 4297+ goto out_fput_both;
2380c486
JR
4298+ } else if (ret < size) {
4299+ ret = -ENOSPC;
4300+ goto out_fput_both;
4301+ } else {
a168f21d
AM
4302+ struct inode *old_inode = old_dentry->d_inode;
4303+ struct inode *new_inode = new_dentry->d_inode;
2380c486
JR
4304+ struct iattr attr = {
4305+ .ia_uid = old_inode->i_uid,
4306+ .ia_gid = old_inode->i_gid,
4307+ .ia_valid = ATTR_UID | ATTR_GID
4308+ };
4309+
93de0823
AM
4310+ setattr_copy(new_inode, &attr);
4311+ mark_inode_dirty(new_inode);
2380c486 4312+ }
d337f35e 4313+
e915af4e 4314+ /* lock rename mutex */
a168f21d 4315+ mutex_lock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
2380c486
JR
4316+
4317+ /* drop out late */
4318+ ret = -ENOENT;
a168f21d 4319+ if ((redo = d_unhashed(old_dentry)))
2380c486
JR
4320+ goto out_unlock;
4321+
4322+ vxdprintk(VXD_CBIT(misc, 2),
ba86f833 4323+ "vfs_rename: [" VS_Q("%*s") ":%d] -> [" VS_Q("%*s") ":%d]",
a168f21d
AM
4324+ new_dentry->d_name.len, new_dentry->d_name.name,
4325+ new_dentry->d_name.len,
4326+ old_dentry->d_name.len, old_dentry->d_name.name,
4327+ old_dentry->d_name.len);
cc23e853 4328+ ret = vfs_rename(par_path.dentry->d_inode, new_dentry,
eafa5b1d 4329+ old_dentry->d_parent->d_inode, old_dentry, NULL, 0);
d337f35e 4330+ vxdprintk(VXD_CBIT(misc, 2), "vfs_rename: %d", ret);
2380c486
JR
4331+
4332+out_unlock:
a168f21d 4333+ mutex_unlock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
d337f35e
JR
4334+
4335+out_fput_both:
4336+ vxdprintk(VXD_CBIT(misc, 3),
2380c486 4337+ "fput(new_file=%p[#%ld])", new_file,
4a036bed 4338+ atomic_long_read(&new_file->f_count));
d337f35e
JR
4339+ fput(new_file);
4340+
4341+out_fput_old:
4342+ vxdprintk(VXD_CBIT(misc, 3),
2380c486 4343+ "fput(old_file=%p[#%ld])", old_file,
4a036bed 4344+ atomic_long_read(&old_file->f_count));
d337f35e
JR
4345+ fput(old_file);
4346+
2380c486 4347+out_unlock_new:
cc23e853
AM
4348+ /* drop references from par_path */
4349+ path_put(&par_path);
e915af4e 4350+
b00e13aa 4351+ if (drop) {
cc23e853
AM
4352+ /* unlock the inode from filename_create() */
4353+ inode_unlock(dir->d_inode);
b00e13aa
AM
4354+
4355+ /* drop write access to mnt */
4356+ mnt_drop_write(new_path->mnt);
4357+ }
e915af4e 4358+
2380c486
JR
4359+ if (!ret)
4360+ goto out_redo;
4361+
4362+ /* error path cleanup */
c2e5f7c8 4363+ vfs_unlink(dir->d_inode, new_dentry, NULL);
2380c486
JR
4364+
4365+out_redo:
4366+ if (!redo)
4367+ goto out_rel_both;
e915af4e
AM
4368+
4369+ /* lookup dentry once again
cc23e853
AM
4370+ old_path will be freed as old_path in out_rel_old */
4371+ ret = filename_lookup(AT_FDCWD, filename, LOOKUP_FOLLOW, &old_path, NULL);
2380c486
JR
4372+ if (ret)
4373+ goto out_rel_both;
d337f35e 4374+
e915af4e 4375+ /* drop reference on new_dentry */
a168f21d 4376+ dput(new_dentry);
cc23e853 4377+ new_dentry = old_path.dentry;
e915af4e 4378+ dget(new_dentry);
2380c486 4379+ vxdprintk(VXD_CBIT(misc, 2),
763640ca 4380+ "do_path_lookup(redo): %p [" VS_Q("%.*s") ":%d]",
a168f21d
AM
4381+ new_dentry,
4382+ new_dentry->d_name.len, new_dentry->d_name.name,
4383+ new_dentry->d_name.len);
2380c486
JR
4384+
4385+out_rel_both:
cc23e853 4386+ dump_path("put (new)", new_path);
e915af4e
AM
4387+ if (new_path)
4388+ path_put(new_path);
d337f35e 4389+out_rel_old:
cc23e853
AM
4390+ dump_path("put (old)", &old_path);
4391+ path_put(&old_path);
2380c486 4392+out_free_path:
d337f35e 4393+ kfree(path);
2380c486 4394+out:
a168f21d
AM
4395+ if (ret) {
4396+ dput(new_dentry);
4397+ new_dentry = ERR_PTR(ret);
4398+ }
cc23e853
AM
4399+ // if (!IS_ERR(filename))
4400+ // putname(filename);
a168f21d 4401+ vxdprintk(VXD_CBIT(misc, 3),
e915af4e 4402+ "cow_break_link returning with %p", new_dentry);
a168f21d 4403+ return new_dentry;
d337f35e
JR
4404+}
4405+
4406+#endif
1e8b8f9b
AM
4407+
4408+int vx_info_mnt_namespace(struct mnt_namespace *ns, char *buffer)
4409+{
4410+ struct path path;
4411+ struct vfsmount *vmnt;
4412+ char *pstr, *root;
4413+ int length = 0;
4414+
4415+ pstr = kmalloc(PATH_MAX, GFP_KERNEL);
4416+ if (!pstr)
4417+ return 0;
4418+
4419+ vmnt = &ns->root->mnt;
4420+ path.mnt = vmnt;
4421+ path.dentry = vmnt->mnt_root;
4422+ root = d_path(&path, pstr, PATH_MAX - 2);
4423+ length = sprintf(buffer + length,
4424+ "Namespace:\t%p [#%u]\n"
4425+ "RootPath:\t%s\n",
4426+ ns, atomic_read(&ns->count),
4427+ root);
4428+ kfree(pstr);
4429+ return length;
4430+}
bb20add7 4431+
265de2f7 4432+EXPORT_SYMBOL(vx_info_mnt_namespace);
d337f35e
JR
4433+
4434 /* get the link contents into pagecache */
cc23e853
AM
4435 const char *page_get_link(struct dentry *dentry, struct inode *inode,
4436 struct delayed_call *callback)
cef7ea10
AM
4437diff -NurpP --minimal linux-4.9.82/fs/namespace.c linux-4.9.82-vs2.3.9.7/fs/namespace.c
4438--- linux-4.9.82/fs/namespace.c 2018-02-22 21:18:47.000000000 +0000
4439+++ linux-4.9.82-vs2.3.9.7/fs/namespace.c 2018-01-13 01:17:24.000000000 +0000
978063ce 4440@@ -24,6 +24,11 @@
09be7631 4441 #include <linux/magic.h>
52afa9bd 4442 #include <linux/bootmem.h>
bb20add7 4443 #include <linux/task_work.h>
d337f35e 4444+#include <linux/vs_base.h>
d337f35e
JR
4445+#include <linux/vs_context.h>
4446+#include <linux/vs_tag.h>
2380c486
JR
4447+#include <linux/vserver/space.h>
4448+#include <linux/vserver/global.h>
d337f35e 4449 #include "pnode.h"
db55b927
AM
4450 #include "internal.h"
4451
cc23e853 4452@@ -971,6 +976,10 @@ vfs_kern_mount(struct file_system_type *
be261992
AM
4453 if (!type)
4454 return ERR_PTR(-ENODEV);
4455
4456+ if ((type->fs_flags & FS_BINARY_MOUNTDATA) &&
4457+ !vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT))
4458+ return ERR_PTR(-EPERM);
4459+
4460 mnt = alloc_vfsmnt(name);
4461 if (!mnt)
4462 return ERR_PTR(-ENOMEM);
cc23e853 4463@@ -1061,6 +1070,7 @@ static struct mount *clone_mnt(struct mo
92598135
AM
4464 mnt->mnt.mnt_root = dget(root);
4465 mnt->mnt_mountpoint = mnt->mnt.mnt_root;
4466 mnt->mnt_parent = mnt;
c2e5f7c8
JR
4467+ mnt->mnt_tag = old->mnt_tag;
4468 lock_mount_hash();
92598135 4469 list_add_tail(&mnt->mnt_instance, &sb->s_mounts);
c2e5f7c8 4470 unlock_mount_hash();
cc23e853 4471@@ -1635,7 +1645,8 @@ out_unlock:
c2e5f7c8
JR
4472 */
4473 static inline bool may_mount(void)
4474 {
4475- return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN);
4476+ return vx_ns_capable(current->nsproxy->mnt_ns->user_ns,
4477+ CAP_SYS_ADMIN, VXC_SECURE_MOUNT);
4478 }
4479
cc23e853
AM
4480 static inline bool may_mandlock(void)
4481@@ -2144,6 +2155,7 @@ static int do_change_type(struct path *p
763640ca
JR
4482 if (err)
4483 goto out_unlock;
4484 }
4485+ // mnt->mnt_flags = mnt_flags;
4486
c2e5f7c8 4487 lock_mount_hash();
763640ca 4488 for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL))
cc23e853 4489@@ -2172,12 +2184,14 @@ static bool has_locked_children(struct m
ec22aa5c 4490 * do loopback mount.
d337f35e 4491 */
537831f9 4492 static int do_loopback(struct path *path, const char *old_name,
2380c486 4493- int recurse)
61333608 4494+ vtag_t tag, unsigned long flags, int mnt_flags)
d337f35e 4495 {
ec22aa5c 4496 struct path old_path;
09be7631
JR
4497 struct mount *mnt = NULL, *old, *parent;
4498 struct mountpoint *mp;
d337f35e 4499+ int recurse = flags & MS_REC;
b00e13aa 4500 int err;
2380c486 4501+
d337f35e 4502 if (!old_name || !*old_name)
b00e13aa
AM
4503 return -EINVAL;
4504 err = kern_path(old_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path);
cc23e853 4505@@ -2257,7 +2271,7 @@ static int change_mount_flags(struct vfs
ec22aa5c 4506 * on it - tough luck.
d337f35e 4507 */
ec22aa5c 4508 static int do_remount(struct path *path, int flags, int mnt_flags,
d337f35e 4509- void *data)
61333608 4510+ void *data, vxid_t xid)
d337f35e
JR
4511 {
4512 int err;
ec22aa5c 4513 struct super_block *sb = path->mnt->mnt_sb;
cc23e853 4514@@ -2742,6 +2756,7 @@ long do_mount(const char *dev_name, cons
ec22aa5c 4515 struct path path;
d337f35e
JR
4516 int retval = 0;
4517 int mnt_flags = 0;
61333608 4518+ vtag_t tag = 0;
d337f35e
JR
4519
4520 /* Discard magic */
4521 if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
cc23e853 4522@@ -2769,6 +2784,12 @@ long do_mount(const char *dev_name, cons
ec22aa5c
AM
4523 if (!(flags & MS_NOATIME))
4524 mnt_flags |= MNT_RELATIME;
d337f35e 4525
2380c486
JR
4526+ if (dx_parse_tag(data_page, &tag, 1, &mnt_flags, &flags)) {
4527+ /* FIXME: bind and re-mounts get the tag flag? */
d337f35e
JR
4528+ if (flags & (MS_BIND|MS_REMOUNT))
4529+ flags |= MS_TAGID;
4530+ }
d337f35e
JR
4531+
4532 /* Separate the per-mountpoint flags */
d337f35e
JR
4533 if (flags & MS_NOSUID)
4534 mnt_flags |= MNT_NOSUID;
cc23e853 4535@@ -2793,15 +2814,18 @@ long do_mount(const char *dev_name, cons
bb20add7
AM
4536 mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK;
4537 }
d337f35e 4538
b00e13aa 4539+ if (!vx_capable(CAP_SYS_ADMIN, VXC_DEV_MOUNT))
d337f35e 4540+ mnt_flags |= MNT_NODEV;
cc23e853 4541+
c146dd73 4542 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN |
ec22aa5c 4543 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
cc23e853 4544 MS_STRICTATIME | MS_NOREMOTELOCK | MS_SUBMOUNT);
d337f35e
JR
4545
4546 if (flags & MS_REMOUNT)
ec22aa5c 4547 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
d337f35e
JR
4548- data_page);
4549+ data_page, tag);
4550 else if (flags & MS_BIND)
ec22aa5c
AM
4551- retval = do_loopback(&path, dev_name, flags & MS_REC);
4552+ retval = do_loopback(&path, dev_name, tag, flags, mnt_flags);
d337f35e 4553 else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
ec22aa5c 4554 retval = do_change_type(&path, flags);
d337f35e 4555 else if (flags & MS_MOVE)
cc23e853 4556@@ -2942,6 +2966,7 @@ struct mnt_namespace *copy_mnt_ns(unsign
c2e5f7c8 4557 p = next_mnt(p, old);
d337f35e 4558 }
09be7631 4559 namespace_unlock();
2380c486
JR
4560+ atomic_inc(&vs_global_mnt_ns);
4561
4562 if (rootmnt)
4563 mntput(rootmnt);
cc23e853 4564@@ -3117,9 +3142,10 @@ SYSCALL_DEFINE2(pivot_root, const char _
db55b927
AM
4565 new_mnt = real_mount(new.mnt);
4566 root_mnt = real_mount(root.mnt);
09be7631
JR
4567 old_mnt = real_mount(old.mnt);
4568- if (IS_MNT_SHARED(old_mnt) ||
4569+ if ((IS_MNT_SHARED(old_mnt) ||
db55b927
AM
4570 IS_MNT_SHARED(new_mnt->mnt_parent) ||
4571- IS_MNT_SHARED(root_mnt->mnt_parent))
4572+ IS_MNT_SHARED(root_mnt->mnt_parent)) &&
50e68740 4573+ !vx_flags(VXF_STATE_SETUP, 0))
763640ca 4574 goto out4;
db55b927 4575 if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
763640ca 4576 goto out4;
cc23e853 4577@@ -3257,6 +3283,7 @@ void put_mnt_ns(struct mnt_namespace *ns
c2e5f7c8
JR
4578 if (!atomic_dec_and_test(&ns->count))
4579 return;
4580 drop_collected_mounts(&ns->root->mnt);
2380c486 4581+ atomic_dec(&vs_global_mnt_ns);
b00e13aa 4582 free_mnt_ns(ns);
2380c486 4583 }
db55b927 4584
cef7ea10
AM
4585diff -NurpP --minimal linux-4.9.82/fs/nfs/client.c linux-4.9.82-vs2.3.9.7/fs/nfs/client.c
4586--- linux-4.9.82/fs/nfs/client.c 2016-12-11 19:17:54.000000000 +0000
4587+++ linux-4.9.82-vs2.3.9.7/fs/nfs/client.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 4588@@ -586,6 +586,9 @@ int nfs_init_server_rpcclient(struct nfs
2380c486
JR
4589 if (server->flags & NFS_MOUNT_SOFT)
4590 server->client->cl_softrtry = 1;
d337f35e
JR
4591
4592+ server->client->cl_tag = 0;
4593+ if (server->flags & NFS_MOUNT_TAGGED)
4594+ server->client->cl_tag = 1;
4595 return 0;
4596 }
92598135 4597 EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
cc23e853 4598@@ -762,6 +765,10 @@ static void nfs_server_set_fsinfo(struct
d337f35e
JR
4599 server->acdirmin = server->acdirmax = 0;
4600 }
4601
4602+ /* FIXME: needs fsinfo
4603+ if (server->flags & NFS_MOUNT_TAGGED)
4604+ sb->s_flags |= MS_TAGGED; */
4605+
4606 server->maxfilesize = fsinfo->maxfilesize;
4607
ab30d09f 4608 server->time_delta = fsinfo->time_delta;
cef7ea10
AM
4609diff -NurpP --minimal linux-4.9.82/fs/nfs/dir.c linux-4.9.82-vs2.3.9.7/fs/nfs/dir.c
4610--- linux-4.9.82/fs/nfs/dir.c 2018-02-22 21:18:47.000000000 +0000
4611+++ linux-4.9.82-vs2.3.9.7/fs/nfs/dir.c 2018-01-10 02:50:49.000000000 +0000
c2e5f7c8 4612@@ -37,6 +37,7 @@
2380c486 4613 #include <linux/sched.h>
ab30d09f 4614 #include <linux/kmemleak.h>
d33d7b00 4615 #include <linux/xattr.h>
d337f35e
JR
4616+#include <linux/vs_tag.h>
4617
d337f35e 4618 #include "delegation.h"
ab30d09f 4619 #include "iostat.h"
cc23e853 4620@@ -1420,6 +1421,7 @@ struct dentry *nfs_lookup(struct inode *
42bc425c
AM
4621 /* Success: notify readdir to use READDIRPLUS */
4622 nfs_advise_use_readdirplus(dir);
d337f35e
JR
4623
4624+ dx_propagate_tag(nd, inode);
4625 no_entry:
cc23e853 4626 res = d_splice_alias(inode, dentry);
d337f35e 4627 if (res != NULL) {
cef7ea10
AM
4628diff -NurpP --minimal linux-4.9.82/fs/nfs/inode.c linux-4.9.82-vs2.3.9.7/fs/nfs/inode.c
4629--- linux-4.9.82/fs/nfs/inode.c 2018-02-22 21:18:47.000000000 +0000
4630+++ linux-4.9.82-vs2.3.9.7/fs/nfs/inode.c 2018-01-10 02:50:49.000000000 +0000
c2e5f7c8
JR
4631@@ -38,6 +38,7 @@
4632 #include <linux/slab.h>
d33d7b00 4633 #include <linux/compat.h>
db55b927 4634 #include <linux/freezer.h>
d337f35e
JR
4635+#include <linux/vs_tag.h>
4636
d337f35e 4637 #include <asm/uaccess.h>
1e8b8f9b 4638
cc23e853 4639@@ -383,6 +384,8 @@ nfs_fhget(struct super_block *sb, struct
ec22aa5c
AM
4640 if (inode->i_state & I_NEW) {
4641 struct nfs_inode *nfsi = NFS_I(inode);
4642 unsigned long now = jiffies;
a4a22af8
AM
4643+ kuid_t kuid;
4644+ kgid_t kgid;
ec22aa5c
AM
4645
4646 /* We set i_ino for the few things that still rely on it,
4647 * such as stat(2) */
cc23e853 4648@@ -427,8 +430,8 @@ nfs_fhget(struct super_block *sb, struct
f6c5ef8b 4649 inode->i_version = 0;
ec22aa5c 4650 inode->i_size = 0;
f6c5ef8b 4651 clear_nlink(inode);
b00e13aa
AM
4652- inode->i_uid = make_kuid(&init_user_ns, -2);
4653- inode->i_gid = make_kgid(&init_user_ns, -2);
a4a22af8
AM
4654+ kuid = make_kuid(&init_user_ns, -2);
4655+ kgid = make_kgid(&init_user_ns, -2);
ec22aa5c
AM
4656 inode->i_blocks = 0;
4657 memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
42bc425c 4658 nfsi->write_io = 0;
cc23e853 4659@@ -463,11 +466,11 @@ nfs_fhget(struct super_block *sb, struct
7e46296a 4660 else if (nfs_server_capable(inode, NFS_CAP_NLINK))
bb20add7 4661 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
ec22aa5c
AM
4662 if (fattr->valid & NFS_ATTR_FATTR_OWNER)
4663- inode->i_uid = fattr->uid;
a4a22af8 4664+ kuid = fattr->uid;
7e46296a 4665 else if (nfs_server_capable(inode, NFS_CAP_OWNER))
bb20add7 4666 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
ec22aa5c
AM
4667 if (fattr->valid & NFS_ATTR_FATTR_GROUP)
4668- inode->i_gid = fattr->gid;
a4a22af8 4669+ kgid = fattr->gid;
7e46296a 4670 else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP))
bb20add7 4671 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
42bc425c 4672 if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
cc23e853 4673@@ -478,6 +481,10 @@ nfs_fhget(struct super_block *sb, struct
ec22aa5c
AM
4674 */
4675 inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
4676 }
a4a22af8
AM
4677+ inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
4678+ inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
4679+ inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, GLOBAL_ROOT_TAG);
ec22aa5c 4680+ /* maybe fattr->xid someday */
c2e5f7c8
JR
4681
4682 nfs_setsecurity(inode, fattr, label);
4683
cc23e853 4684@@ -619,6 +626,8 @@ void nfs_setattr_update_inode(struct ino
d337f35e
JR
4685 inode->i_uid = attr->ia_uid;
4686 if ((attr->ia_valid & ATTR_GID) != 0)
4687 inode->i_gid = attr->ia_gid;
4688+ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
4689+ inode->i_tag = attr->ia_tag;
bb20add7
AM
4690 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ACCESS
4691 | NFS_INO_INVALID_ACL);
cc23e853
AM
4692 }
4693@@ -1272,7 +1281,9 @@ static int nfs_check_inode_attributes(st
d337f35e
JR
4694 struct nfs_inode *nfsi = NFS_I(inode);
4695 loff_t cur_size, new_isize;
2380c486 4696 unsigned long invalid = 0;
a4a22af8 4697-
b00e13aa
AM
4698+ kuid_t kuid;
4699+ kgid_t kgid;
4700+ ktag_t ktag;
d337f35e 4701
42bc425c 4702 if (nfs_have_delegated_attributes(inode))
a4a22af8 4703 return 0;
cc23e853
AM
4704@@ -1301,13 +1312,18 @@ static int nfs_check_inode_attributes(st
4705 }
ec22aa5c 4706 }
d337f35e 4707
a4a22af8
AM
4708+ kuid = INOTAG_KUID(DX_TAG(inode), fattr->uid, fattr->gid);
4709+ kgid = INOTAG_KGID(DX_TAG(inode), fattr->uid, fattr->gid);
4710+ ktag = INOTAG_KTAG(DX_TAG(inode), fattr->uid, fattr->gid, GLOBAL_ROOT_TAG);
d337f35e
JR
4711+
4712 /* Have any file permissions changed? */
ec22aa5c 4713 if ((fattr->valid & NFS_ATTR_FATTR_MODE) && (inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO))
9474138d 4714 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
b00e13aa
AM
4715- if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, fattr->uid))
4716+ if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, kuid))
ec22aa5c 4717 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
b00e13aa
AM
4718- if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, fattr->gid))
4719+ if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, kgid))
ec22aa5c
AM
4720 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
4721+ /* maybe check for tag too? */
d337f35e
JR
4722
4723 /* Has the link count changed? */
ec22aa5c 4724 if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink)
cc23e853 4725@@ -1666,6 +1682,9 @@ static int nfs_update_inode(struct inode
7e46296a 4726 unsigned long save_cache_validity;
cc23e853
AM
4727 bool have_writers = nfs_file_has_buffered_writers(nfsi);
4728 bool cache_revalidated = true;
a4a22af8
AM
4729+ kuid_t kuid;
4730+ kgid_t kgid;
4731+ ktag_t ktag;
d337f35e 4732
bb20add7 4733 dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n",
2380c486 4734 __func__, inode->i_sb->s_id, inode->i_ino,
cc23e853
AM
4735@@ -1785,6 +1804,9 @@ static int nfs_update_inode(struct inode
4736 cache_revalidated = false;
4737 }
d337f35e 4738
a4a22af8
AM
4739+ kuid = TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag);
4740+ kgid = TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag);
4741+ ktag = TAGINO_KTAG(DX_TAG(inode), inode->i_tag);
ec22aa5c
AM
4742
4743 if (fattr->valid & NFS_ATTR_FATTR_ATIME)
4744 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
cc23e853
AM
4745@@ -1839,6 +1861,10 @@ static int nfs_update_inode(struct inode
4746 cache_revalidated = false;
4747 }
ec22aa5c 4748
a4a22af8
AM
4749+ inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
4750+ inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
4751+ inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, ktag);
ec22aa5c
AM
4752+
4753 if (fattr->valid & NFS_ATTR_FATTR_NLINK) {
4754 if (inode->i_nlink != fattr->nlink) {
4755 invalid |= NFS_INO_INVALID_ATTR;
cef7ea10
AM
4756diff -NurpP --minimal linux-4.9.82/fs/nfs/nfs3xdr.c linux-4.9.82-vs2.3.9.7/fs/nfs/nfs3xdr.c
4757--- linux-4.9.82/fs/nfs/nfs3xdr.c 2016-12-11 19:17:54.000000000 +0000
4758+++ linux-4.9.82-vs2.3.9.7/fs/nfs/nfs3xdr.c 2018-01-10 02:50:49.000000000 +0000
78865d5b 4759@@ -20,6 +20,7 @@
d337f35e
JR
4760 #include <linux/nfs3.h>
4761 #include <linux/nfs_fs.h>
4762 #include <linux/nfsacl.h>
4763+#include <linux/vs_tag.h>
4764 #include "internal.h"
4765
4766 #define NFSDBG_FACILITY NFSDBG_XDR
b00e13aa 4767@@ -558,7 +559,8 @@ static __be32 *xdr_decode_nfstime3(__be3
d33d7b00
AM
4768 * set_mtime mtime;
4769 * };
4770 */
4771-static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
4772+static void encode_sattr3(struct xdr_stream *xdr,
4773+ const struct iattr *attr, int tag)
d337f35e 4774 {
d33d7b00
AM
4775 u32 nbytes;
4776 __be32 *p;
b00e13aa 4777@@ -590,15 +592,19 @@ static void encode_sattr3(struct xdr_str
d33d7b00 4778 } else
d337f35e 4779 *p++ = xdr_zero;
d33d7b00 4780
d337f35e
JR
4781- if (attr->ia_valid & ATTR_UID) {
4782+ if (attr->ia_valid & ATTR_UID ||
4783+ (tag && (attr->ia_valid & ATTR_TAG))) {
4784 *p++ = xdr_one;
b00e13aa 4785- *p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid));
a4a22af8
AM
4786+ *p++ = cpu_to_be32(from_kuid(&init_user_ns,
4787+ TAGINO_KUID(tag, attr->ia_uid, attr->ia_tag)));
d33d7b00 4788 } else
d337f35e 4789 *p++ = xdr_zero;
d33d7b00 4790
d337f35e
JR
4791- if (attr->ia_valid & ATTR_GID) {
4792+ if (attr->ia_valid & ATTR_GID ||
4793+ (tag && (attr->ia_valid & ATTR_TAG))) {
4794 *p++ = xdr_one;
b00e13aa 4795- *p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid));
a4a22af8
AM
4796+ *p++ = cpu_to_be32(from_kgid(&init_user_ns,
4797+ TAGINO_KGID(tag, attr->ia_gid, attr->ia_tag)));
d33d7b00 4798 } else
d337f35e 4799 *p++ = xdr_zero;
d33d7b00 4800
b00e13aa 4801@@ -887,7 +893,7 @@ static void nfs3_xdr_enc_setattr3args(st
d33d7b00 4802 const struct nfs3_sattrargs *args)
d337f35e 4803 {
d33d7b00
AM
4804 encode_nfs_fh3(xdr, args->fh);
4805- encode_sattr3(xdr, args->sattr);
4806+ encode_sattr3(xdr, args->sattr, req->rq_task->tk_client->cl_tag);
4807 encode_sattrguard3(xdr, args);
4808 }
d337f35e 4809
b00e13aa 4810@@ -1037,13 +1043,13 @@ static void nfs3_xdr_enc_write3args(stru
d33d7b00
AM
4811 * };
4812 */
4813 static void encode_createhow3(struct xdr_stream *xdr,
4814- const struct nfs3_createargs *args)
4815+ const struct nfs3_createargs *args, int tag)
d337f35e 4816 {
d33d7b00
AM
4817 encode_uint32(xdr, args->createmode);
4818 switch (args->createmode) {
4819 case NFS3_CREATE_UNCHECKED:
4820 case NFS3_CREATE_GUARDED:
4821- encode_sattr3(xdr, args->sattr);
4822+ encode_sattr3(xdr, args->sattr, tag);
4823 break;
4824 case NFS3_CREATE_EXCLUSIVE:
4825 encode_createverf3(xdr, args->verifier);
b00e13aa 4826@@ -1058,7 +1064,7 @@ static void nfs3_xdr_enc_create3args(str
d33d7b00
AM
4827 const struct nfs3_createargs *args)
4828 {
4829 encode_diropargs3(xdr, args->fh, args->name, args->len);
4830- encode_createhow3(xdr, args);
4831+ encode_createhow3(xdr, args, req->rq_task->tk_client->cl_tag);
4832 }
4833
4834 /*
b00e13aa 4835@@ -1074,7 +1080,7 @@ static void nfs3_xdr_enc_mkdir3args(stru
d33d7b00
AM
4836 const struct nfs3_mkdirargs *args)
4837 {
4838 encode_diropargs3(xdr, args->fh, args->name, args->len);
4839- encode_sattr3(xdr, args->sattr);
4840+ encode_sattr3(xdr, args->sattr, req->rq_task->tk_client->cl_tag);
d337f35e 4841 }
d33d7b00
AM
4842
4843 /*
b00e13aa 4844@@ -1091,9 +1097,9 @@ static void nfs3_xdr_enc_mkdir3args(stru
d33d7b00
AM
4845 * };
4846 */
4847 static void encode_symlinkdata3(struct xdr_stream *xdr,
4848- const struct nfs3_symlinkargs *args)
4849+ const struct nfs3_symlinkargs *args, int tag)
4850 {
4851- encode_sattr3(xdr, args->sattr);
4852+ encode_sattr3(xdr, args->sattr, tag);
4853 encode_nfspath3(xdr, args->pages, args->pathlen);
4854 }
4855
b00e13aa 4856@@ -1102,7 +1108,7 @@ static void nfs3_xdr_enc_symlink3args(st
d33d7b00
AM
4857 const struct nfs3_symlinkargs *args)
4858 {
4859 encode_diropargs3(xdr, args->fromfh, args->fromname, args->fromlen);
4860- encode_symlinkdata3(xdr, args);
4861+ encode_symlinkdata3(xdr, args, req->rq_task->tk_client->cl_tag);
cc23e853 4862 xdr->buf->flags |= XDRBUF_WRITE;
d33d7b00
AM
4863 }
4864
cc23e853 4865@@ -1131,24 +1137,24 @@ static void nfs3_xdr_enc_symlink3args(st
d33d7b00
AM
4866 * };
4867 */
4868 static void encode_devicedata3(struct xdr_stream *xdr,
4869- const struct nfs3_mknodargs *args)
4870+ const struct nfs3_mknodargs *args, int tag)
4871 {
4872- encode_sattr3(xdr, args->sattr);
4873+ encode_sattr3(xdr, args->sattr, tag);
4874 encode_specdata3(xdr, args->rdev);
4875 }
4876
4877 static void encode_mknoddata3(struct xdr_stream *xdr,
4878- const struct nfs3_mknodargs *args)
4879+ const struct nfs3_mknodargs *args, int tag)
4880 {
4881 encode_ftype3(xdr, args->type);
4882 switch (args->type) {
4883 case NF3CHR:
4884 case NF3BLK:
4885- encode_devicedata3(xdr, args);
4886+ encode_devicedata3(xdr, args, tag);
4887 break;
4888 case NF3SOCK:
4889 case NF3FIFO:
4890- encode_sattr3(xdr, args->sattr);
4891+ encode_sattr3(xdr, args->sattr, tag);
4892 break;
4893 case NF3REG:
4894 case NF3DIR:
cc23e853 4895@@ -1163,7 +1169,7 @@ static void nfs3_xdr_enc_mknod3args(stru
d33d7b00 4896 const struct nfs3_mknodargs *args)
d337f35e 4897 {
d33d7b00
AM
4898 encode_diropargs3(xdr, args->fh, args->name, args->len);
4899- encode_mknoddata3(xdr, args);
4900+ encode_mknoddata3(xdr, args, req->rq_task->tk_client->cl_tag);
4901 }
4902
4903 /*
cef7ea10
AM
4904diff -NurpP --minimal linux-4.9.82/fs/nfs/super.c linux-4.9.82-vs2.3.9.7/fs/nfs/super.c
4905--- linux-4.9.82/fs/nfs/super.c 2018-02-22 21:18:48.000000000 +0000
4906+++ linux-4.9.82-vs2.3.9.7/fs/nfs/super.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 4907@@ -54,6 +54,7 @@
b00e13aa 4908 #include <linux/parser.h>
1e8b8f9b
AM
4909 #include <linux/nsproxy.h>
4910 #include <linux/rcupdate.h>
d337f35e
JR
4911+#include <linux/vs_tag.h>
4912
d337f35e 4913 #include <asm/uaccess.h>
1e8b8f9b 4914
cc23e853 4915@@ -102,6 +103,7 @@ enum {
1e8b8f9b 4916 Opt_mountport,
ab30d09f 4917 Opt_mountvers,
ab30d09f
AM
4918 Opt_minorversion,
4919+ Opt_tagid,
4920
4921 /* Mount options that take string arguments */
1e8b8f9b 4922 Opt_nfsvers,
cc23e853 4923@@ -114,6 +116,9 @@ enum {
537831f9
AM
4924 /* Special mount options */
4925 Opt_userspace, Opt_deprecated, Opt_sloppy,
4926
4927+ /* Linux-VServer tagging options */
4928+ Opt_tag, Opt_notag,
4929+
4930 Opt_err
4931 };
4932
cc23e853 4933@@ -183,6 +188,10 @@ static const match_table_t nfs_mount_opt
537831f9
AM
4934 { Opt_fscache_uniq, "fsc=%s" },
4935 { Opt_local_lock, "local_lock=%s" },
ab30d09f
AM
4936
4937+ { Opt_tag, "tag" },
4938+ { Opt_notag, "notag" },
4939+ { Opt_tagid, "tagid=%u" },
4940+
537831f9
AM
4941 /* The following needs to be listed after all other options */
4942 { Opt_nfsvers, "v%s" },
ab30d09f 4943
cc23e853 4944@@ -644,6 +653,7 @@ static void nfs_show_mount_options(struc
2380c486 4945 { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
ec22aa5c
AM
4946 { NFS_MOUNT_UNSHARED, ",nosharecache", "" },
4947 { NFS_MOUNT_NORESVPORT, ",noresvport", "" },
d337f35e
JR
4948+ { NFS_MOUNT_TAGGED, ",tag", "" },
4949 { 0, NULL, NULL }
4950 };
4951 const struct proc_nfs_info *nfs_infop;
cc23e853 4952@@ -1341,6 +1351,14 @@ static int nfs_parse_mount_options(char
537831f9 4953 case Opt_nomigration:
cc23e853 4954 mnt->options &= ~NFS_OPTION_MIGRATION;
ab30d09f
AM
4955 break;
4956+#ifndef CONFIG_TAGGING_NONE
4957+ case Opt_tag:
4958+ mnt->flags |= NFS_MOUNT_TAGGED;
4959+ break;
4960+ case Opt_notag:
4961+ mnt->flags &= ~NFS_MOUNT_TAGGED;
4962+ break;
4963+#endif
4964
4965 /*
4966 * options that take numeric values
cc23e853 4967@@ -1427,6 +1445,12 @@ static int nfs_parse_mount_options(char
ab30d09f
AM
4968 goto out_invalid_value;
4969 mnt->minorversion = option;
4970 break;
4971+#ifdef CONFIG_PROPAGATE
4972+ case Opt_tagid:
4973+ /* use args[0] */
4974+ nfs_data.flags |= NFS_MOUNT_TAGGED;
4975+ break;
4976+#endif
4977
4978 /*
4979 * options that take text values
cef7ea10
AM
4980diff -NurpP --minimal linux-4.9.82/fs/nfsd/auth.c linux-4.9.82-vs2.3.9.7/fs/nfsd/auth.c
4981--- linux-4.9.82/fs/nfsd/auth.c 2018-02-22 21:18:48.000000000 +0000
4982+++ linux-4.9.82-vs2.3.9.7/fs/nfsd/auth.c 2018-02-10 15:15:43.000000000 +0000
bb20add7
AM
4983@@ -1,6 +1,7 @@
4984 /* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */
2bf5ad28
AM
4985
4986 #include <linux/sched.h>
d337f35e 4987+#include <linux/vs_tag.h>
2bf5ad28 4988 #include "nfsd.h"
2380c486 4989 #include "auth.h"
d337f35e 4990
bb20add7 4991@@ -35,6 +36,9 @@ int nfsd_setuser(struct svc_rqst *rqstp,
d337f35e 4992
ec22aa5c
AM
4993 new->fsuid = rqstp->rq_cred.cr_uid;
4994 new->fsgid = rqstp->rq_cred.cr_gid;
4995+ /* FIXME: this desperately needs a tag :)
61333608 4996+ new->xid = (vxid_t)INOTAG_TAG(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid, 0);
ec22aa5c 4997+ */
d337f35e 4998
ec22aa5c
AM
4999 rqgi = rqstp->rq_cred.cr_group_info;
5000
cef7ea10
AM
5001diff -NurpP --minimal linux-4.9.82/fs/nfsd/nfs3xdr.c linux-4.9.82-vs2.3.9.7/fs/nfsd/nfs3xdr.c
5002--- linux-4.9.82/fs/nfsd/nfs3xdr.c 2018-02-22 21:18:48.000000000 +0000
5003+++ linux-4.9.82-vs2.3.9.7/fs/nfsd/nfs3xdr.c 2018-01-10 02:50:49.000000000 +0000
b00e13aa 5004@@ -8,6 +8,7 @@
2bf5ad28
AM
5005
5006 #include <linux/namei.h>
b00e13aa 5007 #include <linux/sunrpc/svc_xprt.h>
d337f35e 5008+#include <linux/vs_tag.h>
2bf5ad28 5009 #include "xdr3.h"
2380c486 5010 #include "auth.h"
b00e13aa
AM
5011 #include "netns.h"
5012@@ -98,6 +99,8 @@ static __be32 *
d337f35e
JR
5013 decode_sattr3(__be32 *p, struct iattr *iap)
5014 {
5015 u32 tmp;
a4a22af8
AM
5016+ kuid_t kuid = GLOBAL_ROOT_UID;
5017+ kgid_t kgid = GLOBAL_ROOT_GID;
d337f35e
JR
5018
5019 iap->ia_valid = 0;
5020
b00e13aa
AM
5021@@ -106,15 +109,18 @@ decode_sattr3(__be32 *p, struct iattr *i
5022 iap->ia_mode = ntohl(*p++);
d337f35e
JR
5023 }
5024 if (*p++) {
b00e13aa 5025- iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++));
a4a22af8 5026+ kuid = make_kuid(&init_user_ns, ntohl(*p++));
b00e13aa
AM
5027 if (uid_valid(iap->ia_uid))
5028 iap->ia_valid |= ATTR_UID;
d337f35e
JR
5029 }
5030 if (*p++) {
b00e13aa 5031- iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++));
a4a22af8 5032+ kgid = make_kgid(&init_user_ns, ntohl(*p++));
b00e13aa
AM
5033 if (gid_valid(iap->ia_gid))
5034 iap->ia_valid |= ATTR_GID;
d337f35e 5035 }
a4a22af8
AM
5036+ iap->ia_uid = INOTAG_KUID(DX_TAG_NFSD, kuid, kgid);
5037+ iap->ia_gid = INOTAG_KGID(DX_TAG_NFSD, kuid, kgid);
5038+ iap->ia_tag = INOTAG_KTAG(DX_TAG_NFSD, kuid, kgid, GLOBAL_ROOT_TAG);
d337f35e
JR
5039 if (*p++) {
5040 u64 newsize;
5041
bb20add7 5042@@ -167,8 +173,12 @@ encode_fattr3(struct svc_rqst *rqstp, __
d337f35e 5043 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
bb20add7 5044 *p++ = htonl((u32) (stat->mode & S_IALLUGO));
d337f35e 5045 *p++ = htonl((u32) stat->nlink);
b00e13aa
AM
5046- *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
5047- *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
5048+ *p++ = htonl((u32) from_kuid(&init_user_ns,
a4a22af8 5049+ TAGINO_KUID(0 /* FIXME: DX_TAG(dentry->d_inode) */,
2380c486 5050+ stat->uid, stat->tag)));
b00e13aa 5051+ *p++ = htonl((u32) from_kgid(&init_user_ns,
a4a22af8 5052+ TAGINO_KGID(0 /* FIXME: DX_TAG(dentry->d_inode) */,
2380c486 5053+ stat->gid, stat->tag)));
d337f35e
JR
5054 if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
5055 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
5056 } else {
cef7ea10
AM
5057diff -NurpP --minimal linux-4.9.82/fs/nfsd/nfs4xdr.c linux-4.9.82-vs2.3.9.7/fs/nfsd/nfs4xdr.c
5058--- linux-4.9.82/fs/nfsd/nfs4xdr.c 2018-02-22 21:18:48.000000000 +0000
5059+++ linux-4.9.82-vs2.3.9.7/fs/nfsd/nfs4xdr.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 5060@@ -40,6 +40,7 @@
d33d7b00 5061 #include <linux/utsname.h>
a168f21d 5062 #include <linux/pagemap.h>
2380c486 5063 #include <linux/sunrpc/svcauth_gss.h>
d337f35e
JR
5064+#include <linux/vs_tag.h>
5065
d33d7b00
AM
5066 #include "idmap.h"
5067 #include "acl.h"
cc23e853 5068@@ -2677,12 +2678,16 @@ out_acl:
bb20add7 5069 *p++ = cpu_to_be32(stat.nlink);
d337f35e
JR
5070 }
5071 if (bmval1 & FATTR4_WORD1_OWNER) {
bb20add7
AM
5072- status = nfsd4_encode_user(xdr, rqstp, stat.uid);
5073+ status = nfsd4_encode_user(xdr, rqstp,
a4a22af8 5074+ TAGINO_KUID(DX_TAG(dentry->d_inode),
bb20add7 5075+ stat.uid, stat.tag));
d337f35e
JR
5076 if (status)
5077 goto out;
5078 }
5079 if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
bb20add7
AM
5080- status = nfsd4_encode_group(xdr, rqstp, stat.gid);
5081+ status = nfsd4_encode_group(xdr, rqstp,
a4a22af8 5082+ TAGINO_KGID(DX_TAG(dentry->d_inode),
bb20add7 5083+ stat.gid, stat.tag));
d337f35e 5084 if (status)
f15949f2
JR
5085 goto out;
5086 }
cef7ea10
AM
5087diff -NurpP --minimal linux-4.9.82/fs/nfsd/nfsxdr.c linux-4.9.82-vs2.3.9.7/fs/nfsd/nfsxdr.c
5088--- linux-4.9.82/fs/nfsd/nfsxdr.c 2018-02-22 21:18:48.000000000 +0000
5089+++ linux-4.9.82-vs2.3.9.7/fs/nfsd/nfsxdr.c 2018-01-10 02:50:49.000000000 +0000
b00e13aa
AM
5090@@ -7,6 +7,7 @@
5091 #include "vfs.h"
2bf5ad28 5092 #include "xdr.h"
2380c486 5093 #include "auth.h"
2bf5ad28 5094+#include <linux/vs_tag.h>
d337f35e
JR
5095
5096 #define NFSDDBG_FACILITY NFSDDBG_XDR
2bf5ad28 5097
b00e13aa 5098@@ -89,6 +90,8 @@ static __be32 *
d337f35e
JR
5099 decode_sattr(__be32 *p, struct iattr *iap)
5100 {
5101 u32 tmp, tmp1;
a4a22af8
AM
5102+ kuid_t kuid = GLOBAL_ROOT_UID;
5103+ kgid_t kgid = GLOBAL_ROOT_GID;
d337f35e
JR
5104
5105 iap->ia_valid = 0;
5106
b00e13aa
AM
5107@@ -101,15 +104,18 @@ decode_sattr(__be32 *p, struct iattr *ia
5108 iap->ia_mode = tmp;
d337f35e
JR
5109 }
5110 if ((tmp = ntohl(*p++)) != (u32)-1) {
b00e13aa 5111- iap->ia_uid = make_kuid(&init_user_ns, tmp);
a4a22af8 5112+ kuid = make_kuid(&init_user_ns, tmp);
b00e13aa
AM
5113 if (uid_valid(iap->ia_uid))
5114 iap->ia_valid |= ATTR_UID;
d337f35e
JR
5115 }
5116 if ((tmp = ntohl(*p++)) != (u32)-1) {
b00e13aa 5117- iap->ia_gid = make_kgid(&init_user_ns, tmp);
a4a22af8 5118+ kgid = make_kgid(&init_user_ns, tmp);
b00e13aa
AM
5119 if (gid_valid(iap->ia_gid))
5120 iap->ia_valid |= ATTR_GID;
d337f35e 5121 }
a4a22af8
AM
5122+ iap->ia_uid = INOTAG_KUID(DX_TAG_NFSD, kuid, kgid);
5123+ iap->ia_gid = INOTAG_KGID(DX_TAG_NFSD, kuid, kgid);
5124+ iap->ia_tag = INOTAG_KTAG(DX_TAG_NFSD, kuid, kgid, GLOBAL_ROOT_TAG);
d337f35e
JR
5125 if ((tmp = ntohl(*p++)) != (u32)-1) {
5126 iap->ia_valid |= ATTR_SIZE;
5127 iap->ia_size = tmp;
b00e13aa 5128@@ -154,8 +160,10 @@ encode_fattr(struct svc_rqst *rqstp, __b
d337f35e
JR
5129 *p++ = htonl(nfs_ftypes[type >> 12]);
5130 *p++ = htonl((u32) stat->mode);
5131 *p++ = htonl((u32) stat->nlink);
b00e13aa
AM
5132- *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
5133- *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
5134+ *p++ = htonl((u32) from_kuid(&init_user_ns,
a4a22af8 5135+ TAGINO_KUID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
b00e13aa 5136+ *p++ = htonl((u32) from_kgid(&init_user_ns,
a4a22af8 5137+ TAGINO_KGID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
d337f35e
JR
5138
5139 if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
5140 *p++ = htonl(NFS_MAXPATHLEN);
cef7ea10
AM
5141diff -NurpP --minimal linux-4.9.82/fs/ocfs2/dlmglue.c linux-4.9.82-vs2.3.9.7/fs/ocfs2/dlmglue.c
5142--- linux-4.9.82/fs/ocfs2/dlmglue.c 2018-02-22 21:18:49.000000000 +0000
5143+++ linux-4.9.82-vs2.3.9.7/fs/ocfs2/dlmglue.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 5144@@ -2120,6 +2120,7 @@ static void __ocfs2_stuff_meta_lvb(struc
d337f35e 5145 lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters);
b00e13aa
AM
5146 lvb->lvb_iuid = cpu_to_be32(i_uid_read(inode));
5147 lvb->lvb_igid = cpu_to_be32(i_gid_read(inode));
a4a22af8 5148+ lvb->lvb_itag = cpu_to_be16(i_tag_read(inode));
d337f35e
JR
5149 lvb->lvb_imode = cpu_to_be16(inode->i_mode);
5150 lvb->lvb_inlink = cpu_to_be16(inode->i_nlink);
5151 lvb->lvb_iatime_packed =
cc23e853 5152@@ -2170,6 +2171,7 @@ static void ocfs2_refresh_inode_from_lvb
d337f35e 5153
b00e13aa
AM
5154 i_uid_write(inode, be32_to_cpu(lvb->lvb_iuid));
5155 i_gid_write(inode, be32_to_cpu(lvb->lvb_igid));
5156+ i_tag_write(inode, be16_to_cpu(lvb->lvb_itag));
d337f35e 5157 inode->i_mode = be16_to_cpu(lvb->lvb_imode);
f6c5ef8b 5158 set_nlink(inode, be16_to_cpu(lvb->lvb_inlink));
d337f35e 5159 ocfs2_unpack_timespec(&inode->i_atime,
cef7ea10
AM
5160diff -NurpP --minimal linux-4.9.82/fs/ocfs2/dlmglue.h linux-4.9.82-vs2.3.9.7/fs/ocfs2/dlmglue.h
5161--- linux-4.9.82/fs/ocfs2/dlmglue.h 2018-02-22 21:18:49.000000000 +0000
5162+++ linux-4.9.82-vs2.3.9.7/fs/ocfs2/dlmglue.h 2018-01-10 02:50:49.000000000 +0000
2380c486
JR
5163@@ -46,7 +46,8 @@ struct ocfs2_meta_lvb {
5164 __be16 lvb_inlink;
5165 __be32 lvb_iattr;
5166 __be32 lvb_igeneration;
5167- __be32 lvb_reserved2;
d337f35e 5168+ __be16 lvb_itag;
2380c486
JR
5169+ __be16 lvb_reserved2;
5170 };
5171
ec22aa5c 5172 #define OCFS2_QINFO_LVB_VERSION 1
cef7ea10
AM
5173diff -NurpP --minimal linux-4.9.82/fs/ocfs2/file.c linux-4.9.82-vs2.3.9.7/fs/ocfs2/file.c
5174--- linux-4.9.82/fs/ocfs2/file.c 2018-02-22 21:18:49.000000000 +0000
5175+++ linux-4.9.82-vs2.3.9.7/fs/ocfs2/file.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 5176@@ -1151,7 +1151,7 @@ int ocfs2_setattr(struct dentry *dentry,
763640ca 5177 attr->ia_valid &= ~ATTR_SIZE;
d337f35e
JR
5178
5179 #define OCFS2_VALID_ATTRS (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_SIZE \
5180- | ATTR_GID | ATTR_UID | ATTR_MODE)
5181+ | ATTR_GID | ATTR_UID | ATTR_TAG | ATTR_MODE)
763640ca 5182 if (!(attr->ia_valid & OCFS2_VALID_ATTRS))
d337f35e 5183 return 0;
763640ca 5184
cef7ea10
AM
5185diff -NurpP --minimal linux-4.9.82/fs/ocfs2/inode.c linux-4.9.82-vs2.3.9.7/fs/ocfs2/inode.c
5186--- linux-4.9.82/fs/ocfs2/inode.c 2016-12-11 19:17:54.000000000 +0000
5187+++ linux-4.9.82-vs2.3.9.7/fs/ocfs2/inode.c 2018-01-10 02:50:49.000000000 +0000
78865d5b 5188@@ -28,6 +28,7 @@
d337f35e
JR
5189 #include <linux/highmem.h>
5190 #include <linux/pagemap.h>
ec22aa5c 5191 #include <linux/quotaops.h>
d337f35e
JR
5192+#include <linux/vs_tag.h>
5193
5194 #include <asm/byteorder.h>
5195
cc23e853 5196@@ -87,11 +88,13 @@ void ocfs2_set_inode_flags(struct inode
2380c486
JR
5197 {
5198 unsigned int flags = OCFS2_I(inode)->ip_attr;
5199
5200- inode->i_flags &= ~(S_IMMUTABLE |
5201+ inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK |
5202 S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
d337f35e
JR
5203
5204 if (flags & OCFS2_IMMUTABLE_FL)
5205 inode->i_flags |= S_IMMUTABLE;
2380c486
JR
5206+ if (flags & OCFS2_IXUNLINK_FL)
5207+ inode->i_flags |= S_IXUNLINK;
d337f35e
JR
5208
5209 if (flags & OCFS2_SYNC_FL)
5210 inode->i_flags |= S_SYNC;
cc23e853 5211@@ -101,25 +104,44 @@ void ocfs2_set_inode_flags(struct inode
2380c486
JR
5212 inode->i_flags |= S_NOATIME;
5213 if (flags & OCFS2_DIRSYNC_FL)
d337f35e 5214 inode->i_flags |= S_DIRSYNC;
2380c486
JR
5215+
5216+ inode->i_vflags &= ~(V_BARRIER | V_COW);
5217+
5218+ if (flags & OCFS2_BARRIER_FL)
5219+ inode->i_vflags |= V_BARRIER;
5220+ if (flags & OCFS2_COW_FL)
5221+ inode->i_vflags |= V_COW;
d337f35e
JR
5222 }
5223
2380c486
JR
5224 /* Propagate flags from i_flags to OCFS2_I(inode)->ip_attr */
5225 void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi)
5226 {
5227 unsigned int flags = oi->vfs_inode.i_flags;
5228+ unsigned int vflags = oi->vfs_inode.i_vflags;
5229+
5230+ oi->ip_attr &= ~(OCFS2_SYNC_FL | OCFS2_APPEND_FL |
5231+ OCFS2_IMMUTABLE_FL | OCFS2_IXUNLINK_FL |
5232+ OCFS2_NOATIME_FL | OCFS2_DIRSYNC_FL |
5233+ OCFS2_BARRIER_FL | OCFS2_COW_FL);
5234+
5235+ if (flags & S_IMMUTABLE)
5236+ oi->ip_attr |= OCFS2_IMMUTABLE_FL;
5237+ if (flags & S_IXUNLINK)
5238+ oi->ip_attr |= OCFS2_IXUNLINK_FL;
5239
5240- oi->ip_attr &= ~(OCFS2_SYNC_FL|OCFS2_APPEND_FL|
5241- OCFS2_IMMUTABLE_FL|OCFS2_NOATIME_FL|OCFS2_DIRSYNC_FL);
5242 if (flags & S_SYNC)
5243 oi->ip_attr |= OCFS2_SYNC_FL;
5244 if (flags & S_APPEND)
5245 oi->ip_attr |= OCFS2_APPEND_FL;
5246- if (flags & S_IMMUTABLE)
5247- oi->ip_attr |= OCFS2_IMMUTABLE_FL;
5248 if (flags & S_NOATIME)
5249 oi->ip_attr |= OCFS2_NOATIME_FL;
5250 if (flags & S_DIRSYNC)
5251 oi->ip_attr |= OCFS2_DIRSYNC_FL;
5252+
5253+ if (vflags & V_BARRIER)
5254+ oi->ip_attr |= OCFS2_BARRIER_FL;
5255+ if (vflags & V_COW)
5256+ oi->ip_attr |= OCFS2_COW_FL;
2380c486
JR
5257 }
5258
ec22aa5c 5259 struct inode *ocfs2_ilookup(struct super_block *sb, u64 blkno)
cc23e853 5260@@ -278,6 +300,8 @@ void ocfs2_populate_inode(struct inode *
d337f35e
JR
5261 struct super_block *sb;
5262 struct ocfs2_super *osb;
ec22aa5c 5263 int use_plocks = 1;
d337f35e
JR
5264+ uid_t uid;
5265+ gid_t gid;
5266
763640ca
JR
5267 sb = inode->i_sb;
5268 osb = OCFS2_SB(sb);
cc23e853 5269@@ -306,8 +330,12 @@ void ocfs2_populate_inode(struct inode *
d337f35e
JR
5270 inode->i_generation = le32_to_cpu(fe->i_generation);
5271 inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
5272 inode->i_mode = le16_to_cpu(fe->i_mode);
b00e13aa
AM
5273- i_uid_write(inode, le32_to_cpu(fe->i_uid));
5274- i_gid_write(inode, le32_to_cpu(fe->i_gid));
d337f35e
JR
5275+ uid = le32_to_cpu(fe->i_uid);
5276+ gid = le32_to_cpu(fe->i_gid);
b00e13aa
AM
5277+ i_uid_write(inode, INOTAG_UID(DX_TAG(inode), uid, gid));
5278+ i_gid_write(inode, INOTAG_GID(DX_TAG(inode), uid, gid));
5279+ i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), uid, gid,
5280+ /* le16_to_cpu(raw_inode->i_raw_tag) */ 0));
d337f35e
JR
5281
5282 /* Fast symlinks will have i_size but no allocated clusters. */
42bc425c 5283 if (S_ISLNK(inode->i_mode) && !fe->i_clusters) {
cef7ea10
AM
5284diff -NurpP --minimal linux-4.9.82/fs/ocfs2/inode.h linux-4.9.82-vs2.3.9.7/fs/ocfs2/inode.h
5285--- linux-4.9.82/fs/ocfs2/inode.h 2016-12-11 19:17:54.000000000 +0000
5286+++ linux-4.9.82-vs2.3.9.7/fs/ocfs2/inode.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 5287@@ -155,6 +155,7 @@ int ocfs2_mark_inode_dirty(handle_t *han
d337f35e
JR
5288
5289 void ocfs2_set_inode_flags(struct inode *inode);
2380c486 5290 void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi);
d4263eb0 5291+int ocfs2_sync_flags(struct inode *inode, int, int);
d337f35e 5292
2380c486
JR
5293 static inline blkcnt_t ocfs2_inode_sector_count(struct inode *inode)
5294 {
cef7ea10
AM
5295diff -NurpP --minimal linux-4.9.82/fs/ocfs2/ioctl.c linux-4.9.82-vs2.3.9.7/fs/ocfs2/ioctl.c
5296--- linux-4.9.82/fs/ocfs2/ioctl.c 2016-12-11 19:17:54.000000000 +0000
5297+++ linux-4.9.82-vs2.3.9.7/fs/ocfs2/ioctl.c 2018-01-10 02:50:49.000000000 +0000
1e8b8f9b 5298@@ -76,7 +76,41 @@ static int ocfs2_get_inode_attr(struct i
d337f35e
JR
5299 return status;
5300 }
5301
5302-static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
d4263eb0
JR
5303+int ocfs2_sync_flags(struct inode *inode, int flags, int vflags)
5304+{
5305+ struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
5306+ struct buffer_head *bh = NULL;
5307+ handle_t *handle = NULL;
5308+ int status;
5309+
5310+ status = ocfs2_inode_lock(inode, &bh, 1);
5311+ if (status < 0) {
5312+ mlog_errno(status);
5313+ return status;
5314+ }
5315+ handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
5316+ if (IS_ERR(handle)) {
5317+ status = PTR_ERR(handle);
5318+ mlog_errno(status);
5319+ goto bail_unlock;
5320+ }
5321+
5322+ inode->i_flags = flags;
5323+ inode->i_vflags = vflags;
5324+ ocfs2_get_inode_flags(OCFS2_I(inode));
5325+
5326+ status = ocfs2_mark_inode_dirty(handle, inode, bh);
5327+ if (status < 0)
5328+ mlog_errno(status);
5329+
5330+ ocfs2_commit_trans(osb, handle);
5331+bail_unlock:
5332+ ocfs2_inode_unlock(inode, 1);
5333+ brelse(bh);
5334+ return status;
5335+}
5336+
d337f35e
JR
5337+int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
5338 unsigned mask)
5339 {
5340 struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
09be7631
JR
5341@@ -116,6 +150,11 @@ static int ocfs2_set_inode_attr(struct i
5342 goto bail_unlock;
5343 }
2380c486
JR
5344
5345+ if (IS_BARRIER(inode)) {
5346+ vxwprintk_task(1, "messing with the barrier.");
5347+ goto bail_unlock;
5348+ }
5349+
5350 handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
5351 if (IS_ERR(handle)) {
5352 status = PTR_ERR(handle);
cc23e853 5353@@ -839,6 +878,7 @@ bail:
d4263eb0
JR
5354 return status;
5355 }
d337f35e 5356
d337f35e 5357+
d4263eb0
JR
5358 long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
5359 {
b00e13aa 5360 struct inode *inode = file_inode(filp);
cef7ea10
AM
5361diff -NurpP --minimal linux-4.9.82/fs/ocfs2/namei.c linux-4.9.82-vs2.3.9.7/fs/ocfs2/namei.c
5362--- linux-4.9.82/fs/ocfs2/namei.c 2016-12-11 19:17:54.000000000 +0000
5363+++ linux-4.9.82-vs2.3.9.7/fs/ocfs2/namei.c 2018-01-10 02:50:49.000000000 +0000
ec22aa5c 5364@@ -41,6 +41,7 @@
d337f35e
JR
5365 #include <linux/slab.h>
5366 #include <linux/highmem.h>
ec22aa5c 5367 #include <linux/quotaops.h>
d337f35e
JR
5368+#include <linux/vs_tag.h>
5369
d337f35e 5370 #include <cluster/masklog.h>
763640ca 5371
cc23e853 5372@@ -516,6 +517,7 @@ static int __ocfs2_mknod_locked(struct i
93de0823 5373 struct ocfs2_extent_list *fel;
ec22aa5c 5374 u16 feat;
265de2f7 5375 struct ocfs2_inode_info *oi = OCFS2_I(inode);
a4a22af8 5376+ ktag_t ktag;
d337f35e 5377
7e46296a
AM
5378 *new_fe_bh = NULL;
5379
cc23e853 5380@@ -553,8 +555,13 @@ static int __ocfs2_mknod_locked(struct i
76514441 5381 fe->i_suballoc_loc = cpu_to_le64(suballoc_loc);
d337f35e 5382 fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
2380c486 5383 fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot);
b00e13aa
AM
5384- fe->i_uid = cpu_to_le32(i_uid_read(inode));
5385- fe->i_gid = cpu_to_le32(i_gid_read(inode));
d337f35e 5386+
a4a22af8
AM
5387+ ktag = make_ktag(&init_user_ns, dx_current_fstag(osb->sb));
5388+ fe->i_uid = cpu_to_le32(from_kuid(&init_user_ns,
5389+ TAGINO_KUID(DX_TAG(inode), inode->i_uid, ktag)));
5390+ fe->i_gid = cpu_to_le32(from_kgid(&init_user_ns,
5391+ TAGINO_KGID(DX_TAG(inode), inode->i_gid, ktag)));
5392+ inode->i_tag = ktag; /* is this correct? */
ec22aa5c
AM
5393 fe->i_mode = cpu_to_le16(inode->i_mode);
5394 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
d337f35e 5395 fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
cef7ea10
AM
5396diff -NurpP --minimal linux-4.9.82/fs/ocfs2/ocfs2.h linux-4.9.82-vs2.3.9.7/fs/ocfs2/ocfs2.h
5397--- linux-4.9.82/fs/ocfs2/ocfs2.h 2018-02-22 21:18:49.000000000 +0000
5398+++ linux-4.9.82-vs2.3.9.7/fs/ocfs2/ocfs2.h 2018-01-10 02:50:49.000000000 +0000
cc23e853
AM
5399@@ -289,6 +289,7 @@ enum ocfs2_mount_options
5400 OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT = 1 << 15, /* Journal Async Commit */
5401 OCFS2_MOUNT_ERRORS_CONT = 1 << 16, /* Return EIO to the calling process on error */
5402 OCFS2_MOUNT_ERRORS_ROFS = 1 << 17, /* Change filesystem to read-only on error */
5403+ OCFS2_MOUNT_TAGGED = 1 << 18, /* use tagging */
d33d7b00
AM
5404 };
5405
bb20add7 5406 #define OCFS2_OSB_SOFT_RO 0x0001
cef7ea10
AM
5407diff -NurpP --minimal linux-4.9.82/fs/ocfs2/ocfs2_fs.h linux-4.9.82-vs2.3.9.7/fs/ocfs2/ocfs2_fs.h
5408--- linux-4.9.82/fs/ocfs2/ocfs2_fs.h 2016-12-11 19:17:54.000000000 +0000
5409+++ linux-4.9.82-vs2.3.9.7/fs/ocfs2/ocfs2_fs.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 5410@@ -275,6 +275,11 @@
93de0823
AM
5411 #define OCFS2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/
5412 #define OCFS2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */
2380c486 5413
93de0823
AM
5414+#define OCFS2_IXUNLINK_FL FS_IXUNLINK_FL /* Immutable invert on unlink */
5415+
5416+#define OCFS2_BARRIER_FL FS_BARRIER_FL /* Barrier for chroot() */
5417+#define OCFS2_COW_FL FS_COW_FL /* Copy on Write marker */
5418+
5419 #define OCFS2_FL_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */
5420 #define OCFS2_FL_MODIFIABLE FS_FL_USER_MODIFIABLE /* User modifiable flags */
5421
cef7ea10
AM
5422diff -NurpP --minimal linux-4.9.82/fs/ocfs2/super.c linux-4.9.82-vs2.3.9.7/fs/ocfs2/super.c
5423--- linux-4.9.82/fs/ocfs2/super.c 2016-12-11 19:17:54.000000000 +0000
5424+++ linux-4.9.82-vs2.3.9.7/fs/ocfs2/super.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 5425@@ -188,6 +188,7 @@ enum {
76514441 5426 Opt_dir_resv_level,
cc23e853
AM
5427 Opt_journal_async_commit,
5428 Opt_err_cont,
d337f35e
JR
5429+ Opt_tag, Opt_notag, Opt_tagid,
5430 Opt_err,
5431 };
5432
cc23e853 5433@@ -221,6 +222,9 @@ static const match_table_t tokens = {
76514441 5434 {Opt_dir_resv_level, "dir_resv_level=%u"},
cc23e853
AM
5435 {Opt_journal_async_commit, "journal_async_commit"},
5436 {Opt_err_cont, "errors=continue"},
d337f35e 5437+ {Opt_tag, "tag"},
d337f35e
JR
5438+ {Opt_notag, "notag"},
5439+ {Opt_tagid, "tagid=%u"},
5440 {Opt_err, NULL}
5441 };
5442
cc23e853 5443@@ -673,6 +677,13 @@ static int ocfs2_remount(struct super_bl
d337f35e
JR
5444 goto out;
5445 }
5446
d4263eb0
JR
5447+ if ((osb->s_mount_opt & OCFS2_MOUNT_TAGGED) !=
5448+ (parsed_options.mount_opt & OCFS2_MOUNT_TAGGED)) {
d337f35e
JR
5449+ ret = -EINVAL;
5450+ mlog(ML_ERROR, "Cannot change tagging on remount\n");
5451+ goto out;
5452+ }
5453+
ab30d09f
AM
5454 /* We're going to/from readonly mode. */
5455 if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
5456 /* Disable quota accounting before remounting RO */
cc23e853 5457@@ -1162,6 +1173,9 @@ static int ocfs2_fill_super(struct super
d337f35e
JR
5458
5459 ocfs2_complete_mount_recovery(osb);
5460
5461+ if (osb->s_mount_opt & OCFS2_MOUNT_TAGGED)
5462+ sb->s_flags |= MS_TAGGED;
5463+
2380c486
JR
5464 if (ocfs2_mount_local(osb))
5465 snprintf(nodestr, sizeof(nodestr), "local");
5466 else
cc23e853
AM
5467@@ -1481,6 +1495,20 @@ static int ocfs2_parse_options(struct su
5468 case Opt_journal_async_commit:
5469 mopt->mount_opt |= OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT;
d337f35e
JR
5470 break;
5471+#ifndef CONFIG_TAGGING_NONE
5472+ case Opt_tag:
2380c486 5473+ mopt->mount_opt |= OCFS2_MOUNT_TAGGED;
d337f35e
JR
5474+ break;
5475+ case Opt_notag:
2380c486 5476+ mopt->mount_opt &= ~OCFS2_MOUNT_TAGGED;
d337f35e
JR
5477+ break;
5478+#endif
5479+#ifdef CONFIG_PROPAGATE
5480+ case Opt_tagid:
5481+ /* use args[0] */
2380c486 5482+ mopt->mount_opt |= OCFS2_MOUNT_TAGGED;
d337f35e
JR
5483+ break;
5484+#endif
5485 default:
5486 mlog(ML_ERROR,
5487 "Unrecognized mount option \"%s\" "
cef7ea10
AM
5488diff -NurpP --minimal linux-4.9.82/fs/open.c linux-4.9.82-vs2.3.9.7/fs/open.c
5489--- linux-4.9.82/fs/open.c 2018-02-22 21:18:49.000000000 +0000
5490+++ linux-4.9.82-vs2.3.9.7/fs/open.c 2018-01-13 22:17:33.000000000 +0000
b00e13aa 5491@@ -31,6 +31,11 @@
2bf5ad28 5492 #include <linux/ima.h>
93de0823 5493 #include <linux/dnotify.h>
b00e13aa 5494 #include <linux/compat.h>
d337f35e
JR
5495+#include <linux/vs_base.h>
5496+#include <linux/vs_limit.h>
d337f35e
JR
5497+#include <linux/vs_tag.h>
5498+#include <linux/vs_cowbl.h>
78865d5b 5499+#include <linux/vserver/dlimit.h>
d337f35e 5500
2bf5ad28
AM
5501 #include "internal.h"
5502
cc23e853
AM
5503@@ -65,12 +70,17 @@ int do_truncate(struct dentry *dentry, l
5504 return ret;
5505 }
5506
5507-long vfs_truncate(const struct path *path, loff_t length)
5508+long vfs_truncate(struct path *path, loff_t length)
5509 {
b00e13aa 5510 struct inode *inode;
cc23e853 5511 struct dentry *upperdentry;
b00e13aa
AM
5512 long error;
5513
76514441 5514+#ifdef CONFIG_VSERVER_COWBL
b00e13aa 5515+ error = cow_check_and_break(path);
d337f35e 5516+ if (error)
b00e13aa 5517+ goto out;
76514441 5518+#endif
b00e13aa 5519 inode = path->dentry->d_inode;
d337f35e 5520
a168f21d 5521 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
cc23e853 5522@@ -565,6 +575,13 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons
b00e13aa
AM
5523 unsigned int lookup_flags = LOOKUP_FOLLOW;
5524 retry:
5525 error = user_path_at(dfd, filename, lookup_flags, &path);
a168f21d 5526+#ifdef CONFIG_VSERVER_COWBL
b00e13aa 5527+ if (!error) {
a168f21d 5528+ error = cow_check_and_break(&path);
b00e13aa
AM
5529+ if (error)
5530+ path_put(&path);
5531+ }
a168f21d 5532+#endif
b00e13aa 5533 if (!error) {
a168f21d
AM
5534 error = chmod_common(&path, mode);
5535 path_put(&path);
cc23e853 5536@@ -599,13 +616,15 @@ retry_deleg:
42bc425c
AM
5537 if (!uid_valid(uid))
5538 return -EINVAL;
d337f35e 5539 newattrs.ia_valid |= ATTR_UID;
42bc425c 5540- newattrs.ia_uid = uid;
8ce283e1
AM
5541+ newattrs.ia_uid = make_kuid(&init_user_ns,
5542+ dx_map_uid(user));
d337f35e
JR
5543 }
5544 if (group != (gid_t) -1) {
42bc425c
AM
5545 if (!gid_valid(gid))
5546 return -EINVAL;
d337f35e 5547 newattrs.ia_valid |= ATTR_GID;
42bc425c 5548- newattrs.ia_gid = gid;
8ce283e1
AM
5549+ newattrs.ia_gid = make_kgid(&init_user_ns,
5550+ dx_map_gid(group));
d337f35e
JR
5551 }
5552 if (!S_ISDIR(inode->i_mode))
2380c486 5553 newattrs.ia_valid |=
cc23e853 5554@@ -643,6 +662,10 @@ retry:
2380c486 5555 error = mnt_want_write(path.mnt);
d337f35e 5556 if (error)
2380c486 5557 goto out_release;
d337f35e 5558+#ifdef CONFIG_VSERVER_COWBL
2380c486 5559+ error = cow_check_and_break(&path);
d337f35e 5560+ if (!error)
d337f35e 5561+#endif
2bf5ad28 5562 error = chown_common(&path, user, group);
2380c486
JR
5563 mnt_drop_write(path.mnt);
5564 out_release:
cef7ea10
AM
5565diff -NurpP --minimal linux-4.9.82/fs/proc/array.c linux-4.9.82-vs2.3.9.7/fs/proc/array.c
5566--- linux-4.9.82/fs/proc/array.c 2018-02-22 21:18:51.000000000 +0000
5567+++ linux-4.9.82-vs2.3.9.7/fs/proc/array.c 2018-01-25 00:21:32.000000000 +0000
cc23e853
AM
5568@@ -85,6 +85,8 @@
5569 #include <linux/string_helpers.h>
42bc425c 5570 #include <linux/user_namespace.h>
cc23e853 5571 #include <linux/fs_struct.h>
d337f35e
JR
5572+#include <linux/vs_context.h>
5573+#include <linux/vs_network.h>
5574
d337f35e 5575 #include <asm/pgtable.h>
2380c486 5576 #include <asm/processor.h>
cc23e853 5577@@ -169,6 +171,9 @@ static inline void task_state(struct seq
2380c486
JR
5578 ppid = pid_alive(p) ?
5579 task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
cc23e853 5580
2380c486
JR
5581+ if (unlikely(vx_current_initpid(p->pid)))
5582+ ppid = 0;
5583+
cc23e853
AM
5584 tracer = ptrace_parent(p);
5585 if (tracer)
5586 tpid = task_pid_nr_ns(tracer, ns);
5587@@ -306,8 +311,8 @@ static inline void task_sig(struct seq_f
bb20add7 5588 render_sigset_t(m, "SigCgt:\t", &caught);
2380c486
JR
5589 }
5590
bb20add7 5591-static void render_cap_t(struct seq_file *m, const char *header,
2380c486 5592- kernel_cap_t *a)
bb20add7 5593+void render_cap_t(struct seq_file *m, const char *header,
2380c486 5594+ struct vx_info *vxi, kernel_cap_t *a)
d337f35e 5595 {
2380c486
JR
5596 unsigned __capi;
5597
cc23e853
AM
5598@@ -334,11 +339,12 @@ static inline void task_cap(struct seq_f
5599 cap_ambient = cred->cap_ambient;
bb20add7 5600 rcu_read_unlock();
2380c486 5601
ec22aa5c
AM
5602- render_cap_t(m, "CapInh:\t", &cap_inheritable);
5603- render_cap_t(m, "CapPrm:\t", &cap_permitted);
5604- render_cap_t(m, "CapEff:\t", &cap_effective);
5605- render_cap_t(m, "CapBnd:\t", &cap_bset);
cc23e853 5606- render_cap_t(m, "CapAmb:\t", &cap_ambient);
ec22aa5c
AM
5607+ /* FIXME: maybe move the p->vx_info masking to __task_cred() ? */
5608+ render_cap_t(m, "CapInh:\t", p->vx_info, &cap_inheritable);
5609+ render_cap_t(m, "CapPrm:\t", p->vx_info, &cap_permitted);
5610+ render_cap_t(m, "CapEff:\t", p->vx_info, &cap_effective);
5611+ render_cap_t(m, "CapBnd:\t", p->vx_info, &cap_bset);
cc23e853 5612+ render_cap_t(m, "CapAmb:\t", p->vx_info, &cap_ambient);
d337f35e
JR
5613 }
5614
b00e13aa 5615 static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
cc23e853
AM
5616@@ -365,6 +371,43 @@ static void task_cpus_allowed(struct seq
5617 cpumask_pr_args(&task->cpus_allowed));
2380c486
JR
5618 }
5619
5620+int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
5621+ struct pid *pid, struct task_struct *task)
5622+{
5623+ seq_printf(m, "Proxy:\t%p(%c)\n"
5624+ "Count:\t%u\n"
5625+ "uts:\t%p(%c)\n"
5626+ "ipc:\t%p(%c)\n"
5627+ "mnt:\t%p(%c)\n"
5628+ "pid:\t%p(%c)\n"
5629+ "net:\t%p(%c)\n",
5630+ task->nsproxy,
5631+ (task->nsproxy == init_task.nsproxy ? 'I' : '-'),
5632+ atomic_read(&task->nsproxy->count),
5633+ task->nsproxy->uts_ns,
5634+ (task->nsproxy->uts_ns == init_task.nsproxy->uts_ns ? 'I' : '-'),
5635+ task->nsproxy->ipc_ns,
5636+ (task->nsproxy->ipc_ns == init_task.nsproxy->ipc_ns ? 'I' : '-'),
5637+ task->nsproxy->mnt_ns,
5638+ (task->nsproxy->mnt_ns == init_task.nsproxy->mnt_ns ? 'I' : '-'),
c2e5f7c8
JR
5639+ task->nsproxy->pid_ns_for_children,
5640+ (task->nsproxy->pid_ns_for_children ==
5641+ init_task.nsproxy->pid_ns_for_children ? 'I' : '-'),
2380c486
JR
5642+ task->nsproxy->net_ns,
5643+ (task->nsproxy->net_ns == init_task.nsproxy->net_ns ? 'I' : '-'));
5644+ return 0;
5645+}
d337f35e 5646+
2380c486
JR
5647+void task_vs_id(struct seq_file *m, struct task_struct *task)
5648+{
d337f35e 5649+ if (task_vx_flags(task, VXF_HIDE_VINFO, 0))
2380c486
JR
5650+ return;
5651+
bb20add7
AM
5652+ seq_printf(m, "VxID:\t%d\n", vx_task_xid(task));
5653+ seq_printf(m, "NxID:\t%d\n", nx_task_nid(task));
2380c486
JR
5654+}
5655+
5656+
5657 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
5658 struct pid *pid, struct task_struct *task)
5659 {
cc23e853 5660@@ -382,6 +425,7 @@ int proc_pid_status(struct seq_file *m,
b00e13aa 5661 task_seccomp(m, task);
2bf5ad28 5662 task_cpus_allowed(m, task);
2380c486
JR
5663 cpuset_task_status_allowed(m, task);
5664+ task_vs_id(m, task);
152aeb71
JR
5665 task_context_switch_counts(m, task);
5666 return 0;
5667 }
369dbd59 5668@@ -497,6 +541,17 @@ static int do_task_stat(struct seq_file
d337f35e 5669 /* convert nsec -> ticks */
bb20add7 5670 start_time = nsec_to_clock_t(task->real_start_time);
d337f35e
JR
5671
5672+ /* fixup start time for virt uptime */
5673+ if (vx_flags(VXF_VIRT_UPTIME, 0)) {
5674+ unsigned long long bias =
5675+ current->vx_info->cvirt.bias_clock;
5676+
5677+ if (start_time > bias)
5678+ start_time -= bias;
5679+ else
5680+ start_time = 0;
5681+ }
5682+
1e8b8f9b 5683 seq_printf(m, "%d (%s) %c", pid_nr_ns(pid, ns), tcomm, state);
cc23e853
AM
5684 seq_put_decimal_ll(m, " ", ppid);
5685 seq_put_decimal_ll(m, " ", pgid);
cef7ea10
AM
5686diff -NurpP --minimal linux-4.9.82/fs/proc/base.c linux-4.9.82-vs2.3.9.7/fs/proc/base.c
5687--- linux-4.9.82/fs/proc/base.c 2018-02-22 21:18:51.000000000 +0000
5688+++ linux-4.9.82-vs2.3.9.7/fs/proc/base.c 2018-01-13 01:59:11.000000000 +0000
09be7631 5689@@ -87,6 +87,8 @@
78865d5b 5690 #include <linux/slab.h>
db55b927 5691 #include <linux/flex_array.h>
09be7631 5692 #include <linux/posix-timers.h>
d337f35e
JR
5693+#include <linux/vs_context.h>
5694+#include <linux/vs_network.h>
763640ca
JR
5695 #ifdef CONFIG_HARDWALL
5696 #include <asm/hardwall.h>
5697 #endif
cc23e853
AM
5698@@ -1063,10 +1065,15 @@ static int __set_oom_adj(struct file *fi
5699 mutex_lock(&oom_adj_mutex);
5700 if (legacy) {
5701 if (oom_adj < task->signal->oom_score_adj &&
5702- !capable(CAP_SYS_RESOURCE)) {
5703+ !vx_capable(CAP_SYS_RESOURCE, VXC_OOM_ADJUST)) {
5704 err = -EACCES;
5705 goto err_unlock;
5706 }
7e46296a 5707+
cc23e853
AM
5708+ /* prevent guest processes from circumventing the oom killer */
5709+ if (vx_current_xid() && (oom_adj == OOM_DISABLE))
5710+ oom_adj = OOM_ADJUST_MIN;
5711+
5712 /*
5713 * /proc/pid/oom_adj is provided for legacy purposes, ask users to use
5714 * /proc/pid/oom_score_adj instead.
5715@@ -1696,6 +1703,8 @@ struct inode *proc_pid_make_inode(struct
ec22aa5c
AM
5716 inode->i_gid = cred->egid;
5717 rcu_read_unlock();
d337f35e
JR
5718 }
5719+ /* procfs is xid tagged */
61333608 5720+ i_tag_write(inode, (vtag_t)vx_task_xid(task));
d337f35e
JR
5721 security_task_to_inode(task, inode);
5722
5723 out:
cc23e853 5724@@ -1741,6 +1750,8 @@ int pid_getattr(struct vfsmount *mnt, st
d33d7b00
AM
5725
5726 /* dentry stuff */
5727
bb20add7 5728+// static unsigned name_to_int(struct dentry *dentry);
d33d7b00
AM
5729+
5730 /*
5731 * Exceptional case: normally we are not allowed to unhash a busy
5732 * directory. In this case, however, we can do it - no aliasing problems
cc23e853 5733@@ -1769,6 +1780,19 @@ int pid_revalidate(struct dentry *dentry
d33d7b00
AM
5734 task = get_proc_task(inode);
5735
5736 if (task) {
bb20add7
AM
5737+ unsigned pid = name_to_int(&dentry->d_name);
5738+
5739+ if (pid != ~0U && pid != vx_map_pid(task->pid) &&
5740+ pid != __task_pid_nr_ns(task, PIDTYPE_PID,
5741+ task_active_pid_ns(task))) {
5742+ vxdprintk(VXD_CBIT(misc, 10),
5743+ VS_Q("%*s") " dropped by pid_revalidate(%d!=%d)",
5744+ dentry->d_name.len, dentry->d_name.name,
5745+ pid, vx_map_pid(task->pid));
d33d7b00 5746+ put_task_struct(task);
bb20add7
AM
5747+ d_drop(dentry);
5748+ return 0;
d33d7b00
AM
5749+ }
5750 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
5751 task_dumpable(task)) {
5752 rcu_read_lock();
cc23e853 5753@@ -2408,6 +2432,13 @@ static struct dentry *proc_pident_lookup
d337f35e
JR
5754 if (!task)
5755 goto out_no_task;
5756
2380c486 5757+ /* TODO: maybe we can come up with a generic approach? */
d337f35e
JR
5758+ if (task_vx_flags(task, VXF_HIDE_VINFO, 0) &&
5759+ (dentry->d_name.len == 5) &&
5760+ (!memcmp(dentry->d_name.name, "vinfo", 5) ||
5761+ !memcmp(dentry->d_name.name, "ninfo", 5)))
5762+ goto out;
5763+
5764 /*
5765 * Yes, it does not scale. And it should not. Don't add
5766 * new entries into /proc/<tgid>/ without very good reasons.
cc23e853 5767@@ -2847,6 +2878,11 @@ static int proc_pid_personality(struct s
2380c486
JR
5768 static const struct file_operations proc_task_operations;
5769 static const struct inode_operations proc_task_inode_operations;
d337f35e 5770
bb20add7
AM
5771+extern int proc_pid_vx_info(struct seq_file *,
5772+ struct pid_namespace *, struct pid *, struct task_struct *);
5773+extern int proc_pid_nx_info(struct seq_file *,
5774+ struct pid_namespace *, struct pid *, struct task_struct *);
d337f35e 5775+
2380c486 5776 static const struct pid_entry tgid_base_stuff[] = {
ec22aa5c
AM
5777 DIR("task", S_IRUGO|S_IXUGO, proc_task_inode_operations, proc_task_operations),
5778 DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
cc23e853 5779@@ -2911,6 +2947,8 @@ static const struct pid_entry tgid_base_
2380c486 5780 #ifdef CONFIG_CGROUPS
bb20add7 5781 ONE("cgroup", S_IRUGO, proc_cgroup_show),
d337f35e 5782 #endif
bb20add7
AM
5783+ ONE("vinfo", S_IRUGO, proc_pid_vx_info),
5784+ ONE("ninfo", S_IRUGO, proc_pid_nx_info),
5785 ONE("oom_score", S_IRUGO, proc_oom_score),
537831f9 5786 REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
93de0823 5787 REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
cc23e853 5788@@ -3126,7 +3164,7 @@ retry:
2380c486
JR
5789 iter.task = NULL;
5790 pid = find_ge_pid(iter.tgid, ns);
5791 if (pid) {
5792- iter.tgid = pid_nr_ns(pid, ns);
5793+ iter.tgid = pid_unmapped_nr_ns(pid, ns);
5794 iter.task = pid_task(pid, PIDTYPE_PID);
5795 /* What we to know is if the pid we have find is the
5796 * pid of a thread_group_leader. Testing for task
cc23e853 5797@@ -3186,8 +3224,10 @@ int proc_pid_readdir(struct file *file,
c2e5f7c8
JR
5798 if (!has_pid_permissions(ns, iter.task, 2))
5799 continue;
db55b927 5800
c2e5f7c8
JR
5801- len = snprintf(name, sizeof(name), "%d", iter.tgid);
5802+ len = snprintf(name, sizeof(name), "%d", vx_map_tgid(iter.tgid));
5803 ctx->pos = iter.tgid + TGID_OFFSET;
2380c486 5804+ if (!vx_proc_task_visible(iter.task))
d337f35e 5805+ continue;
c2e5f7c8
JR
5806 if (!proc_fill_cache(file, ctx, name, len,
5807 proc_pid_instantiate, iter.task, NULL)) {
2380c486 5808 put_task_struct(iter.task);
cc23e853 5809@@ -3324,6 +3364,7 @@ static const struct pid_entry tid_base_s
09be7631 5810 REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
bb20add7 5811 REG("setgroups", S_IRUGO|S_IWUSR, proc_setgroups_operations),
09be7631
JR
5812 #endif
5813+ ONE("nsproxy", S_IRUGO, proc_pid_nsproxy),
5814 };
5815
c2e5f7c8 5816 static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx)
cc23e853 5817@@ -3390,6 +3431,8 @@ static struct dentry *proc_task_lookup(s
bb20add7 5818 tid = name_to_int(&dentry->d_name);
d337f35e
JR
5819 if (tid == ~0U)
5820 goto out;
5821+ if (vx_current_initpid(tid))
5822+ goto out;
5823
2380c486 5824 ns = dentry->d_sb->s_fs_info;
d337f35e 5825 rcu_read_lock();
cef7ea10
AM
5826diff -NurpP --minimal linux-4.9.82/fs/proc/generic.c linux-4.9.82-vs2.3.9.7/fs/proc/generic.c
5827--- linux-4.9.82/fs/proc/generic.c 2018-02-22 21:18:51.000000000 +0000
5828+++ linux-4.9.82-vs2.3.9.7/fs/proc/generic.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 5829@@ -22,6 +22,7 @@
d337f35e
JR
5830 #include <linux/bitops.h>
5831 #include <linux/spinlock.h>
2380c486 5832 #include <linux/completion.h>
d337f35e
JR
5833+#include <linux/vserver/inode.h>
5834 #include <asm/uaccess.h>
5835
5836 #include "internal.h"
cc23e853
AM
5837@@ -66,8 +67,16 @@ static struct proc_dir_entry *pde_subdir
5838 node = node->rb_left;
5839 else if (result > 0)
5840 node = node->rb_right;
5841- else
5842+ else {
5843+ if (!vx_hide_check(0, de->vx_flags)) {
5844+ vxdprintk(VXD_CBIT(misc, 9),
5845+ VS_Q("%*s")
5846+ " hidden in pde_subdir_find()",
5847+ de->namelen, de->name);
5848+ return 0;
5849+ }
5850 return de;
bb20add7 5851+ }
cc23e853
AM
5852 }
5853 return NULL;
5854 }
5855@@ -241,6 +250,8 @@ struct dentry *proc_lookup_de(struct pro
5856 return ERR_PTR(-ENOMEM);
5857 d_set_d_op(dentry, &simple_dentry_operations);
5858 d_add(dentry, inode);
ba86f833 5859+ /* generic proc entries belong to the host */
537831f9 5860+ i_tag_write(inode, 0);
cc23e853 5861 return NULL;
2380c486 5862 }
cc23e853
AM
5863 read_unlock(&proc_subdir_lock);
5864@@ -287,6 +298,12 @@ int proc_readdir_de(struct proc_dir_entr
c2e5f7c8
JR
5865 do {
5866 struct proc_dir_entry *next;
5867 pde_get(de);
bb20add7
AM
5868+ if (!vx_hide_check(0, de->vx_flags)) {
5869+ vxdprintk(VXD_CBIT(misc, 9),
5870+ VS_Q("%*s") " hidden in proc_readdir_de()",
5871+ de->namelen, de->name);
c2e5f7c8 5872+ goto skip;
bb20add7 5873+ }
cc23e853 5874 read_unlock(&proc_subdir_lock);
c2e5f7c8
JR
5875 if (!dir_emit(ctx, de->name, de->namelen,
5876 de->low_ino, de->mode >> 12)) {
cc23e853 5877@@ -294,6 +311,7 @@ int proc_readdir_de(struct proc_dir_entr
c2e5f7c8
JR
5878 return 0;
5879 }
cc23e853 5880 read_lock(&proc_subdir_lock);
c2e5f7c8
JR
5881+ skip:
5882 ctx->pos++;
cc23e853 5883 next = pde_subdir_next(de);
c2e5f7c8 5884 pde_put(de);
cc23e853 5885@@ -387,6 +405,7 @@ static struct proc_dir_entry *__proc_cre
537831f9 5886 ent->mode = mode;
d337f35e 5887 ent->nlink = nlink;
cc23e853 5888 ent->subdir = RB_ROOT;
d337f35e 5889+ ent->vx_flags = IATTR_PROC_DEFAULT;
537831f9 5890 atomic_set(&ent->count, 1);
2380c486 5891 spin_lock_init(&ent->pde_unload_lock);
2380c486 5892 INIT_LIST_HEAD(&ent->pde_openers);
cc23e853 5893@@ -413,7 +432,8 @@ struct proc_dir_entry *proc_symlink(cons
d337f35e
JR
5894 kfree(ent->data);
5895 kfree(ent);
5896 ent = NULL;
5897- }
5898+ } else
5899+ ent->vx_flags = IATTR_PROC_SYMLINK;
5900 } else {
5901 kfree(ent);
5902 ent = NULL;
cef7ea10
AM
5903diff -NurpP --minimal linux-4.9.82/fs/proc/inode.c linux-4.9.82-vs2.3.9.7/fs/proc/inode.c
5904--- linux-4.9.82/fs/proc/inode.c 2016-12-11 19:17:54.000000000 +0000
5905+++ linux-4.9.82-vs2.3.9.7/fs/proc/inode.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 5906@@ -432,6 +432,8 @@ struct inode *proc_get_inode(struct supe
d337f35e
JR
5907 inode->i_uid = de->uid;
5908 inode->i_gid = de->gid;
5909 }
5910+ if (de->vx_flags)
5911+ PROC_I(inode)->vx_flags = de->vx_flags;
5912 if (de->size)
5913 inode->i_size = de->size;
5914 if (de->nlink)
cef7ea10
AM
5915diff -NurpP --minimal linux-4.9.82/fs/proc/internal.h linux-4.9.82-vs2.3.9.7/fs/proc/internal.h
5916--- linux-4.9.82/fs/proc/internal.h 2016-12-11 19:17:54.000000000 +0000
5917+++ linux-4.9.82-vs2.3.9.7/fs/proc/internal.h 2018-01-13 01:48:13.000000000 +0000
09be7631
JR
5918@@ -14,6 +14,7 @@
5919 #include <linux/spinlock.h>
5920 #include <linux/atomic.h>
b00e13aa 5921 #include <linux/binfmts.h>
d337f35e
JR
5922+#include <linux/vs_pid.h>
5923
09be7631
JR
5924 struct ctl_table_header;
5925 struct mempolicy;
cc23e853 5926@@ -34,6 +35,7 @@ struct proc_dir_entry {
09be7631
JR
5927 nlink_t nlink;
5928 kuid_t uid;
5929 kgid_t gid;
5930+ int vx_flags;
5931 loff_t size;
5932 const struct inode_operations *proc_iops;
5933 const struct file_operations *proc_fops;
cc23e853 5934@@ -51,15 +53,22 @@ struct proc_dir_entry {
09be7631
JR
5935 char name[];
5936 };
5937
5938+struct vx_info;
5939+struct nx_info;
2380c486 5940+
09be7631
JR
5941 union proc_op {
5942 int (*proc_get_link)(struct dentry *, struct path *);
09be7631
JR
5943 int (*proc_show)(struct seq_file *m,
5944 struct pid_namespace *ns, struct pid *pid,
5945 struct task_struct *task);
5946+ int (*proc_vs_read)(char *page);
5947+ int (*proc_vxi_read)(struct vx_info *vxi, char *page);
5948+ int (*proc_nxi_read)(struct nx_info *nxi, char *page);
5949 };
2380c486 5950
09be7631
JR
5951 struct proc_inode {
5952 struct pid *pid;
5953+ int vx_flags;
cc23e853 5954 unsigned int fd;
09be7631
JR
5955 union proc_op op;
5956 struct proc_dir_entry *pde;
cc23e853 5957@@ -92,11 +101,16 @@ static inline struct pid *proc_pid(struc
d337f35e
JR
5958 return PROC_I(inode)->pid;
5959 }
5960
5961-static inline struct task_struct *get_proc_task(struct inode *inode)
5962+static inline struct task_struct *get_proc_task_real(struct inode *inode)
5963 {
5964 return get_pid_task(proc_pid(inode), PIDTYPE_PID);
5965 }
5966
5967+static inline struct task_struct *get_proc_task(struct inode *inode)
5968+{
5969+ return vx_get_proc_task(inode, proc_pid(inode));
5970+}
5971+
09be7631 5972 static inline int task_dumpable(struct task_struct *task)
d337f35e 5973 {
09be7631 5974 int dumpable = 0;
cc23e853 5975@@ -155,6 +169,8 @@ extern int proc_pid_status(struct seq_fi
09be7631
JR
5976 struct pid *, struct task_struct *);
5977 extern int proc_pid_statm(struct seq_file *, struct pid_namespace *,
5978 struct pid *, struct task_struct *);
5979+extern int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
5980+ struct pid *pid, struct task_struct *task);
5981
5982 /*
5983 * base.c
cef7ea10
AM
5984diff -NurpP --minimal linux-4.9.82/fs/proc/loadavg.c linux-4.9.82-vs2.3.9.7/fs/proc/loadavg.c
5985--- linux-4.9.82/fs/proc/loadavg.c 2016-12-11 19:17:54.000000000 +0000
5986+++ linux-4.9.82-vs2.3.9.7/fs/proc/loadavg.c 2018-01-10 02:50:49.000000000 +0000
ec22aa5c 5987@@ -12,15 +12,27 @@
1bc743c0 5988
ec22aa5c 5989 static int loadavg_proc_show(struct seq_file *m, void *v)
1bc743c0
JR
5990 {
5991+ unsigned long running;
5992+ unsigned int threads;
ec22aa5c 5993 unsigned long avnrun[3];
1bc743c0 5994
ec22aa5c 5995 get_avenrun(avnrun, FIXED_1/200, 0);
bd427b06 5996
ec22aa5c 5997+ if (vx_flags(VXF_VIRT_LOAD, 0)) {
eab5a9a6 5998+ struct vx_info *vxi = current_vx_info();
ec22aa5c
AM
5999+
6000+ running = atomic_read(&vxi->cvirt.nr_running);
6001+ threads = atomic_read(&vxi->cvirt.nr_threads);
6002+ } else {
6003+ running = nr_running();
6004+ threads = nr_threads;
6005+ }
6006+
6007 seq_printf(m, "%lu.%02lu %lu.%02lu %lu.%02lu %ld/%d %d\n",
6008 LOAD_INT(avnrun[0]), LOAD_FRAC(avnrun[0]),
6009 LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]),
6010 LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]),
1bc743c0
JR
6011- nr_running(), nr_threads,
6012+ running, threads,
6013 task_active_pid_ns(current)->last_pid);
ec22aa5c 6014 return 0;
1bc743c0 6015 }
cef7ea10
AM
6016diff -NurpP --minimal linux-4.9.82/fs/proc/meminfo.c linux-4.9.82-vs2.3.9.7/fs/proc/meminfo.c
6017--- linux-4.9.82/fs/proc/meminfo.c 2016-12-11 19:17:54.000000000 +0000
6018+++ linux-4.9.82-vs2.3.9.7/fs/proc/meminfo.c 2018-01-13 01:55:40.000000000 +0000
cc23e853 6019@@ -55,7 +55,8 @@ static int meminfo_proc_show(struct seq_
c2e5f7c8
JR
6020 si_swapinfo(&i);
6021 committed = percpu_counter_read_positive(&vm_committed_as);
e3afe727 6022
cc23e853 6023- cached = global_node_page_state(NR_FILE_PAGES) -
e3afe727 6024+ cached = vx_flags(VXF_VIRT_MEM, 0) ?
cc23e853 6025+ vx_vsi_cached(&i) : global_node_page_state(NR_FILE_PAGES) -
b00e13aa 6026 total_swapcache_pages() - i.bufferram;
e3afe727 6027 if (cached < 0)
d337f35e 6028 cached = 0;
cef7ea10
AM
6029diff -NurpP --minimal linux-4.9.82/fs/proc/root.c linux-4.9.82-vs2.3.9.7/fs/proc/root.c
6030--- linux-4.9.82/fs/proc/root.c 2016-12-11 19:17:54.000000000 +0000
6031+++ linux-4.9.82-vs2.3.9.7/fs/proc/root.c 2018-01-13 01:48:57.000000000 +0000
b00e13aa 6032@@ -20,9 +20,14 @@
2380c486
JR
6033 #include <linux/mount.h>
6034 #include <linux/pid_namespace.h>
db55b927 6035 #include <linux/parser.h>
2380c486 6036+#include <linux/vserver/inode.h>
d337f35e 6037
2380c486 6038 #include "internal.h"
d337f35e 6039
d337f35e
JR
6040+struct proc_dir_entry *proc_virtual;
6041+
6042+extern void proc_vx_init(void);
2380c486 6043+
cc23e853
AM
6044 enum {
6045 Opt_gid, Opt_hidepid, Opt_err,
6046 };
6047@@ -145,6 +150,7 @@ void __init proc_root_init(void)
bb20add7 6048 proc_tty_init();
2380c486
JR
6049 proc_mkdir("bus", NULL);
6050 proc_sys_init();
d337f35e
JR
6051+ proc_vx_init();
6052 }
6053
6054 static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
cc23e853 6055@@ -206,6 +212,7 @@ struct proc_dir_entry proc_root = {
2380c486
JR
6056 .proc_iops = &proc_root_inode_operations,
6057 .proc_fops = &proc_root_operations,
6058 .parent = &proc_root,
6059+ .vx_flags = IATTR_ADMIN | IATTR_WATCH,
cc23e853 6060 .subdir = RB_ROOT,
a168f21d 6061 .name = "/proc",
2380c486 6062 };
cef7ea10
AM
6063diff -NurpP --minimal linux-4.9.82/fs/proc/self.c linux-4.9.82-vs2.3.9.7/fs/proc/self.c
6064--- linux-4.9.82/fs/proc/self.c 2016-12-11 19:17:54.000000000 +0000
6065+++ linux-4.9.82-vs2.3.9.7/fs/proc/self.c 2018-01-10 02:50:49.000000000 +0000
cc23e853
AM
6066@@ -1,6 +1,7 @@
6067 #include <linux/sched.h>
09be7631
JR
6068 #include <linux/slab.h>
6069 #include <linux/pid_namespace.h>
b00e13aa 6070+#include <linux/vserver/inode.h>
09be7631 6071 #include "internal.h"
b00e13aa
AM
6072
6073 /*
c2e5f7c8 6074@@ -54,6 +55,8 @@ int proc_setup_self(struct super_block *
09be7631
JR
6075 self = d_alloc_name(s->s_root, "self");
6076 if (self) {
6077 struct inode *inode = new_inode_pseudo(s);
6078+
6079+ // self->vx_flags = IATTR_PROC_SYMLINK;
6080 if (inode) {
6081 inode->i_ino = self_inum;
cc23e853 6082 inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
cef7ea10
AM
6083diff -NurpP --minimal linux-4.9.82/fs/proc/stat.c linux-4.9.82-vs2.3.9.7/fs/proc/stat.c
6084--- linux-4.9.82/fs/proc/stat.c 2016-12-11 19:17:54.000000000 +0000
6085+++ linux-4.9.82-vs2.3.9.7/fs/proc/stat.c 2018-01-16 00:55:05.000000000 +0000
537831f9 6086@@ -9,8 +9,10 @@
1e8b8f9b
AM
6087 #include <linux/slab.h>
6088 #include <linux/time.h>
6089 #include <linux/irqnr.h>
6090+#include <linux/vserver/cvirt.h>
265de2f7 6091 #include <linux/cputime.h>
1e8b8f9b 6092 #include <linux/tick.h>
537831f9
AM
6093+#include <linux/cpuset.h>
6094
6095 #ifndef arch_irq_stat_cpu
6096 #define arch_irq_stat_cpu(cpu) 0
cc23e853 6097@@ -86,13 +88,24 @@ static int show_stat(struct seq_file *p,
537831f9
AM
6098 u64 sum_softirq = 0;
6099 unsigned int per_softirq_sums[NR_SOFTIRQS] = {0};
cc23e853 6100 struct timespec64 boottime;
537831f9
AM
6101+ cpumask_var_t cpus_allowed;
6102+ bool virt_cpu = vx_flags(VXF_VIRT_CPU, 0);
6103
6104 user = nice = system = idle = iowait =
1e8b8f9b
AM
6105 irq = softirq = steal = 0;
6106 guest = guest_nice = 0;
cc23e853
AM
6107 getboottime64(&boottime);
6108
1e8b8f9b 6109+ if (vx_flags(VXF_VIRT_UPTIME, 0))
369dbd59 6110+ vx_vsi_boottime64(&boottime);
537831f9
AM
6111+
6112+ if (virt_cpu)
6113+ cpuset_cpus_allowed(current, cpus_allowed);
1e8b8f9b 6114+
1e8b8f9b 6115 for_each_possible_cpu(i) {
537831f9
AM
6116+ if (virt_cpu && !cpumask_test_cpu(i, cpus_allowed))
6117+ continue;
6118+
6119 user += kcpustat_cpu(i).cpustat[CPUTIME_USER];
6120 nice += kcpustat_cpu(i).cpustat[CPUTIME_NICE];
6121 system += kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
cc23e853 6122@@ -128,6 +141,9 @@ static int show_stat(struct seq_file *p,
537831f9
AM
6123 seq_putc(p, '\n');
6124
6125 for_each_online_cpu(i) {
6126+ if (virt_cpu && !cpumask_test_cpu(i, cpus_allowed))
6127+ continue;
6128+
6129 /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
6130 user = kcpustat_cpu(i).cpustat[CPUTIME_USER];
6131 nice = kcpustat_cpu(i).cpustat[CPUTIME_NICE];
cef7ea10
AM
6132diff -NurpP --minimal linux-4.9.82/fs/proc/uptime.c linux-4.9.82-vs2.3.9.7/fs/proc/uptime.c
6133--- linux-4.9.82/fs/proc/uptime.c 2016-12-11 19:17:54.000000000 +0000
6134+++ linux-4.9.82-vs2.3.9.7/fs/proc/uptime.c 2018-01-16 00:56:48.000000000 +0000
f6c5ef8b 6135@@ -5,6 +5,7 @@
ec22aa5c
AM
6136 #include <linux/seq_file.h>
6137 #include <linux/time.h>
f6c5ef8b 6138 #include <linux/kernel_stat.h>
ec22aa5c 6139+#include <linux/vserver/cvirt.h>
265de2f7 6140 #include <linux/cputime.h>
ec22aa5c
AM
6141
6142 static int uptime_proc_show(struct seq_file *m, void *v)
c2e5f7c8 6143@@ -24,6 +25,10 @@ static int uptime_proc_show(struct seq_f
f6c5ef8b
AM
6144 nsec = cputime64_to_jiffies64(idletime) * TICK_NSEC;
6145 idle.tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
6146 idle.tv_nsec = rem;
ec22aa5c
AM
6147+
6148+ if (vx_flags(VXF_VIRT_UPTIME, 0))
6149+ vx_vsi_uptime(&uptime, &idle);
6150+
6151 seq_printf(m, "%lu.%02lu %lu.%02lu\n",
6152 (unsigned long) uptime.tv_sec,
6153 (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
cef7ea10
AM
6154diff -NurpP --minimal linux-4.9.82/fs/proc_namespace.c linux-4.9.82-vs2.3.9.7/fs/proc_namespace.c
6155--- linux-4.9.82/fs/proc_namespace.c 2016-12-11 19:17:54.000000000 +0000
6156+++ linux-4.9.82-vs2.3.9.7/fs/proc_namespace.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 6157@@ -46,6 +46,8 @@ static int show_sb_opts(struct seq_file
db55b927
AM
6158 { MS_DIRSYNC, ",dirsync" },
6159 { MS_MANDLOCK, ",mand" },
cc23e853 6160 { MS_LAZYTIME, ",lazytime" },
db55b927
AM
6161+ { MS_TAGGED, ",tag" },
6162+ { MS_NOTAGCHECK, ",notagcheck" },
6163 { 0, NULL }
6164 };
6165 const struct proc_fs_info *fs_infop;
cc23e853 6166@@ -82,6 +84,38 @@ static inline void mangle(struct seq_fil
db55b927
AM
6167 seq_escape(m, s, " \t\n\\");
6168 }
6169
61b0c03f
JR
6170+#ifdef CONFIG_VSERVER_EXTRA_MNT_CHECK
6171+
db55b927
AM
6172+static int mnt_is_reachable(struct vfsmount *vfsmnt)
6173+{
6174+ struct path root;
6175+ struct dentry *point;
6176+ struct mount *mnt = real_mount(vfsmnt);
6177+ struct mount *root_mnt;
6178+ int ret;
6179+
6180+ if (mnt == mnt->mnt_ns->root)
6181+ return 1;
6182+
98d9a5b1 6183+ rcu_read_lock();
db55b927
AM
6184+ root = current->fs->root;
6185+ root_mnt = real_mount(root.mnt);
6186+ point = root.dentry;
6187+
6188+ while ((mnt != mnt->mnt_parent) && (mnt != root_mnt)) {
6189+ point = mnt->mnt_mountpoint;
6190+ mnt = mnt->mnt_parent;
6191+ }
98d9a5b1 6192+ rcu_read_unlock();
db55b927
AM
6193+
6194+ ret = (mnt == root_mnt) && is_subdir(point, root.dentry);
db55b927
AM
6195+ return ret;
6196+}
61b0c03f
JR
6197+
6198+#else
6199+#define mnt_is_reachable(v) (1)
6200+#endif
db55b927
AM
6201+
6202 static void show_type(struct seq_file *m, struct super_block *sb)
6203 {
6204 mangle(m, sb->s_type->name);
cc23e853 6205@@ -99,6 +133,17 @@ static int show_vfsmnt(struct seq_file *
db55b927 6206 struct super_block *sb = mnt_path.dentry->d_sb;
cc23e853 6207 int err;
db55b927
AM
6208
6209+ if (vx_flags(VXF_HIDE_MOUNT, 0))
6210+ return SEQ_SKIP;
6211+ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6212+ return SEQ_SKIP;
6213+
6214+ if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
6215+ mnt == current->fs->root.mnt) {
6216+ seq_puts(m, "/dev/root / ");
6217+ goto type;
6218+ }
6219+
6220 if (sb->s_op->show_devname) {
6221 err = sb->s_op->show_devname(m, mnt_path.dentry);
6222 if (err)
cc23e853
AM
6223@@ -112,6 +157,7 @@ static int show_vfsmnt(struct seq_file *
6224 if (err)
6225 goto out;
db55b927
AM
6226 seq_putc(m, ' ');
6227+type:
6228 show_type(m, sb);
6229 seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw");
6230 err = show_sb_opts(m, sb);
cc23e853
AM
6231@@ -133,6 +179,11 @@ static int show_mountinfo(struct seq_fil
6232 struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
6233 int err;
db55b927
AM
6234
6235+ if (vx_flags(VXF_HIDE_MOUNT, 0))
6236+ return SEQ_SKIP;
6237+ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6238+ return SEQ_SKIP;
6239+
6240 seq_printf(m, "%i %i %u:%u ", r->mnt_id, r->mnt_parent->mnt_id,
6241 MAJOR(sb->s_dev), MINOR(sb->s_dev));
cc23e853
AM
6242 if (sb->s_op->show_path) {
6243@@ -195,6 +246,17 @@ static int show_vfsstat(struct seq_file
db55b927 6244 struct super_block *sb = mnt_path.dentry->d_sb;
cc23e853 6245 int err;
db55b927
AM
6246
6247+ if (vx_flags(VXF_HIDE_MOUNT, 0))
6248+ return SEQ_SKIP;
6249+ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6250+ return SEQ_SKIP;
6251+
6252+ if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
6253+ mnt == current->fs->root.mnt) {
6254+ seq_puts(m, "device /dev/root mounted on / ");
6255+ goto type;
6256+ }
6257+
6258 /* device */
6259 if (sb->s_op->show_devname) {
6260 seq_puts(m, "device ");
cc23e853
AM
6261@@ -216,7 +278,7 @@ static int show_vfsstat(struct seq_file
6262 if (err)
6263 goto out;
db55b927
AM
6264 seq_putc(m, ' ');
6265-
6266+type:
6267 /* file system type */
6268 seq_puts(m, "with fstype ");
6269 show_type(m, sb);
cef7ea10
AM
6270diff -NurpP --minimal linux-4.9.82/fs/quota/dquot.c linux-4.9.82-vs2.3.9.7/fs/quota/dquot.c
6271--- linux-4.9.82/fs/quota/dquot.c 2018-02-22 21:18:51.000000000 +0000
6272+++ linux-4.9.82-vs2.3.9.7/fs/quota/dquot.c 2018-02-10 15:15:43.000000000 +0000
cc23e853 6273@@ -1658,6 +1658,9 @@ int __dquot_alloc_space(struct inode *in
76514441 6274 int reserve = flags & DQUOT_SPACE_RESERVE;
cc23e853 6275 struct dquot **dquots;
76514441
AM
6276
6277+ if ((ret = dl_alloc_space(inode, number)))
6278+ return ret;
6279+
bb20add7
AM
6280 if (!dquot_active(inode)) {
6281 inode_incr_space(inode, number, reserve);
6282 goto out;
cc23e853 6283@@ -1710,6 +1713,9 @@ int dquot_alloc_inode(struct inode *inod
1e8b8f9b 6284 struct dquot_warn warn[MAXQUOTAS];
cc23e853 6285 struct dquot * const *dquots;
76514441
AM
6286
6287+ if ((ret = dl_alloc_inode(inode)))
6288+ return ret;
6289+
93de0823 6290 if (!dquot_active(inode))
bb20add7
AM
6291 return 0;
6292 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
cc23e853
AM
6293@@ -1812,6 +1818,8 @@ void __dquot_free_space(struct inode *in
6294 struct dquot **dquots;
bb20add7 6295 int reserve = flags & DQUOT_SPACE_RESERVE, index;
76514441
AM
6296
6297+ dl_free_space(inode, number);
6298+
93de0823 6299 if (!dquot_active(inode)) {
bb20add7
AM
6300 inode_decr_space(inode, number, reserve);
6301 return;
cc23e853
AM
6302@@ -1856,6 +1864,8 @@ void dquot_free_inode(struct inode *inod
6303 struct dquot * const *dquots;
bb20add7 6304 int index;
76514441
AM
6305
6306+ dl_free_inode(inode);
6307+
93de0823 6308 if (!dquot_active(inode))
bb20add7
AM
6309 return;
6310
cef7ea10
AM
6311diff -NurpP --minimal linux-4.9.82/fs/quota/quota.c linux-4.9.82-vs2.3.9.7/fs/quota/quota.c
6312--- linux-4.9.82/fs/quota/quota.c 2016-12-11 19:17:54.000000000 +0000
6313+++ linux-4.9.82-vs2.3.9.7/fs/quota/quota.c 2018-01-10 02:50:49.000000000 +0000
78865d5b
AM
6314@@ -8,6 +8,7 @@
6315 #include <linux/fs.h>
6316 #include <linux/namei.h>
6317 #include <linux/slab.h>
d337f35e 6318+#include <linux/vs_context.h>
78865d5b 6319 #include <asm/current.h>
92598135 6320 #include <linux/uaccess.h>
78865d5b 6321 #include <linux/kernel.h>
c2e5f7c8 6322@@ -38,7 +39,7 @@ static int check_quotactl_permission(str
78865d5b
AM
6323 break;
6324 /*FALLTHROUGH*/
6325 default:
d337f35e
JR
6326- if (!capable(CAP_SYS_ADMIN))
6327+ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
6328 return -EPERM;
6329 }
6330
cc23e853 6331@@ -768,6 +769,46 @@ static int do_quotactl(struct super_bloc
b00e13aa
AM
6332
6333 #ifdef CONFIG_BLOCK
d337f35e 6334
d337f35e
JR
6335+#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
6336+
6337+#include <linux/vroot.h>
2380c486
JR
6338+#include <linux/major.h>
6339+#include <linux/module.h>
d337f35e 6340+#include <linux/kallsyms.h>
2380c486 6341+#include <linux/vserver/debug.h>
d337f35e
JR
6342+
6343+static vroot_grb_func *vroot_get_real_bdev = NULL;
6344+
763640ca 6345+static DEFINE_SPINLOCK(vroot_grb_lock);
d337f35e
JR
6346+
6347+int register_vroot_grb(vroot_grb_func *func) {
6348+ int ret = -EBUSY;
6349+
6350+ spin_lock(&vroot_grb_lock);
6351+ if (!vroot_get_real_bdev) {
6352+ vroot_get_real_bdev = func;
6353+ ret = 0;
6354+ }
6355+ spin_unlock(&vroot_grb_lock);
6356+ return ret;
6357+}
6358+EXPORT_SYMBOL(register_vroot_grb);
6359+
6360+int unregister_vroot_grb(vroot_grb_func *func) {
6361+ int ret = -EINVAL;
6362+
6363+ spin_lock(&vroot_grb_lock);
6364+ if (vroot_get_real_bdev) {
6365+ vroot_get_real_bdev = NULL;
6366+ ret = 0;
6367+ }
6368+ spin_unlock(&vroot_grb_lock);
6369+ return ret;
6370+}
6371+EXPORT_SYMBOL(unregister_vroot_grb);
6372+
6373+#endif
6374+
db55b927
AM
6375 /* Return 1 if 'cmd' will block on frozen filesystem */
6376 static int quotactl_cmd_write(int cmd)
6377 {
cc23e853 6378@@ -809,6 +850,22 @@ static struct super_block *quotactl_bloc
2380c486
JR
6379 putname(tmp);
6380 if (IS_ERR(bdev))
6381 return ERR_CAST(bdev);
6382+#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
6383+ if (bdev && bdev->bd_inode &&
537831f9 6384+ imajor(bdev->bd_inode) == VROOT_MAJOR) {
2380c486
JR
6385+ struct block_device *bdnew = (void *)-EINVAL;
6386+
6387+ if (vroot_get_real_bdev)
6388+ bdnew = vroot_get_real_bdev(bdev);
6389+ else
6390+ vxdprintk(VXD_CBIT(misc, 0),
6391+ "vroot_get_real_bdev not set");
6392+ bdput(bdev);
6393+ if (IS_ERR(bdnew))
6394+ return ERR_PTR(PTR_ERR(bdnew));
6395+ bdev = bdnew;
6396+ }
6397+#endif
db55b927
AM
6398 if (quotactl_cmd_write(cmd))
6399 sb = get_super_thawed(bdev);
6400 else
cef7ea10
AM
6401diff -NurpP --minimal linux-4.9.82/fs/stat.c linux-4.9.82-vs2.3.9.7/fs/stat.c
6402--- linux-4.9.82/fs/stat.c 2018-02-22 21:18:51.000000000 +0000
6403+++ linux-4.9.82-vs2.3.9.7/fs/stat.c 2018-01-10 02:50:49.000000000 +0000
2380c486 6404@@ -26,6 +26,7 @@ void generic_fillattr(struct inode *inod
d337f35e
JR
6405 stat->nlink = inode->i_nlink;
6406 stat->uid = inode->i_uid;
6407 stat->gid = inode->i_gid;
6408+ stat->tag = inode->i_tag;
6409 stat->rdev = inode->i_rdev;
a168f21d 6410 stat->size = i_size_read(inode);
d337f35e 6411 stat->atime = inode->i_atime;
cef7ea10
AM
6412diff -NurpP --minimal linux-4.9.82/fs/statfs.c linux-4.9.82-vs2.3.9.7/fs/statfs.c
6413--- linux-4.9.82/fs/statfs.c 2016-12-11 19:17:54.000000000 +0000
6414+++ linux-4.9.82-vs2.3.9.7/fs/statfs.c 2018-01-10 02:50:49.000000000 +0000
93de0823 6415@@ -7,6 +7,8 @@
76514441
AM
6416 #include <linux/statfs.h>
6417 #include <linux/security.h>
6418 #include <linux/uaccess.h>
6419+#include <linux/vs_base.h>
6420+#include <linux/vs_dlimit.h>
db55b927 6421 #include "internal.h"
76514441 6422
93de0823 6423 static int flags_by_mnt(int mnt_flags)
db55b927 6424@@ -60,6 +62,8 @@ static int statfs_by_dentry(struct dentr
93de0823
AM
6425 retval = dentry->d_sb->s_op->statfs(dentry, buf);
6426 if (retval == 0 && buf->f_frsize == 0)
6427 buf->f_frsize = buf->f_bsize;
6428+ if (!vx_check(0, VS_ADMIN|VS_WATCH))
6429+ vx_vsi_statfs(dentry->d_sb, buf);
76514441
AM
6430 return retval;
6431 }
93de0823 6432
cef7ea10
AM
6433diff -NurpP --minimal linux-4.9.82/fs/super.c linux-4.9.82-vs2.3.9.7/fs/super.c
6434--- linux-4.9.82/fs/super.c 2018-02-22 21:18:51.000000000 +0000
6435+++ linux-4.9.82-vs2.3.9.7/fs/super.c 2018-01-13 01:53:26.000000000 +0000
cc23e853 6436@@ -34,6 +34,8 @@
1e8b8f9b 6437 #include <linux/fsnotify.h>
92598135 6438 #include <linux/lockdep.h>
cc23e853 6439 #include <linux/user_namespace.h>
1e8b8f9b 6440+#include <linux/magic.h>
be261992
AM
6441+#include <linux/vs_context.h>
6442 #include "internal.h"
6443
6444
cc23e853
AM
6445@@ -981,7 +983,8 @@ struct dentry *mount_ns(struct file_syst
6446 /* Don't allow mounting unless the caller has CAP_SYS_ADMIN
6447 * over the namespace.
6448 */
6449- if (!(flags & MS_KERNMOUNT) && !ns_capable(user_ns, CAP_SYS_ADMIN))
6450+ if (!(flags & MS_KERNMOUNT) &&
6451+ !vx_ns_capable(user_ns, CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
6452 return ERR_PTR(-EPERM);
6453
6454 sb = sget_userns(fs_type, ns_test_super, ns_set_super, flags,
6455@@ -1191,6 +1194,13 @@ mount_fs(struct file_system_type *type,
6456 WARN_ON(!sb->s_bdi);
be261992
AM
6457 sb->s_flags |= MS_BORN;
6458
6459+ error = -EPERM;
6460+ if (!vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT) &&
6461+ !sb->s_bdev &&
6462+ (sb->s_magic != PROC_SUPER_MAGIC) &&
6463+ (sb->s_magic != DEVPTS_SUPER_MAGIC))
6464+ goto out_sb;
6465+
6466 error = security_sb_kern_mount(sb, flags, secdata);
6467 if (error)
6468 goto out_sb;
cef7ea10
AM
6469diff -NurpP --minimal linux-4.9.82/fs/utimes.c linux-4.9.82-vs2.3.9.7/fs/utimes.c
6470--- linux-4.9.82/fs/utimes.c 2016-12-11 19:17:54.000000000 +0000
6471+++ linux-4.9.82-vs2.3.9.7/fs/utimes.c 2018-01-10 02:50:49.000000000 +0000
2380c486
JR
6472@@ -8,6 +8,8 @@
6473 #include <linux/stat.h>
d337f35e 6474 #include <linux/utime.h>
2380c486 6475 #include <linux/syscalls.h>
d337f35e
JR
6476+#include <linux/mount.h>
6477+#include <linux/vs_cowbl.h>
6478 #include <asm/uaccess.h>
6479 #include <asm/unistd.h>
6480
c2e5f7c8 6481@@ -52,13 +54,19 @@ static int utimes_common(struct path *pa
76514441
AM
6482 {
6483 int error;
6484 struct iattr newattrs;
6485- struct inode *inode = path->dentry->d_inode;
c2e5f7c8 6486 struct inode *delegated_inode = NULL;
76514441 6487+ struct inode *inode;
b00e13aa
AM
6488+
6489+ error = cow_check_and_break(path);
6490+ if (error)
6491+ goto out;
76514441
AM
6492
6493 error = mnt_want_write(path->mnt);
6494 if (error)
6495 goto out;
6496
76514441
AM
6497+ inode = path->dentry->d_inode;
6498+
6499 if (times && times[0].tv_nsec == UTIME_NOW &&
6500 times[1].tv_nsec == UTIME_NOW)
6501 times = NULL;
cef7ea10
AM
6502diff -NurpP --minimal linux-4.9.82/fs/xattr.c linux-4.9.82-vs2.3.9.7/fs/xattr.c
6503--- linux-4.9.82/fs/xattr.c 2018-02-22 21:18:51.000000000 +0000
6504+++ linux-4.9.82-vs2.3.9.7/fs/xattr.c 2018-01-10 02:50:49.000000000 +0000
537831f9 6505@@ -21,6 +21,7 @@
d337f35e 6506 #include <linux/audit.h>
1e8b8f9b 6507 #include <linux/vmalloc.h>
537831f9 6508 #include <linux/posix_acl_xattr.h>
d337f35e 6509+#include <linux/mount.h>
d337f35e 6510
1e8b8f9b 6511 #include <asm/uaccess.h>
d337f35e 6512
cc23e853 6513@@ -112,7 +113,7 @@ xattr_permission(struct inode *inode, co
763640ca 6514 * The trusted.* namespace can only be accessed by privileged users.
e03b8c3c 6515 */
763640ca
JR
6516 if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
6517- if (!capable(CAP_SYS_ADMIN))
a168f21d
AM
6518+ if (!vx_capable(CAP_SYS_ADMIN, VXC_FS_TRUSTED))
6519 return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
6520 return 0;
6521 }
cef7ea10
AM
6522diff -NurpP --minimal linux-4.9.82/include/linux/capability.h linux-4.9.82-vs2.3.9.7/include/linux/capability.h
6523--- linux-4.9.82/include/linux/capability.h 2018-02-22 21:18:53.000000000 +0000
6524+++ linux-4.9.82-vs2.3.9.7/include/linux/capability.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 6525@@ -78,7 +78,8 @@ extern const kernel_cap_t __cap_init_eff
bb20add7
AM
6526 #else /* HAND-CODED capability initializers */
6527
6528 #define CAP_LAST_U32 ((_KERNEL_CAPABILITY_U32S) - 1)
6529-#define CAP_LAST_U32_VALID_MASK (CAP_TO_MASK(CAP_LAST_CAP + 1) -1)
6530+#define CAP_LAST_U32_VALID_MASK ((CAP_TO_MASK(CAP_LAST_CAP + 1) -1) \
6531+ | CAP_TO_MASK(CAP_CONTEXT))
6532
6533 # define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }})
6534 # define CAP_FULL_SET ((kernel_cap_t){{ ~0, CAP_LAST_U32_VALID_MASK }})
cef7ea10
AM
6535diff -NurpP --minimal linux-4.9.82/include/linux/cred.h linux-4.9.82-vs2.3.9.7/include/linux/cred.h
6536--- linux-4.9.82/include/linux/cred.h 2018-02-22 21:18:53.000000000 +0000
6537+++ linux-4.9.82-vs2.3.9.7/include/linux/cred.h 2018-01-13 21:30:31.000000000 +0000
cc23e853 6538@@ -152,6 +152,7 @@ extern void exit_creds(struct task_struc
1163e6ab
AM
6539 extern int copy_creds(struct task_struct *, unsigned long);
6540 extern const struct cred *get_task_cred(struct task_struct *);
6541 extern struct cred *cred_alloc_blank(void);
6542+extern struct cred *__prepare_creds(const struct cred *);
6543 extern struct cred *prepare_creds(void);
6544 extern struct cred *prepare_exec_creds(void);
6545 extern int commit_creds(struct cred *);
cc23e853
AM
6546@@ -212,6 +213,31 @@ static inline bool cap_ambient_invariant
6547 cred->cap_inheritable));
3bac966d 6548 }
3bac966d
AM
6549
6550+static inline void set_cred_subscribers(struct cred *cred, int n)
6551+{
6552+#ifdef CONFIG_DEBUG_CREDENTIALS
6553+ atomic_set(&cred->subscribers, n);
6554+#endif
6555+}
6556+
6557+static inline int read_cred_subscribers(const struct cred *cred)
6558+{
6559+#ifdef CONFIG_DEBUG_CREDENTIALS
6560+ return atomic_read(&cred->subscribers);
6561+#else
6562+ return 0;
6563+#endif
6564+}
6565+
6566+static inline void alter_cred_subscribers(const struct cred *_cred, int n)
6567+{
6568+#ifdef CONFIG_DEBUG_CREDENTIALS
6569+ struct cred *cred = (struct cred *) _cred;
6570+
6571+ atomic_add(n, &cred->subscribers);
6572+#endif
6573+}
6574+
6575 /**
6576 * get_new_cred - Get a reference on a new set of credentials
6577 * @cred: The new credentials to reference
cef7ea10
AM
6578diff -NurpP --minimal linux-4.9.82/include/linux/dcache.h linux-4.9.82-vs2.3.9.7/include/linux/dcache.h
6579--- linux-4.9.82/include/linux/dcache.h 2018-02-22 21:18:53.000000000 +0000
6580+++ linux-4.9.82-vs2.3.9.7/include/linux/dcache.h 2018-01-10 02:50:49.000000000 +0000
cc23e853
AM
6581@@ -307,8 +307,10 @@ extern char *dentry_path(struct dentry *
6582 */
6583 static inline struct dentry *dget_dlock(struct dentry *dentry)
6584 {
6585- if (dentry)
6586+ if (dentry) {
6587 dentry->d_lockref.count++;
6588+ // vx_dentry_inc(dentry);
6589+ }
6590 return dentry;
6591 }
6592
cef7ea10
AM
6593diff -NurpP --minimal linux-4.9.82/include/linux/devpts_fs.h linux-4.9.82-vs2.3.9.7/include/linux/devpts_fs.h
6594--- linux-4.9.82/include/linux/devpts_fs.h 2016-12-11 19:17:54.000000000 +0000
6595+++ linux-4.9.82-vs2.3.9.7/include/linux/devpts_fs.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 6596@@ -34,5 +34,4 @@ void devpts_pty_kill(struct dentry *);
2380c486
JR
6597
6598 #endif
d337f35e 6599
2380c486 6600-
d337f35e 6601 #endif /* _LINUX_DEVPTS_FS_H */
cef7ea10
AM
6602diff -NurpP --minimal linux-4.9.82/include/linux/fs.h linux-4.9.82-vs2.3.9.7/include/linux/fs.h
6603--- linux-4.9.82/include/linux/fs.h 2018-02-22 21:18:53.000000000 +0000
6604+++ linux-4.9.82-vs2.3.9.7/include/linux/fs.h 2018-01-13 22:18:13.000000000 +0000
cc23e853 6605@@ -225,6 +225,7 @@ typedef int (dio_iodone_t)(struct kiocb
2380c486
JR
6606 #define ATTR_OPEN (1 << 15) /* Truncating from open(O_TRUNC) */
6607 #define ATTR_TIMES_SET (1 << 16)
cc23e853
AM
6608 #define ATTR_TOUCH (1 << 17)
6609+#define ATTR_TAG (1 << 18)
d337f35e
JR
6610
6611 /*
bb20add7 6612 * Whiteout is represented by a char device. The following constants define the
cc23e853 6613@@ -247,6 +248,7 @@ struct iattr {
d337f35e 6614 umode_t ia_mode;
42bc425c
AM
6615 kuid_t ia_uid;
6616 kgid_t ia_gid;
537831f9 6617+ ktag_t ia_tag;
d337f35e
JR
6618 loff_t ia_size;
6619 struct timespec ia_atime;
6620 struct timespec ia_mtime;
cc23e853 6621@@ -606,7 +608,9 @@ struct inode {
a168f21d 6622 unsigned short i_opflags;
42bc425c
AM
6623 kuid_t i_uid;
6624 kgid_t i_gid;
2380c486 6625- unsigned int i_flags;
537831f9 6626+ ktag_t i_tag;
2380c486
JR
6627+ unsigned short i_flags;
6628+ unsigned short i_vflags;
a168f21d
AM
6629
6630 #ifdef CONFIG_FS_POSIX_ACL
6631 struct posix_acl *i_acl;
cc23e853 6632@@ -635,6 +639,7 @@ struct inode {
f6c5ef8b
AM
6633 unsigned int __i_nlink;
6634 };
d33d7b00
AM
6635 dev_t i_rdev;
6636+ dev_t i_mdev;
42bc425c 6637 loff_t i_size;
a168f21d
AM
6638 struct timespec i_atime;
6639 struct timespec i_mtime;
cc23e853
AM
6640@@ -839,14 +844,19 @@ static inline void i_size_write(struct i
6641 #endif
537831f9 6642 }
2380c486 6643
61333608 6644+static inline void i_tag_write(struct inode *inode, vtag_t tag)
537831f9
AM
6645+{
6646+ inode->i_tag = make_ktag(&init_user_ns, tag);
6647+}
6648+
2380c486
JR
6649 static inline unsigned iminor(const struct inode *inode)
6650 {
6651- return MINOR(inode->i_rdev);
6652+ return MINOR(inode->i_mdev);
6653 }
6654
6655 static inline unsigned imajor(const struct inode *inode)
6656 {
6657- return MAJOR(inode->i_rdev);
6658+ return MAJOR(inode->i_mdev);
6659 }
6660
6661 extern struct block_device *I_BDEV(struct inode *inode);
cc23e853 6662@@ -903,6 +913,7 @@ struct file {
d337f35e
JR
6663 loff_t f_pos;
6664 struct fown_struct f_owner;
ec22aa5c 6665 const struct cred *f_cred;
61333608 6666+ vxid_t f_xid;
d337f35e
JR
6667 struct file_ra_state f_ra;
6668
2380c486 6669 u64 f_version;
cc23e853 6670@@ -1037,6 +1048,7 @@ struct file_lock {
2380c486 6671 struct file *fl_file;
d337f35e
JR
6672 loff_t fl_start;
6673 loff_t fl_end;
61333608 6674+ vxid_t fl_xid;
d337f35e
JR
6675
6676 struct fasync_struct * fl_fasync; /* for lease break notifications */
f6c5ef8b 6677 /* for lease breaks: */
cc23e853
AM
6678@@ -1469,6 +1481,11 @@ static inline gid_t i_gid_read(const str
6679 return from_kgid(inode->i_sb->s_user_ns, inode->i_gid);
6680 }
6681
6682+static inline vtag_t i_tag_read(const struct inode *inode)
6683+{
6684+ return from_ktag(&init_user_ns, inode->i_tag);
6685+}
6686+
6687 static inline void i_uid_write(struct inode *inode, uid_t uid)
6688 {
6689 inode->i_uid = make_kuid(inode->i_sb->s_user_ns, uid);
6690@@ -1758,6 +1775,7 @@ struct inode_operations {
6691 int (*setattr) (struct dentry *, struct iattr *);
6692 int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
d4263eb0 6693 ssize_t (*listxattr) (struct dentry *, char *, size_t);
d4263eb0 6694+ int (*sync_flags) (struct inode *, int, int);
d33d7b00
AM
6695 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
6696 u64 len);
42bc425c 6697 int (*update_time)(struct inode *, struct timespec *, int);
cc23e853 6698@@ -1772,6 +1790,7 @@ ssize_t rw_copy_check_uvector(int type,
537831f9
AM
6699 unsigned long nr_segs, unsigned long fast_segs,
6700 struct iovec *fast_pointer,
6701 struct iovec **ret_pointer);
d337f35e
JR
6702+ssize_t vfs_sendfile(struct file *, struct file *, loff_t *, size_t, loff_t);
6703
cc23e853
AM
6704 extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
6705 extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *);
6706@@ -1843,6 +1862,14 @@ struct super_operations {
6707 #else
6708 #define S_DAX 0 /* Make all the DAX code disappear */
6709 #endif
6710+#define S_IXUNLINK 16384 /* Immutable Invert on unlink */
537831f9
AM
6711+
6712+/* Linux-VServer related Inode flags */
6713+
6714+#define V_VALID 1
6715+#define V_XATTR 2
6716+#define V_BARRIER 4 /* Barrier for chroot() */
6717+#define V_COW 8 /* Copy on Write */
6718
6719 /*
6720 * Note that nosuid etc flags are inode-specific: setting some file-system
cc23e853 6721@@ -1867,10 +1894,13 @@ struct super_operations {
537831f9
AM
6722 #define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK)
6723 #define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME)
6724 #define IS_I_VERSION(inode) __IS_FLG(inode, MS_I_VERSION)
6725+#define IS_TAGGED(inode) __IS_FLG(inode, MS_TAGGED)
6726
6727 #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
6728 #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
6729 #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
6730+#define IS_IXUNLINK(inode) ((inode)->i_flags & S_IXUNLINK)
6731+#define IS_IXORUNLINK(inode) ((IS_IXUNLINK(inode) ? S_IMMUTABLE : 0) ^ IS_IMMUTABLE(inode))
6732 #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL)
6733
6734 #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
cc23e853
AM
6735@@ -1890,6 +1920,16 @@ static inline bool HAS_UNMAPPED_ID(struc
6736 return !uid_valid(inode->i_uid) || !gid_valid(inode->i_gid);
6737 }
537831f9
AM
6738
6739+#define IS_BARRIER(inode) (S_ISDIR((inode)->i_mode) && ((inode)->i_vflags & V_BARRIER))
6740+
6741+#ifdef CONFIG_VSERVER_COWBL
6742+# define IS_COW(inode) (IS_IXUNLINK(inode) && IS_IMMUTABLE(inode))
6743+# define IS_COW_LINK(inode) (S_ISREG((inode)->i_mode) && ((inode)->i_nlink > 1))
6744+#else
6745+# define IS_COW(inode) (0)
6746+# define IS_COW_LINK(inode) (0)
6747+#endif
6748+
6749 /*
6750 * Inode state bits. Protected by inode->i_lock
6751 *
cc23e853 6752@@ -2155,6 +2195,9 @@ extern struct kobject *fs_kobj;
bb20add7 6753 extern int locks_mandatory_locked(struct file *);
cc23e853 6754 extern int locks_mandatory_area(struct inode *, struct file *, loff_t, loff_t, unsigned char);
537831f9
AM
6755
6756+#define ATTR_FLAG_BARRIER 512 /* Barrier for chroot() */
6757+#define ATTR_FLAG_IXUNLINK 1024 /* Immutable invert on unlink */
6758+
6759 /*
6760 * Candidates for mandatory locking have the setgid bit set
6761 * but no group execute bit - an otherwise meaningless combination.
cc23e853
AM
6762@@ -2335,7 +2378,7 @@ struct filename {
6763 const char iname[];
6764 };
6765
6766-extern long vfs_truncate(const struct path *, loff_t);
6767+extern long vfs_truncate(struct path *, loff_t);
6768 extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
6769 struct file *filp);
6770 extern int vfs_fallocate(struct file *file, int mode, loff_t offset,
6771@@ -2965,6 +3008,7 @@ extern int dcache_dir_open(struct inode
d337f35e
JR
6772 extern int dcache_dir_close(struct inode *, struct file *);
6773 extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
c2e5f7c8
JR
6774 extern int dcache_readdir(struct file *, struct dir_context *);
6775+extern int dcache_readdir_filter(struct file *, struct dir_context *, int (*)(struct dentry *));
76514441 6776 extern int simple_setattr(struct dentry *, struct iattr *);
d337f35e
JR
6777 extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
6778 extern int simple_statfs(struct dentry *, struct kstatfs *);
cef7ea10
AM
6779diff -NurpP --minimal linux-4.9.82/include/linux/init_task.h linux-4.9.82-vs2.3.9.7/include/linux/init_task.h
6780--- linux-4.9.82/include/linux/init_task.h 2016-12-11 19:17:54.000000000 +0000
6781+++ linux-4.9.82-vs2.3.9.7/include/linux/init_task.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 6782@@ -271,6 +271,10 @@ extern struct task_group root_task_group
b00e13aa 6783 INIT_VTIME(tsk) \
cc23e853
AM
6784 INIT_NUMA_BALANCING(tsk) \
6785 INIT_KASAN(tsk) \
d337f35e
JR
6786+ .xid = 0, \
6787+ .vx_info = NULL, \
6788+ .nid = 0, \
6789+ .nx_info = NULL, \
6790 }
6791
6792
cef7ea10
AM
6793diff -NurpP --minimal linux-4.9.82/include/linux/ipc.h linux-4.9.82-vs2.3.9.7/include/linux/ipc.h
6794--- linux-4.9.82/include/linux/ipc.h 2016-12-11 19:17:54.000000000 +0000
6795+++ linux-4.9.82-vs2.3.9.7/include/linux/ipc.h 2018-01-10 02:50:49.000000000 +0000
537831f9 6796@@ -16,6 +16,7 @@ struct kern_ipc_perm
d337f35e 6797 key_t key;
537831f9
AM
6798 kuid_t uid;
6799 kgid_t gid;
61333608 6800+ vxid_t xid;
537831f9
AM
6801 kuid_t cuid;
6802 kgid_t cgid;
db55b927 6803 umode_t mode;
cef7ea10
AM
6804diff -NurpP --minimal linux-4.9.82/include/linux/memcontrol.h linux-4.9.82-vs2.3.9.7/include/linux/memcontrol.h
6805--- linux-4.9.82/include/linux/memcontrol.h 2018-02-22 21:18:54.000000000 +0000
6806+++ linux-4.9.82-vs2.3.9.7/include/linux/memcontrol.h 2018-01-25 00:07:15.000000000 +0000
cc23e853
AM
6807@@ -92,6 +92,7 @@ enum mem_cgroup_events_target {
6808 MEM_CGROUP_NTARGETS,
6809 };
6810
6811+
6812 #ifdef CONFIG_MEMCG
6813
6814 #define MEM_CGROUP_ID_SHIFT 16
369dbd59 6815@@ -402,6 +403,12 @@ static inline bool mem_cgroup_is_descend
cc23e853
AM
6816 return cgroup_is_descendant(memcg->css.cgroup, root->css.cgroup);
6817 }
6818
369dbd59
AM
6819+extern unsigned long mem_cgroup_mem_usage_pages(struct mem_cgroup *memcg);
6820+extern unsigned long mem_cgroup_mem_limit_pages(struct mem_cgroup *memcg);
6821+extern unsigned long mem_cgroup_memsw_usage_pages(struct mem_cgroup *memcg);
6822+extern unsigned long mem_cgroup_memsw_limit_pages(struct mem_cgroup *memcg);
6823+extern void dump_mem_cgroup(struct mem_cgroup *memcg);
cc23e853
AM
6824+
6825 static inline bool mm_match_cgroup(struct mm_struct *mm,
6826 struct mem_cgroup *memcg)
e3afe727 6827 {
cef7ea10
AM
6828diff -NurpP --minimal linux-4.9.82/include/linux/mount.h linux-4.9.82-vs2.3.9.7/include/linux/mount.h
6829--- linux-4.9.82/include/linux/mount.h 2018-02-22 21:18:54.000000000 +0000
6830+++ linux-4.9.82-vs2.3.9.7/include/linux/mount.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 6831@@ -63,6 +63,9 @@ struct mnt_namespace;
bb20add7 6832 #define MNT_MARKED 0x4000000
cc23e853 6833 #define MNT_UMOUNT 0x8000000
d337f35e 6834
2380c486
JR
6835+#define MNT_TAGID 0x10000
6836+#define MNT_NOTAG 0x20000
6837+
d337f35e 6838 struct vfsmount {
db55b927
AM
6839 struct dentry *mnt_root; /* root of the mounted tree */
6840 struct super_block *mnt_sb; /* pointer to superblock */
cef7ea10
AM
6841diff -NurpP --minimal linux-4.9.82/include/linux/net.h linux-4.9.82-vs2.3.9.7/include/linux/net.h
6842--- linux-4.9.82/include/linux/net.h 2016-12-11 19:17:54.000000000 +0000
6843+++ linux-4.9.82-vs2.3.9.7/include/linux/net.h 2018-01-10 02:50:49.000000000 +0000
cc23e853
AM
6844@@ -44,6 +44,7 @@ struct net;
6845 #define SOCK_NOSPACE 2
d337f35e
JR
6846 #define SOCK_PASSCRED 3
6847 #define SOCK_PASSSEC 4
cc23e853 6848+#define SOCK_USER_SOCKET 5
d337f35e
JR
6849
6850 #ifndef ARCH_HAS_SOCKET_TYPES
6851 /**
cef7ea10
AM
6852diff -NurpP --minimal linux-4.9.82/include/linux/netdevice.h linux-4.9.82-vs2.3.9.7/include/linux/netdevice.h
6853--- linux-4.9.82/include/linux/netdevice.h 2018-02-22 21:18:54.000000000 +0000
6854+++ linux-4.9.82-vs2.3.9.7/include/linux/netdevice.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 6855@@ -2474,6 +2474,7 @@ static inline int dev_recursion_level(vo
c2e5f7c8
JR
6856
6857 struct net_device *dev_get_by_index(struct net *net, int ifindex);
6858 struct net_device *__dev_get_by_index(struct net *net, int ifindex);
6859+struct net_device *dev_get_by_index_real_rcu(struct net *net, int ifindex);
6860 struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex);
6861 int netdev_get_name(struct net *net, char *name, int ifindex);
6862 int dev_restart(struct net_device *dev);
cef7ea10
AM
6863diff -NurpP --minimal linux-4.9.82/include/linux/nsproxy.h linux-4.9.82-vs2.3.9.7/include/linux/nsproxy.h
6864--- linux-4.9.82/include/linux/nsproxy.h 2016-12-11 19:17:54.000000000 +0000
6865+++ linux-4.9.82-vs2.3.9.7/include/linux/nsproxy.h 2018-01-10 02:50:49.000000000 +0000
2380c486 6866@@ -3,6 +3,7 @@
d337f35e 6867
2380c486
JR
6868 #include <linux/spinlock.h>
6869 #include <linux/sched.h>
6870+#include <linux/vserver/debug.h>
6871
6872 struct mnt_namespace;
6873 struct uts_namespace;
cc23e853 6874@@ -65,6 +66,7 @@ extern struct nsproxy init_nsproxy;
bb20add7 6875 */
2380c486
JR
6876
6877 int copy_namespaces(unsigned long flags, struct task_struct *tsk);
6878+struct nsproxy *copy_nsproxy(struct nsproxy *orig);
6879 void exit_task_namespaces(struct task_struct *tsk);
6880 void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new);
6881 void free_nsproxy(struct nsproxy *ns);
cc23e853 6882@@ -72,16 +74,26 @@ int unshare_nsproxy_namespaces(unsigned
b00e13aa 6883 struct cred *, struct fs_struct *);
a168f21d 6884 int __init nsproxy_cache_init(void);
2380c486
JR
6885
6886-static inline void put_nsproxy(struct nsproxy *ns)
6887+#define get_nsproxy(n) __get_nsproxy(n, __FILE__, __LINE__)
d337f35e 6888+
2380c486
JR
6889+static inline void __get_nsproxy(struct nsproxy *ns,
6890+ const char *_file, int _line)
6891 {
6892- if (atomic_dec_and_test(&ns->count)) {
6893- free_nsproxy(ns);
6894- }
6895+ vxlprintk(VXD_CBIT(space, 0), "get_nsproxy(%p[%u])",
6896+ ns, atomic_read(&ns->count), _file, _line);
d337f35e 6897+ atomic_inc(&ns->count);
2380c486
JR
6898 }
6899
6900-static inline void get_nsproxy(struct nsproxy *ns)
6901+#define put_nsproxy(n) __put_nsproxy(n, __FILE__, __LINE__)
d337f35e 6902+
2380c486
JR
6903+static inline void __put_nsproxy(struct nsproxy *ns,
6904+ const char *_file, int _line)
6905 {
6906- atomic_inc(&ns->count);
6907+ vxlprintk(VXD_CBIT(space, 0), "put_nsproxy(%p[%u])",
6908+ ns, atomic_read(&ns->count), _file, _line);
6909+ if (atomic_dec_and_test(&ns->count)) {
6910+ free_nsproxy(ns);
6911+ }
6912 }
d337f35e 6913
763640ca 6914 #endif
cef7ea10
AM
6915diff -NurpP --minimal linux-4.9.82/include/linux/pid.h linux-4.9.82-vs2.3.9.7/include/linux/pid.h
6916--- linux-4.9.82/include/linux/pid.h 2018-02-22 21:18:54.000000000 +0000
6917+++ linux-4.9.82-vs2.3.9.7/include/linux/pid.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 6918@@ -10,7 +10,8 @@ enum pid_type
d337f35e 6919 PIDTYPE_SID,
cc23e853
AM
6920 PIDTYPE_MAX,
6921 /* only valid to __task_pid_nr_ns() */
6922- __PIDTYPE_TGID
6923+ __PIDTYPE_TGID,
6924+ __PIDTYPE_REALPID
d337f35e
JR
6925 };
6926
6927 /*
cc23e853 6928@@ -172,6 +173,7 @@ static inline pid_t pid_nr(struct pid *p
2380c486
JR
6929 }
6930
6931 pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns);
6932+pid_t pid_unmapped_nr_ns(struct pid *pid, struct pid_namespace *ns);
6933 pid_t pid_vnr(struct pid *pid);
6934
6935 #define do_each_pid_task(pid, type, task) \
cef7ea10
AM
6936diff -NurpP --minimal linux-4.9.82/include/linux/quotaops.h linux-4.9.82-vs2.3.9.7/include/linux/quotaops.h
6937--- linux-4.9.82/include/linux/quotaops.h 2016-12-11 19:17:54.000000000 +0000
6938+++ linux-4.9.82-vs2.3.9.7/include/linux/quotaops.h 2018-01-10 02:50:49.000000000 +0000
e22b5178
AM
6939@@ -8,6 +8,7 @@
6940 #define _LINUX_QUOTAOPS_
6941
6942 #include <linux/fs.h>
6943+#include <linux/vs_dlimit.h>
6944
76514441
AM
6945 #define DQUOT_SPACE_WARN 0x1
6946 #define DQUOT_SPACE_RESERVE 0x2
cc23e853 6947@@ -214,11 +215,12 @@ static inline void dquot_drop(struct ino
76514441 6948
cc23e853 6949 static inline int dquot_alloc_inode(struct inode *inode)
76514441
AM
6950 {
6951- return 0;
6952+ return dl_alloc_inode(inode);
6953 }
6954
cc23e853 6955 static inline void dquot_free_inode(struct inode *inode)
e22b5178 6956 {
76514441
AM
6957+ dl_free_inode(inode);
6958 }
6959
6960 static inline int dquot_transfer(struct inode *inode, struct iattr *iattr)
cc23e853 6961@@ -229,6 +231,10 @@ static inline int dquot_transfer(struct
76514441
AM
6962 static inline int __dquot_alloc_space(struct inode *inode, qsize_t number,
6963 int flags)
6964 {
6965+ int ret = 0;
6966+
6967+ if ((ret = dl_alloc_space(inode, number)))
6968+ return ret;
6969 if (!(flags & DQUOT_SPACE_RESERVE))
6970 inode_add_bytes(inode, number);
6971 return 0;
cc23e853 6972@@ -239,6 +245,7 @@ static inline void __dquot_free_space(st
76514441
AM
6973 {
6974 if (!(flags & DQUOT_SPACE_RESERVE))
6975 inode_sub_bytes(inode, number);
6976+ dl_free_space(inode, number);
6977 }
6978
6979 static inline int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
cef7ea10
AM
6980diff -NurpP --minimal linux-4.9.82/include/linux/sched.h linux-4.9.82-vs2.3.9.7/include/linux/sched.h
6981--- linux-4.9.82/include/linux/sched.h 2018-02-22 21:18:54.000000000 +0000
6982+++ linux-4.9.82-vs2.3.9.7/include/linux/sched.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 6983@@ -1717,6 +1717,14 @@ struct task_struct {
2380c486 6984 #endif
42bc425c 6985 struct seccomp seccomp;
2380c486
JR
6986
6987+/* vserver context data */
6988+ struct vx_info *vx_info;
6989+ struct nx_info *nx_info;
d337f35e 6990+
61333608
AM
6991+ vxid_t xid;
6992+ vnid_t nid;
6993+ vtag_t tag;
2380c486
JR
6994+
6995 /* Thread group tracking */
6996 u32 parent_exec_id;
6997 u32 self_exec_id;
cc23e853 6998@@ -2110,6 +2118,11 @@ struct pid_namespace;
ec22aa5c
AM
6999 pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
7000 struct pid_namespace *ns);
d337f35e 7001
2380c486
JR
7002+#include <linux/vserver/base.h>
7003+#include <linux/vserver/context.h>
7004+#include <linux/vserver/debug.h>
7005+#include <linux/vserver/pid.h>
7006+
7007 static inline pid_t task_pid_nr(struct task_struct *tsk)
7008 {
7009 return tsk->pid;
cc23e853 7010@@ -2123,7 +2136,8 @@ static inline pid_t task_pid_nr_ns(struc
d337f35e 7011
2380c486
JR
7012 static inline pid_t task_pid_vnr(struct task_struct *tsk)
7013 {
ec22aa5c
AM
7014- return __task_pid_nr_ns(tsk, PIDTYPE_PID, NULL);
7015+ // return __task_pid_nr_ns(tsk, PIDTYPE_PID, NULL);
7016+ return vx_map_pid(__task_pid_nr_ns(tsk, PIDTYPE_PID, NULL));
2380c486 7017 }
d337f35e 7018
d337f35e 7019
cef7ea10
AM
7020diff -NurpP --minimal linux-4.9.82/include/linux/shmem_fs.h linux-4.9.82-vs2.3.9.7/include/linux/shmem_fs.h
7021--- linux-4.9.82/include/linux/shmem_fs.h 2016-12-11 19:17:54.000000000 +0000
7022+++ linux-4.9.82-vs2.3.9.7/include/linux/shmem_fs.h 2018-01-10 02:50:49.000000000 +0000
bb20add7 7023@@ -10,6 +10,9 @@
2380c486 7024
a168f21d 7025 /* inode in-kernel data */
2380c486
JR
7026
7027+#define TMPFS_SUPER_MAGIC 0x01021994
7028+
7029+
7030 struct shmem_inode_info {
7031 spinlock_t lock;
bb20add7 7032 unsigned int seals; /* shmem seals */
cef7ea10
AM
7033diff -NurpP --minimal linux-4.9.82/include/linux/stat.h linux-4.9.82-vs2.3.9.7/include/linux/stat.h
7034--- linux-4.9.82/include/linux/stat.h 2016-12-11 19:17:54.000000000 +0000
7035+++ linux-4.9.82-vs2.3.9.7/include/linux/stat.h 2018-01-10 02:50:49.000000000 +0000
537831f9 7036@@ -25,6 +25,7 @@ struct kstat {
2380c486 7037 unsigned int nlink;
42bc425c
AM
7038 kuid_t uid;
7039 kgid_t gid;
8ce283e1 7040+ ktag_t tag;
2380c486
JR
7041 dev_t rdev;
7042 loff_t size;
7043 struct timespec atime;
cef7ea10
AM
7044diff -NurpP --minimal linux-4.9.82/include/linux/sunrpc/auth.h linux-4.9.82-vs2.3.9.7/include/linux/sunrpc/auth.h
7045--- linux-4.9.82/include/linux/sunrpc/auth.h 2016-12-11 19:17:54.000000000 +0000
7046+++ linux-4.9.82-vs2.3.9.7/include/linux/sunrpc/auth.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 7047@@ -46,6 +46,7 @@ enum {
2380c486 7048 struct auth_cred {
b00e13aa
AM
7049 kuid_t uid;
7050 kgid_t gid;
7051+ ktag_t tag;
2380c486 7052 struct group_info *group_info;
db55b927 7053 const char *principal;
c2e5f7c8 7054 unsigned long ac_flags;
cef7ea10
AM
7055diff -NurpP --minimal linux-4.9.82/include/linux/sunrpc/clnt.h linux-4.9.82-vs2.3.9.7/include/linux/sunrpc/clnt.h
7056--- linux-4.9.82/include/linux/sunrpc/clnt.h 2018-02-22 21:18:55.000000000 +0000
7057+++ linux-4.9.82-vs2.3.9.7/include/linux/sunrpc/clnt.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 7058@@ -52,7 +52,8 @@ struct rpc_clnt {
2380c486 7059 cl_discrtry : 1,/* disconnect before retry */
c2e5f7c8 7060 cl_noretranstimeo: 1,/* No retransmit timeouts */
2380c486
JR
7061 cl_autobind : 1,/* use getport() */
7062- cl_chatty : 1;/* be verbose */
7063+ cl_chatty : 1,/* be verbose */
7064+ cl_tag : 1;/* context tagging */
d337f35e 7065
2380c486
JR
7066 struct rpc_rtt * cl_rtt; /* RTO estimator data */
7067 const struct rpc_timeout *cl_timeout; /* Timeout strategy */
cef7ea10
AM
7068diff -NurpP --minimal linux-4.9.82/include/linux/types.h linux-4.9.82-vs2.3.9.7/include/linux/types.h
7069--- linux-4.9.82/include/linux/types.h 2016-12-11 19:17:54.000000000 +0000
7070+++ linux-4.9.82-vs2.3.9.7/include/linux/types.h 2018-01-10 02:50:49.000000000 +0000
537831f9 7071@@ -32,6 +32,9 @@ typedef __kernel_uid32_t uid_t;
2380c486
JR
7072 typedef __kernel_gid32_t gid_t;
7073 typedef __kernel_uid16_t uid16_t;
7074 typedef __kernel_gid16_t gid16_t;
61333608
AM
7075+typedef unsigned int vxid_t;
7076+typedef unsigned int vnid_t;
7077+typedef unsigned int vtag_t;
2380c486
JR
7078
7079 typedef unsigned long uintptr_t;
7080
cef7ea10
AM
7081diff -NurpP --minimal linux-4.9.82/include/linux/uidgid.h linux-4.9.82-vs2.3.9.7/include/linux/uidgid.h
7082--- linux-4.9.82/include/linux/uidgid.h 2016-12-11 19:17:54.000000000 +0000
7083+++ linux-4.9.82-vs2.3.9.7/include/linux/uidgid.h 2018-01-10 02:50:49.000000000 +0000
bb20add7 7084@@ -21,13 +21,17 @@ typedef struct {
537831f9
AM
7085 uid_t val;
7086 } kuid_t;
7087
7088-
7089 typedef struct {
7090 gid_t val;
7091 } kgid_t;
7092
7093+typedef struct {
61333608 7094+ vtag_t val;
537831f9
AM
7095+} ktag_t;
7096+
7097 #define KUIDT_INIT(value) (kuid_t){ value }
7098 #define KGIDT_INIT(value) (kgid_t){ value }
7099+#define KTAGT_INIT(value) (ktag_t){ value }
7100
cc23e853 7101 #ifdef CONFIG_MULTIUSER
537831f9 7102 static inline uid_t __kuid_val(kuid_t uid)
cc23e853 7103@@ -51,11 +55,18 @@ static inline gid_t __kgid_val(kgid_t gi
537831f9 7104 }
cc23e853 7105 #endif
537831f9 7106
61333608 7107+static inline vtag_t __ktag_val(ktag_t tag)
537831f9
AM
7108+{
7109+ return tag.val;
7110+}
7111+
537831f9
AM
7112 #define GLOBAL_ROOT_UID KUIDT_INIT(0)
7113 #define GLOBAL_ROOT_GID KGIDT_INIT(0)
7114+#define GLOBAL_ROOT_TAG KTAGT_INIT(0)
7115
7116 #define INVALID_UID KUIDT_INIT(-1)
7117 #define INVALID_GID KGIDT_INIT(-1)
7118+#define INVALID_TAG KTAGT_INIT(-1)
7119
7120 static inline bool uid_eq(kuid_t left, kuid_t right)
7121 {
cc23e853 7122@@ -67,6 +78,11 @@ static inline bool gid_eq(kgid_t left, k
537831f9
AM
7123 return __kgid_val(left) == __kgid_val(right);
7124 }
7125
7126+static inline bool tag_eq(ktag_t left, ktag_t right)
7127+{
7128+ return __ktag_val(left) == __ktag_val(right);
7129+}
7130+
7131 static inline bool uid_gt(kuid_t left, kuid_t right)
7132 {
7133 return __kuid_val(left) > __kuid_val(right);
cc23e853
AM
7134@@ -117,13 +133,21 @@ static inline bool gid_valid(kgid_t gid)
7135 return __kgid_val(gid) != (gid_t) -1;
537831f9
AM
7136 }
7137
7138+static inline bool tag_valid(ktag_t tag)
7139+{
7140+ return !tag_eq(tag, INVALID_TAG);
7141+}
7142+
7143 #ifdef CONFIG_USER_NS
7144
7145 extern kuid_t make_kuid(struct user_namespace *from, uid_t uid);
7146 extern kgid_t make_kgid(struct user_namespace *from, gid_t gid);
c90fe048 7147+extern ktag_t make_ktag(struct user_namespace *from, gid_t gid);
537831f9
AM
7148
7149 extern uid_t from_kuid(struct user_namespace *to, kuid_t uid);
7150 extern gid_t from_kgid(struct user_namespace *to, kgid_t gid);
61333608 7151+extern vtag_t from_ktag(struct user_namespace *to, ktag_t tag);
537831f9
AM
7152+
7153 extern uid_t from_kuid_munged(struct user_namespace *to, kuid_t uid);
7154 extern gid_t from_kgid_munged(struct user_namespace *to, kgid_t gid);
7155
cc23e853 7156@@ -149,6 +173,11 @@ static inline kgid_t make_kgid(struct us
537831f9
AM
7157 return KGIDT_INIT(gid);
7158 }
7159
61333608 7160+static inline ktag_t make_ktag(struct user_namespace *from, vtag_t tag)
537831f9
AM
7161+{
7162+ return KTAGT_INIT(tag);
7163+}
7164+
7165 static inline uid_t from_kuid(struct user_namespace *to, kuid_t kuid)
7166 {
7167 return __kuid_val(kuid);
cc23e853 7168@@ -159,6 +188,11 @@ static inline gid_t from_kgid(struct use
537831f9
AM
7169 return __kgid_val(kgid);
7170 }
7171
61333608 7172+static inline vtag_t from_ktag(struct user_namespace *to, ktag_t ktag)
537831f9
AM
7173+{
7174+ return __ktag_val(ktag);
7175+}
7176+
7177 static inline uid_t from_kuid_munged(struct user_namespace *to, kuid_t kuid)
7178 {
7179 uid_t uid = from_kuid(to, kuid);
cef7ea10
AM
7180diff -NurpP --minimal linux-4.9.82/include/linux/vroot.h linux-4.9.82-vs2.3.9.7/include/linux/vroot.h
7181--- linux-4.9.82/include/linux/vroot.h 1970-01-01 00:00:00.000000000 +0000
7182+++ linux-4.9.82-vs2.3.9.7/include/linux/vroot.h 2018-01-10 02:50:49.000000000 +0000
2380c486
JR
7183@@ -0,0 +1,51 @@
7184+
7185+/*
7186+ * include/linux/vroot.h
7187+ *
cc23e853
AM
7188+ * written by Herbert P?tzl, 9/11/2002
7189+ * ported to 2.6 by Herbert P?tzl, 30/12/2004
2380c486 7190+ *
cc23e853 7191+ * Copyright (C) 2002-2007 by Herbert P?tzl.
2380c486
JR
7192+ * Redistribution of this file is permitted under the
7193+ * GNU General Public License.
7194+ */
7195+
7196+#ifndef _LINUX_VROOT_H
7197+#define _LINUX_VROOT_H
7198+
7199+
7200+#ifdef __KERNEL__
7201+
7202+/* Possible states of device */
7203+enum {
7204+ Vr_unbound,
7205+ Vr_bound,
7206+};
7207+
7208+struct vroot_device {
7209+ int vr_number;
7210+ int vr_refcnt;
7211+
7212+ struct semaphore vr_ctl_mutex;
7213+ struct block_device *vr_device;
7214+ int vr_state;
7215+};
7216+
7217+
7218+typedef struct block_device *(vroot_grb_func)(struct block_device *);
7219+
7220+extern int register_vroot_grb(vroot_grb_func *);
7221+extern int unregister_vroot_grb(vroot_grb_func *);
7222+
7223+#endif /* __KERNEL__ */
7224+
7225+#define MAX_VROOT_DEFAULT 8
7226+
7227+/*
7228+ * IOCTL commands --- we will commandeer 0x56 ('V')
7229+ */
7230+
7231+#define VROOT_SET_DEV 0x5600
7232+#define VROOT_CLR_DEV 0x5601
7233+
7234+#endif /* _LINUX_VROOT_H */
cef7ea10
AM
7235diff -NurpP --minimal linux-4.9.82/include/linux/vs_base.h linux-4.9.82-vs2.3.9.7/include/linux/vs_base.h
7236--- linux-4.9.82/include/linux/vs_base.h 1970-01-01 00:00:00.000000000 +0000
7237+++ linux-4.9.82-vs2.3.9.7/include/linux/vs_base.h 2018-01-10 02:50:49.000000000 +0000
2380c486
JR
7238@@ -0,0 +1,10 @@
7239+#ifndef _VS_BASE_H
7240+#define _VS_BASE_H
7241+
7242+#include "vserver/base.h"
7243+#include "vserver/check.h"
7244+#include "vserver/debug.h"
7245+
7246+#else
7247+#warning duplicate inclusion
7248+#endif
cef7ea10
AM
7249diff -NurpP --minimal linux-4.9.82/include/linux/vs_context.h linux-4.9.82-vs2.3.9.7/include/linux/vs_context.h
7250--- linux-4.9.82/include/linux/vs_context.h 1970-01-01 00:00:00.000000000 +0000
7251+++ linux-4.9.82-vs2.3.9.7/include/linux/vs_context.h 2018-01-10 02:50:49.000000000 +0000
4a036bed 7252@@ -0,0 +1,242 @@
2380c486
JR
7253+#ifndef _VS_CONTEXT_H
7254+#define _VS_CONTEXT_H
7255+
7256+#include "vserver/base.h"
7257+#include "vserver/check.h"
7258+#include "vserver/context.h"
7259+#include "vserver/history.h"
7260+#include "vserver/debug.h"
7261+
7262+#include <linux/sched.h>
7263+
7264+
7265+#define get_vx_info(i) __get_vx_info(i, __FILE__, __LINE__, __HERE__)
7266+
7267+static inline struct vx_info *__get_vx_info(struct vx_info *vxi,
7268+ const char *_file, int _line, void *_here)
7269+{
7270+ if (!vxi)
7271+ return NULL;
7272+
7273+ vxlprintk(VXD_CBIT(xid, 2), "get_vx_info(%p[#%d.%d])",
7274+ vxi, vxi ? vxi->vx_id : 0,
7275+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7276+ _file, _line);
7277+ __vxh_get_vx_info(vxi, _here);
7278+
7279+ atomic_inc(&vxi->vx_usecnt);
7280+ return vxi;
7281+}
7282+
7283+
7284+extern void free_vx_info(struct vx_info *);
7285+
7286+#define put_vx_info(i) __put_vx_info(i, __FILE__, __LINE__, __HERE__)
7287+
7288+static inline void __put_vx_info(struct vx_info *vxi,
7289+ const char *_file, int _line, void *_here)
7290+{
7291+ if (!vxi)
7292+ return;
7293+
7294+ vxlprintk(VXD_CBIT(xid, 2), "put_vx_info(%p[#%d.%d])",
7295+ vxi, vxi ? vxi->vx_id : 0,
7296+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7297+ _file, _line);
7298+ __vxh_put_vx_info(vxi, _here);
7299+
7300+ if (atomic_dec_and_test(&vxi->vx_usecnt))
7301+ free_vx_info(vxi);
7302+}
7303+
7304+
7305+#define init_vx_info(p, i) \
7306+ __init_vx_info(p, i, __FILE__, __LINE__, __HERE__)
7307+
7308+static inline void __init_vx_info(struct vx_info **vxp, struct vx_info *vxi,
7309+ const char *_file, int _line, void *_here)
7310+{
7311+ if (vxi) {
7312+ vxlprintk(VXD_CBIT(xid, 3),
7313+ "init_vx_info(%p[#%d.%d])",
7314+ vxi, vxi ? vxi->vx_id : 0,
7315+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7316+ _file, _line);
7317+ __vxh_init_vx_info(vxi, vxp, _here);
7318+
7319+ atomic_inc(&vxi->vx_usecnt);
7320+ }
7321+ *vxp = vxi;
7322+}
7323+
7324+
7325+#define set_vx_info(p, i) \
7326+ __set_vx_info(p, i, __FILE__, __LINE__, __HERE__)
7327+
7328+static inline void __set_vx_info(struct vx_info **vxp, struct vx_info *vxi,
7329+ const char *_file, int _line, void *_here)
7330+{
7331+ struct vx_info *vxo;
7332+
7333+ if (!vxi)
7334+ return;
7335+
7336+ vxlprintk(VXD_CBIT(xid, 3), "set_vx_info(%p[#%d.%d])",
7337+ vxi, vxi ? vxi->vx_id : 0,
7338+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7339+ _file, _line);
7340+ __vxh_set_vx_info(vxi, vxp, _here);
7341+
7342+ atomic_inc(&vxi->vx_usecnt);
7343+ vxo = xchg(vxp, vxi);
7344+ BUG_ON(vxo);
7345+}
7346+
7347+
7348+#define clr_vx_info(p) __clr_vx_info(p, __FILE__, __LINE__, __HERE__)
7349+
7350+static inline void __clr_vx_info(struct vx_info **vxp,
7351+ const char *_file, int _line, void *_here)
7352+{
7353+ struct vx_info *vxo;
7354+
7355+ vxo = xchg(vxp, NULL);
7356+ if (!vxo)
7357+ return;
7358+
7359+ vxlprintk(VXD_CBIT(xid, 3), "clr_vx_info(%p[#%d.%d])",
7360+ vxo, vxo ? vxo->vx_id : 0,
7361+ vxo ? atomic_read(&vxo->vx_usecnt) : 0,
7362+ _file, _line);
7363+ __vxh_clr_vx_info(vxo, vxp, _here);
7364+
7365+ if (atomic_dec_and_test(&vxo->vx_usecnt))
7366+ free_vx_info(vxo);
7367+}
7368+
7369+
7370+#define claim_vx_info(v, p) \
7371+ __claim_vx_info(v, p, __FILE__, __LINE__, __HERE__)
7372+
7373+static inline void __claim_vx_info(struct vx_info *vxi,
7374+ struct task_struct *task,
7375+ const char *_file, int _line, void *_here)
7376+{
7377+ vxlprintk(VXD_CBIT(xid, 3), "claim_vx_info(%p[#%d.%d.%d]) %p",
7378+ vxi, vxi ? vxi->vx_id : 0,
7379+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7380+ vxi ? atomic_read(&vxi->vx_tasks) : 0,
7381+ task, _file, _line);
7382+ __vxh_claim_vx_info(vxi, task, _here);
7383+
7384+ atomic_inc(&vxi->vx_tasks);
7385+}
7386+
7387+
7388+extern void unhash_vx_info(struct vx_info *);
7389+
7390+#define release_vx_info(v, p) \
7391+ __release_vx_info(v, p, __FILE__, __LINE__, __HERE__)
7392+
7393+static inline void __release_vx_info(struct vx_info *vxi,
7394+ struct task_struct *task,
7395+ const char *_file, int _line, void *_here)
7396+{
7397+ vxlprintk(VXD_CBIT(xid, 3), "release_vx_info(%p[#%d.%d.%d]) %p",
7398+ vxi, vxi ? vxi->vx_id : 0,
7399+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7400+ vxi ? atomic_read(&vxi->vx_tasks) : 0,
7401+ task, _file, _line);
7402+ __vxh_release_vx_info(vxi, task, _here);
7403+
7404+ might_sleep();
7405+
7406+ if (atomic_dec_and_test(&vxi->vx_tasks))
7407+ unhash_vx_info(vxi);
7408+}
7409+
7410+
7411+#define task_get_vx_info(p) \
7412+ __task_get_vx_info(p, __FILE__, __LINE__, __HERE__)
7413+
7414+static inline struct vx_info *__task_get_vx_info(struct task_struct *p,
7415+ const char *_file, int _line, void *_here)
7416+{
7417+ struct vx_info *vxi;
7418+
7419+ task_lock(p);
7420+ vxlprintk(VXD_CBIT(xid, 5), "task_get_vx_info(%p)",
7421+ p, _file, _line);
7422+ vxi = __get_vx_info(p->vx_info, _file, _line, _here);
7423+ task_unlock(p);
7424+ return vxi;
7425+}
7426+
7427+
7428+static inline void __wakeup_vx_info(struct vx_info *vxi)
7429+{
7430+ if (waitqueue_active(&vxi->vx_wait))
7431+ wake_up_interruptible(&vxi->vx_wait);
7432+}
7433+
7434+
7435+#define enter_vx_info(v, s) __enter_vx_info(v, s, __FILE__, __LINE__)
7436+
7437+static inline void __enter_vx_info(struct vx_info *vxi,
7438+ struct vx_info_save *vxis, const char *_file, int _line)
7439+{
7440+ vxlprintk(VXD_CBIT(xid, 5), "enter_vx_info(%p[#%d],%p) %p[#%d,%p]",
7441+ vxi, vxi ? vxi->vx_id : 0, vxis, current,
7442+ current->xid, current->vx_info, _file, _line);
7443+ vxis->vxi = xchg(&current->vx_info, vxi);
7444+ vxis->xid = current->xid;
7445+ current->xid = vxi ? vxi->vx_id : 0;
7446+}
7447+
7448+#define leave_vx_info(s) __leave_vx_info(s, __FILE__, __LINE__)
7449+
7450+static inline void __leave_vx_info(struct vx_info_save *vxis,
7451+ const char *_file, int _line)
7452+{
7453+ vxlprintk(VXD_CBIT(xid, 5), "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]",
7454+ vxis, vxis->xid, vxis->vxi, current,
7455+ current->xid, current->vx_info, _file, _line);
7456+ (void)xchg(&current->vx_info, vxis->vxi);
7457+ current->xid = vxis->xid;
7458+}
7459+
7460+
7461+static inline void __enter_vx_admin(struct vx_info_save *vxis)
7462+{
7463+ vxis->vxi = xchg(&current->vx_info, NULL);
61333608 7464+ vxis->xid = xchg(&current->xid, (vxid_t)0);
2380c486
JR
7465+}
7466+
7467+static inline void __leave_vx_admin(struct vx_info_save *vxis)
7468+{
7469+ (void)xchg(&current->xid, vxis->xid);
7470+ (void)xchg(&current->vx_info, vxis->vxi);
7471+}
7472+
4a036bed
AM
7473+#define task_is_init(p) \
7474+ __task_is_init(p, __FILE__, __LINE__, __HERE__)
7475+
7476+static inline int __task_is_init(struct task_struct *p,
7477+ const char *_file, int _line, void *_here)
7478+{
7479+ int is_init = is_global_init(p);
7480+
7481+ task_lock(p);
7482+ if (p->vx_info)
7483+ is_init = p->vx_info->vx_initpid == p->pid;
7484+ task_unlock(p);
7485+ return is_init;
7486+}
7487+
2380c486
JR
7488+extern void exit_vx_info(struct task_struct *, int);
7489+extern void exit_vx_info_early(struct task_struct *, int);
7490+
7491+
7492+#else
7493+#warning duplicate inclusion
7494+#endif
cef7ea10
AM
7495diff -NurpP --minimal linux-4.9.82/include/linux/vs_cowbl.h linux-4.9.82-vs2.3.9.7/include/linux/vs_cowbl.h
7496--- linux-4.9.82/include/linux/vs_cowbl.h 1970-01-01 00:00:00.000000000 +0000
7497+++ linux-4.9.82-vs2.3.9.7/include/linux/vs_cowbl.h 2018-01-13 22:17:14.000000000 +0000
78865d5b 7498@@ -0,0 +1,48 @@
2380c486
JR
7499+#ifndef _VS_COWBL_H
7500+#define _VS_COWBL_H
7501+
7502+#include <linux/fs.h>
7503+#include <linux/dcache.h>
7504+#include <linux/namei.h>
78865d5b 7505+#include <linux/slab.h>
2380c486
JR
7506+
7507+extern struct dentry *cow_break_link(const char *pathname);
7508+
7509+static inline int cow_check_and_break(struct path *path)
7510+{
7511+ struct inode *inode = path->dentry->d_inode;
7512+ int error = 0;
7513+
7514+ /* do we need this check? */
7515+ if (IS_RDONLY(inode))
7516+ return -EROFS;
7517+
7518+ if (IS_COW(inode)) {
7519+ if (IS_COW_LINK(inode)) {
7520+ struct dentry *new_dentry, *old_dentry = path->dentry;
7521+ char *pp, *buf;
7522+
7523+ buf = kmalloc(PATH_MAX, GFP_KERNEL);
7524+ if (!buf) {
7525+ return -ENOMEM;
7526+ }
7527+ pp = d_path(path, buf, PATH_MAX);
7528+ new_dentry = cow_break_link(pp);
7529+ kfree(buf);
7530+ if (!IS_ERR(new_dentry)) {
7531+ path->dentry = new_dentry;
7532+ dput(old_dentry);
7533+ } else
7534+ error = PTR_ERR(new_dentry);
7535+ } else {
7536+ inode->i_flags &= ~(S_IXUNLINK | S_IMMUTABLE);
7537+ inode->i_ctime = CURRENT_TIME;
7538+ mark_inode_dirty(inode);
7539+ }
7540+ }
7541+ return error;
7542+}
7543+
7544+#else
7545+#warning duplicate inclusion
7546+#endif
cef7ea10
AM
7547diff -NurpP --minimal linux-4.9.82/include/linux/vs_cvirt.h linux-4.9.82-vs2.3.9.7/include/linux/vs_cvirt.h
7548--- linux-4.9.82/include/linux/vs_cvirt.h 1970-01-01 00:00:00.000000000 +0000
7549+++ linux-4.9.82-vs2.3.9.7/include/linux/vs_cvirt.h 2018-01-10 02:50:49.000000000 +0000
2380c486
JR
7550@@ -0,0 +1,50 @@
7551+#ifndef _VS_CVIRT_H
7552+#define _VS_CVIRT_H
7553+
7554+#include "vserver/cvirt.h"
7555+#include "vserver/context.h"
7556+#include "vserver/base.h"
7557+#include "vserver/check.h"
7558+#include "vserver/debug.h"
7559+
7560+
7561+static inline void vx_activate_task(struct task_struct *p)
7562+{
7563+ struct vx_info *vxi;
7564+
7565+ if ((vxi = p->vx_info)) {
7566+ vx_update_load(vxi);
7567+ atomic_inc(&vxi->cvirt.nr_running);
7568+ }
7569+}
7570+
7571+static inline void vx_deactivate_task(struct task_struct *p)
7572+{
7573+ struct vx_info *vxi;
7574+
7575+ if ((vxi = p->vx_info)) {
7576+ vx_update_load(vxi);
7577+ atomic_dec(&vxi->cvirt.nr_running);
7578+ }
7579+}
7580+
7581+static inline void vx_uninterruptible_inc(struct task_struct *p)
7582+{
7583+ struct vx_info *vxi;
7584+
7585+ if ((vxi = p->vx_info))
7586+ atomic_inc(&vxi->cvirt.nr_uninterruptible);
7587+}
7588+
7589+static inline void vx_uninterruptible_dec(struct task_struct *p)
7590+{
7591+ struct vx_info *vxi;
7592+
7593+ if ((vxi = p->vx_info))
7594+ atomic_dec(&vxi->cvirt.nr_uninterruptible);
7595+}
7596+
7597+
7598+#else
7599+#warning duplicate inclusion
7600+#endif
cef7ea10
AM
7601diff -NurpP --minimal linux-4.9.82/include/linux/vs_device.h linux-4.9.82-vs2.3.9.7/include/linux/vs_device.h
7602--- linux-4.9.82/include/linux/vs_device.h 1970-01-01 00:00:00.000000000 +0000
7603+++ linux-4.9.82-vs2.3.9.7/include/linux/vs_device.h 2018-01-10 02:50:49.000000000 +0000
2380c486
JR
7604@@ -0,0 +1,45 @@
7605+#ifndef _VS_DEVICE_H
7606+#define _VS_DEVICE_H
7607+
7608+#include "vserver/base.h"
7609+#include "vserver/device.h"
7610+#include "vserver/debug.h"
7611+
7612+
7613+#ifdef CONFIG_VSERVER_DEVICE
7614+
7615+int vs_map_device(struct vx_info *, dev_t, dev_t *, umode_t);
7616+
7617+#define vs_device_perm(v, d, m, p) \
7618+ ((vs_map_device(current_vx_info(), d, NULL, m) & (p)) == (p))
7619+
7620+#else
7621+
7622+static inline
7623+int vs_map_device(struct vx_info *vxi,
7624+ dev_t device, dev_t *target, umode_t mode)
7625+{
7626+ if (target)
7627+ *target = device;
7628+ return ~0;
7629+}
7630+
7631+#define vs_device_perm(v, d, m, p) ((p) == (p))
7632+
7633+#endif
7634+
7635+
7636+#define vs_map_chrdev(d, t, p) \
7637+ ((vs_map_device(current_vx_info(), d, t, S_IFCHR) & (p)) == (p))
7638+#define vs_map_blkdev(d, t, p) \
7639+ ((vs_map_device(current_vx_info(), d, t, S_IFBLK) & (p)) == (p))
7640+
7641+#define vs_chrdev_perm(d, p) \
7642+ vs_device_perm(current_vx_info(), d, S_IFCHR, p)
7643+#define vs_blkdev_perm(d, p) \
7644+ vs_device_perm(current_vx_info(), d, S_IFBLK, p)
7645+
7646+
7647+#else
7648+#warning duplicate inclusion
7649+#endif
cef7ea10
AM
7650diff -NurpP --minimal linux-4.9.82/include/linux/vs_dlimit.h linux-4.9.82-vs2.3.9.7/include/linux/vs_dlimit.h
7651--- linux-4.9.82/include/linux/vs_dlimit.h 1970-01-01 00:00:00.000000000 +0000
7652+++ linux-4.9.82-vs2.3.9.7/include/linux/vs_dlimit.h 2018-01-10 02:50:49.000000000 +0000
2c8c5bc5 7653@@ -0,0 +1,215 @@
2380c486
JR
7654+#ifndef _VS_DLIMIT_H
7655+#define _VS_DLIMIT_H
7656+
7657+#include <linux/fs.h>
7658+
7659+#include "vserver/dlimit.h"
7660+#include "vserver/base.h"
7661+#include "vserver/debug.h"
7662+
7663+
7664+#define get_dl_info(i) __get_dl_info(i, __FILE__, __LINE__)
7665+
7666+static inline struct dl_info *__get_dl_info(struct dl_info *dli,
7667+ const char *_file, int _line)
7668+{
7669+ if (!dli)
7670+ return NULL;
7671+ vxlprintk(VXD_CBIT(dlim, 4), "get_dl_info(%p[#%d.%d])",
7672+ dli, dli ? dli->dl_tag : 0,
7673+ dli ? atomic_read(&dli->dl_usecnt) : 0,
7674+ _file, _line);
7675+ atomic_inc(&dli->dl_usecnt);
7676+ return dli;
7677+}
7678+
7679+
7680+#define free_dl_info(i) \
7681+ call_rcu(&(i)->dl_rcu, rcu_free_dl_info)
7682+
7683+#define put_dl_info(i) __put_dl_info(i, __FILE__, __LINE__)
7684+
7685+static inline void __put_dl_info(struct dl_info *dli,
7686+ const char *_file, int _line)
7687+{
7688+ if (!dli)
7689+ return;
7690+ vxlprintk(VXD_CBIT(dlim, 4), "put_dl_info(%p[#%d.%d])",
7691+ dli, dli ? dli->dl_tag : 0,
7692+ dli ? atomic_read(&dli->dl_usecnt) : 0,
7693+ _file, _line);
7694+ if (atomic_dec_and_test(&dli->dl_usecnt))
7695+ free_dl_info(dli);
7696+}
7697+
7698+
7699+#define __dlimit_char(d) ((d) ? '*' : ' ')
7700+
7701+static inline int __dl_alloc_space(struct super_block *sb,
61333608 7702+ vtag_t tag, dlsize_t nr, const char *file, int line)
2380c486
JR
7703+{
7704+ struct dl_info *dli = NULL;
7705+ int ret = 0;
7706+
7707+ if (nr == 0)
7708+ goto out;
7709+ dli = locate_dl_info(sb, tag);
7710+ if (!dli)
7711+ goto out;
7712+
7713+ spin_lock(&dli->dl_lock);
7714+ ret = (dli->dl_space_used + nr > dli->dl_space_total);
7715+ if (!ret)
7716+ dli->dl_space_used += nr;
7717+ spin_unlock(&dli->dl_lock);
7718+ put_dl_info(dli);
7719+out:
7720+ vxlprintk(VXD_CBIT(dlim, 1),
7721+ "ALLOC (%p,#%d)%c %lld bytes (%d)",
7722+ sb, tag, __dlimit_char(dli), (long long)nr,
7723+ ret, file, line);
76514441 7724+ return ret ? -ENOSPC : 0;
2380c486
JR
7725+}
7726+
7727+static inline void __dl_free_space(struct super_block *sb,
61333608 7728+ vtag_t tag, dlsize_t nr, const char *_file, int _line)
2380c486
JR
7729+{
7730+ struct dl_info *dli = NULL;
7731+
7732+ if (nr == 0)
7733+ goto out;
7734+ dli = locate_dl_info(sb, tag);
7735+ if (!dli)
7736+ goto out;
7737+
7738+ spin_lock(&dli->dl_lock);
7739+ if (dli->dl_space_used > nr)
7740+ dli->dl_space_used -= nr;
7741+ else
7742+ dli->dl_space_used = 0;
7743+ spin_unlock(&dli->dl_lock);
7744+ put_dl_info(dli);
7745+out:
7746+ vxlprintk(VXD_CBIT(dlim, 1),
7747+ "FREE (%p,#%d)%c %lld bytes",
7748+ sb, tag, __dlimit_char(dli), (long long)nr,
7749+ _file, _line);
7750+}
7751+
7752+static inline int __dl_alloc_inode(struct super_block *sb,
61333608 7753+ vtag_t tag, const char *_file, int _line)
2380c486
JR
7754+{
7755+ struct dl_info *dli;
7756+ int ret = 0;
d337f35e 7757+
2380c486
JR
7758+ dli = locate_dl_info(sb, tag);
7759+ if (!dli)
7760+ goto out;
d337f35e 7761+
2380c486 7762+ spin_lock(&dli->dl_lock);
2c8c5bc5
AM
7763+ dli->dl_inodes_used++;
7764+ ret = (dli->dl_inodes_used > dli->dl_inodes_total);
2380c486
JR
7765+ spin_unlock(&dli->dl_lock);
7766+ put_dl_info(dli);
7767+out:
7768+ vxlprintk(VXD_CBIT(dlim, 0),
7769+ "ALLOC (%p,#%d)%c inode (%d)",
7770+ sb, tag, __dlimit_char(dli), ret, _file, _line);
76514441 7771+ return ret ? -ENOSPC : 0;
2380c486 7772+}
d337f35e 7773+
2380c486 7774+static inline void __dl_free_inode(struct super_block *sb,
61333608 7775+ vtag_t tag, const char *_file, int _line)
d337f35e 7776+{
2380c486
JR
7777+ struct dl_info *dli;
7778+
7779+ dli = locate_dl_info(sb, tag);
7780+ if (!dli)
7781+ goto out;
7782+
7783+ spin_lock(&dli->dl_lock);
7784+ if (dli->dl_inodes_used > 1)
7785+ dli->dl_inodes_used--;
7786+ else
7787+ dli->dl_inodes_used = 0;
7788+ spin_unlock(&dli->dl_lock);
7789+ put_dl_info(dli);
7790+out:
7791+ vxlprintk(VXD_CBIT(dlim, 0),
7792+ "FREE (%p,#%d)%c inode",
7793+ sb, tag, __dlimit_char(dli), _file, _line);
d337f35e
JR
7794+}
7795+
61333608 7796+static inline void __dl_adjust_block(struct super_block *sb, vtag_t tag,
2380c486
JR
7797+ unsigned long long *free_blocks, unsigned long long *root_blocks,
7798+ const char *_file, int _line)
d337f35e 7799+{
2380c486
JR
7800+ struct dl_info *dli;
7801+ uint64_t broot, bfree;
7802+
7803+ dli = locate_dl_info(sb, tag);
7804+ if (!dli)
7805+ return;
7806+
7807+ spin_lock(&dli->dl_lock);
7808+ broot = (dli->dl_space_total -
7809+ (dli->dl_space_total >> 10) * dli->dl_nrlmult)
7810+ >> sb->s_blocksize_bits;
7811+ bfree = (dli->dl_space_total - dli->dl_space_used)
7812+ >> sb->s_blocksize_bits;
7813+ spin_unlock(&dli->dl_lock);
7814+
7815+ vxlprintk(VXD_CBIT(dlim, 2),
7816+ "ADJUST: %lld,%lld on %lld,%lld [mult=%d]",
7817+ (long long)bfree, (long long)broot,
7818+ *free_blocks, *root_blocks, dli->dl_nrlmult,
7819+ _file, _line);
7820+ if (free_blocks) {
7821+ if (*free_blocks > bfree)
7822+ *free_blocks = bfree;
7823+ }
7824+ if (root_blocks) {
7825+ if (*root_blocks > broot)
7826+ *root_blocks = broot;
7827+ }
7828+ put_dl_info(dli);
d337f35e
JR
7829+}
7830+
e22b5178 7831+#define dl_prealloc_space(in, bytes) \
537831f9 7832+ __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 7833+ __FILE__, __LINE__ )
d337f35e 7834+
e22b5178 7835+#define dl_alloc_space(in, bytes) \
537831f9 7836+ __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 7837+ __FILE__, __LINE__ )
d337f35e 7838+
e22b5178 7839+#define dl_reserve_space(in, bytes) \
537831f9 7840+ __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 7841+ __FILE__, __LINE__ )
d337f35e 7842+
e22b5178
AM
7843+#define dl_claim_space(in, bytes) (0)
7844+
7845+#define dl_release_space(in, bytes) \
537831f9 7846+ __dl_free_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 7847+ __FILE__, __LINE__ )
d337f35e 7848+
e22b5178 7849+#define dl_free_space(in, bytes) \
537831f9 7850+ __dl_free_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
e22b5178
AM
7851+ __FILE__, __LINE__ )
7852+
7853+
d337f35e 7854+
e22b5178 7855+#define dl_alloc_inode(in) \
537831f9 7856+ __dl_alloc_inode((in)->i_sb, i_tag_read(in), __FILE__, __LINE__ )
d337f35e 7857+
e22b5178 7858+#define dl_free_inode(in) \
537831f9 7859+ __dl_free_inode((in)->i_sb, i_tag_read(in), __FILE__, __LINE__ )
d337f35e 7860+
d337f35e 7861+
e22b5178 7862+#define dl_adjust_block(sb, tag, fb, rb) \
2380c486 7863+ __dl_adjust_block(sb, tag, fb, rb, __FILE__, __LINE__ )
d337f35e 7864+
d337f35e 7865+
2380c486
JR
7866+#else
7867+#warning duplicate inclusion
7868+#endif
cef7ea10
AM
7869diff -NurpP --minimal linux-4.9.82/include/linux/vs_inet.h linux-4.9.82-vs2.3.9.7/include/linux/vs_inet.h
7870--- linux-4.9.82/include/linux/vs_inet.h 1970-01-01 00:00:00.000000000 +0000
7871+++ linux-4.9.82-vs2.3.9.7/include/linux/vs_inet.h 2018-01-10 02:50:49.000000000 +0000
5cb1760b 7872@@ -0,0 +1,364 @@
d33d7b00
AM
7873+#ifndef _VS_INET_H
7874+#define _VS_INET_H
d337f35e 7875+
d33d7b00
AM
7876+#include "vserver/base.h"
7877+#include "vserver/network.h"
7878+#include "vserver/debug.h"
d337f35e 7879+
d33d7b00 7880+#define IPI_LOOPBACK htonl(INADDR_LOOPBACK)
d337f35e 7881+
d33d7b00
AM
7882+#define NXAV4(a) NIPQUAD((a)->ip[0]), NIPQUAD((a)->ip[1]), \
7883+ NIPQUAD((a)->mask), (a)->type
7884+#define NXAV4_FMT "[" NIPQUAD_FMT "-" NIPQUAD_FMT "/" NIPQUAD_FMT ":%04x]"
d337f35e 7885+
d33d7b00
AM
7886+#define NIPQUAD(addr) \
7887+ ((unsigned char *)&addr)[0], \
7888+ ((unsigned char *)&addr)[1], \
7889+ ((unsigned char *)&addr)[2], \
7890+ ((unsigned char *)&addr)[3]
d337f35e 7891+
d33d7b00 7892+#define NIPQUAD_FMT "%u.%u.%u.%u"
d337f35e 7893+
d337f35e 7894+
d33d7b00
AM
7895+static inline
7896+int v4_addr_match(struct nx_addr_v4 *nxa, __be32 addr, uint16_t tmask)
7897+{
7898+ __be32 ip = nxa->ip[0].s_addr;
7899+ __be32 mask = nxa->mask.s_addr;
7900+ __be32 bcast = ip | ~mask;
7901+ int ret = 0;
d337f35e 7902+
d33d7b00
AM
7903+ switch (nxa->type & tmask) {
7904+ case NXA_TYPE_MASK:
7905+ ret = (ip == (addr & mask));
7906+ break;
7907+ case NXA_TYPE_ADDR:
7908+ ret = 3;
7909+ if (addr == ip)
7910+ break;
7911+ /* fall through to broadcast */
7912+ case NXA_MOD_BCAST:
7913+ ret = ((tmask & NXA_MOD_BCAST) && (addr == bcast));
7914+ break;
7915+ case NXA_TYPE_RANGE:
7916+ ret = ((nxa->ip[0].s_addr <= addr) &&
7917+ (nxa->ip[1].s_addr > addr));
7918+ break;
7919+ case NXA_TYPE_ANY:
7920+ ret = 2;
7921+ break;
7922+ }
d337f35e 7923+
d33d7b00
AM
7924+ vxdprintk(VXD_CBIT(net, 0),
7925+ "v4_addr_match(%p" NXAV4_FMT "," NIPQUAD_FMT ",%04x) = %d",
7926+ nxa, NXAV4(nxa), NIPQUAD(addr), tmask, ret);
7927+ return ret;
7928+}
d337f35e 7929+
d33d7b00
AM
7930+static inline
7931+int v4_addr_in_nx_info(struct nx_info *nxi, __be32 addr, uint16_t tmask)
7932+{
7933+ struct nx_addr_v4 *nxa;
7a9e40b8 7934+ unsigned long irqflags;
d33d7b00 7935+ int ret = 1;
d337f35e 7936+
d33d7b00
AM
7937+ if (!nxi)
7938+ goto out;
d337f35e 7939+
d33d7b00
AM
7940+ ret = 2;
7941+ /* allow 127.0.0.1 when remapping lback */
7942+ if ((tmask & NXA_LOOPBACK) &&
7943+ (addr == IPI_LOOPBACK) &&
7944+ nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
7945+ goto out;
7946+ ret = 3;
7947+ /* check for lback address */
7948+ if ((tmask & NXA_MOD_LBACK) &&
7949+ (nxi->v4_lback.s_addr == addr))
7950+ goto out;
7951+ ret = 4;
7952+ /* check for broadcast address */
7953+ if ((tmask & NXA_MOD_BCAST) &&
7954+ (nxi->v4_bcast.s_addr == addr))
7955+ goto out;
7956+ ret = 5;
4bf69007 7957+
d33d7b00 7958+ /* check for v4 addresses */
7a9e40b8 7959+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
d33d7b00
AM
7960+ for (nxa = &nxi->v4; nxa; nxa = nxa->next)
7961+ if (v4_addr_match(nxa, addr, tmask))
4bf69007 7962+ goto out_unlock;
d33d7b00 7963+ ret = 0;
4bf69007 7964+out_unlock:
7a9e40b8 7965+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
d33d7b00
AM
7966+out:
7967+ vxdprintk(VXD_CBIT(net, 0),
7968+ "v4_addr_in_nx_info(%p[#%u]," NIPQUAD_FMT ",%04x) = %d",
7969+ nxi, nxi ? nxi->nx_id : 0, NIPQUAD(addr), tmask, ret);
7970+ return ret;
7971+}
d337f35e 7972+
d33d7b00
AM
7973+static inline
7974+int v4_nx_addr_match(struct nx_addr_v4 *nxa, struct nx_addr_v4 *addr, uint16_t mask)
7975+{
7976+ /* FIXME: needs full range checks */
7977+ return v4_addr_match(nxa, addr->ip[0].s_addr, mask);
7978+}
d337f35e 7979+
d33d7b00
AM
7980+static inline
7981+int v4_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v4 *nxa, uint16_t mask)
7982+{
7983+ struct nx_addr_v4 *ptr;
7a9e40b8 7984+ unsigned long irqflags;
4bf69007 7985+ int ret = 1;
d337f35e 7986+
7a9e40b8 7987+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
d33d7b00
AM
7988+ for (ptr = &nxi->v4; ptr; ptr = ptr->next)
7989+ if (v4_nx_addr_match(ptr, nxa, mask))
4bf69007
AM
7990+ goto out_unlock;
7991+ ret = 0;
7992+out_unlock:
7a9e40b8 7993+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007 7994+ return ret;
d33d7b00 7995+}
d337f35e 7996+
d33d7b00 7997+#include <net/inet_sock.h>
d337f35e 7998+
d33d7b00
AM
7999+/*
8000+ * Check if a given address matches for a socket
8001+ *
8002+ * nxi: the socket's nx_info if any
8003+ * addr: to be verified address
8004+ */
8005+static inline
8006+int v4_sock_addr_match (
8007+ struct nx_info *nxi,
8008+ struct inet_sock *inet,
8009+ __be32 addr)
8010+{
8011+ __be32 saddr = inet->inet_rcv_saddr;
8012+ __be32 bcast = nxi ? nxi->v4_bcast.s_addr : INADDR_BROADCAST;
d337f35e 8013+
d33d7b00
AM
8014+ if (addr && (saddr == addr || bcast == addr))
8015+ return 1;
8016+ if (!saddr)
8017+ return v4_addr_in_nx_info(nxi, addr, NXA_MASK_BIND);
8018+ return 0;
8019+}
d337f35e 8020+
d337f35e 8021+
d33d7b00 8022+/* inet related checks and helpers */
d337f35e
JR
8023+
8024+
d33d7b00
AM
8025+struct in_ifaddr;
8026+struct net_device;
8027+struct sock;
d337f35e 8028+
d33d7b00 8029+#ifdef CONFIG_INET
d337f35e 8030+
d33d7b00
AM
8031+#include <linux/netdevice.h>
8032+#include <linux/inetdevice.h>
8033+#include <net/inet_sock.h>
8034+#include <net/inet_timewait_sock.h>
d337f35e 8035+
d337f35e 8036+
d33d7b00
AM
8037+int dev_in_nx_info(struct net_device *, struct nx_info *);
8038+int v4_dev_in_nx_info(struct net_device *, struct nx_info *);
8039+int nx_v4_addr_conflict(struct nx_info *, struct nx_info *);
d337f35e 8040+
d337f35e 8041+
d33d7b00
AM
8042+/*
8043+ * check if address is covered by socket
8044+ *
8045+ * sk: the socket to check against
8046+ * addr: the address in question (must be != 0)
8047+ */
d337f35e 8048+
d33d7b00
AM
8049+static inline
8050+int __v4_addr_match_socket(const struct sock *sk, struct nx_addr_v4 *nxa)
8051+{
8052+ struct nx_info *nxi = sk->sk_nx_info;
c2e5f7c8 8053+ __be32 saddr = sk->sk_rcv_saddr;
d337f35e 8054+
d33d7b00
AM
8055+ vxdprintk(VXD_CBIT(net, 5),
8056+ "__v4_addr_in_socket(%p," NXAV4_FMT ") %p:" NIPQUAD_FMT " %p;%lx",
8057+ sk, NXAV4(nxa), nxi, NIPQUAD(saddr), sk->sk_socket,
8058+ (sk->sk_socket?sk->sk_socket->flags:0));
d337f35e 8059+
d33d7b00
AM
8060+ if (saddr) { /* direct address match */
8061+ return v4_addr_match(nxa, saddr, -1);
8062+ } else if (nxi) { /* match against nx_info */
8063+ return v4_nx_addr_in_nx_info(nxi, nxa, -1);
8064+ } else { /* unrestricted any socket */
8065+ return 1;
8066+ }
8067+}
d337f35e
JR
8068+
8069+
d337f35e 8070+
d33d7b00
AM
8071+static inline
8072+int nx_dev_visible(struct nx_info *nxi, struct net_device *dev)
8073+{
8074+ vxdprintk(VXD_CBIT(net, 1),
8075+ "nx_dev_visible(%p[#%u],%p " VS_Q("%s") ") %d",
8076+ nxi, nxi ? nxi->nx_id : 0, dev, dev->name,
8077+ nxi ? dev_in_nx_info(dev, nxi) : 0);
d337f35e 8078+
d33d7b00
AM
8079+ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
8080+ return 1;
8081+ if (dev_in_nx_info(dev, nxi))
8082+ return 1;
8083+ return 0;
8084+}
d337f35e
JR
8085+
8086+
d33d7b00
AM
8087+static inline
8088+int v4_ifa_in_nx_info(struct in_ifaddr *ifa, struct nx_info *nxi)
8089+{
8090+ if (!nxi)
8091+ return 1;
8092+ if (!ifa)
8093+ return 0;
8094+ return v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW);
8095+}
d337f35e 8096+
d33d7b00
AM
8097+static inline
8098+int nx_v4_ifa_visible(struct nx_info *nxi, struct in_ifaddr *ifa)
8099+{
8100+ vxdprintk(VXD_CBIT(net, 1), "nx_v4_ifa_visible(%p[#%u],%p) %d",
8101+ nxi, nxi ? nxi->nx_id : 0, ifa,
8102+ nxi ? v4_ifa_in_nx_info(ifa, nxi) : 0);
d337f35e 8103+
d33d7b00
AM
8104+ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
8105+ return 1;
8106+ if (v4_ifa_in_nx_info(ifa, nxi))
8107+ return 1;
8108+ return 0;
8109+}
d337f35e 8110+
d337f35e 8111+
d33d7b00
AM
8112+struct nx_v4_sock_addr {
8113+ __be32 saddr; /* Address used for validation */
8114+ __be32 baddr; /* Address used for socket bind */
8115+};
d337f35e 8116+
d33d7b00
AM
8117+static inline
8118+int v4_map_sock_addr(struct inet_sock *inet, struct sockaddr_in *addr,
8119+ struct nx_v4_sock_addr *nsa)
8120+{
8121+ struct sock *sk = &inet->sk;
8122+ struct nx_info *nxi = sk->sk_nx_info;
8123+ __be32 saddr = addr->sin_addr.s_addr;
8124+ __be32 baddr = saddr;
d337f35e 8125+
d33d7b00
AM
8126+ vxdprintk(VXD_CBIT(net, 3),
8127+ "inet_bind(%p)* %p,%p;%lx " NIPQUAD_FMT,
8128+ sk, sk->sk_nx_info, sk->sk_socket,
8129+ (sk->sk_socket ? sk->sk_socket->flags : 0),
8130+ NIPQUAD(saddr));
d337f35e 8131+
d33d7b00
AM
8132+ if (nxi) {
8133+ if (saddr == INADDR_ANY) {
8134+ if (nx_info_flags(nxi, NXF_SINGLE_IP, 0))
8135+ baddr = nxi->v4.ip[0].s_addr;
8136+ } else if (saddr == IPI_LOOPBACK) {
8137+ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
8138+ baddr = nxi->v4_lback.s_addr;
9795bf04
AM
8139+ } else if (!ipv4_is_multicast(saddr) ||
8140+ !nx_info_ncaps(nxi, NXC_MULTICAST)) {
8141+ /* normal address bind */
d33d7b00
AM
8142+ if (!v4_addr_in_nx_info(nxi, saddr, NXA_MASK_BIND))
8143+ return -EADDRNOTAVAIL;
8144+ }
8145+ }
d337f35e 8146+
d33d7b00
AM
8147+ vxdprintk(VXD_CBIT(net, 3),
8148+ "inet_bind(%p) " NIPQUAD_FMT ", " NIPQUAD_FMT,
8149+ sk, NIPQUAD(saddr), NIPQUAD(baddr));
d337f35e 8150+
d33d7b00
AM
8151+ nsa->saddr = saddr;
8152+ nsa->baddr = baddr;
8153+ return 0;
8154+}
d337f35e 8155+
d33d7b00
AM
8156+static inline
8157+void v4_set_sock_addr(struct inet_sock *inet, struct nx_v4_sock_addr *nsa)
8158+{
8159+ inet->inet_saddr = nsa->baddr;
8160+ inet->inet_rcv_saddr = nsa->baddr;
8161+}
d337f35e 8162+
d337f35e 8163+
d33d7b00
AM
8164+/*
8165+ * helper to simplify inet_lookup_listener
8166+ *
8167+ * nxi: the socket's nx_info if any
8168+ * addr: to be verified address
8169+ * saddr: socket address
8170+ */
8171+static inline int v4_inet_addr_match (
8172+ struct nx_info *nxi,
8173+ __be32 addr,
8174+ __be32 saddr)
8175+{
8176+ if (addr && (saddr == addr))
8177+ return 1;
8178+ if (!saddr)
8179+ return nxi ? v4_addr_in_nx_info(nxi, addr, NXA_MASK_BIND) : 1;
8180+ return 0;
8181+}
d337f35e 8182+
d33d7b00
AM
8183+static inline __be32 nx_map_sock_lback(struct nx_info *nxi, __be32 addr)
8184+{
8185+ if (nx_info_flags(nxi, NXF_HIDE_LBACK, 0) &&
8186+ (addr == nxi->v4_lback.s_addr))
8187+ return IPI_LOOPBACK;
8188+ return addr;
8189+}
d337f35e 8190+
d33d7b00
AM
8191+static inline
8192+int nx_info_has_v4(struct nx_info *nxi)
8193+{
8194+ if (!nxi)
8195+ return 1;
8196+ if (NX_IPV4(nxi))
8197+ return 1;
8198+ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
8199+ return 1;
8200+ return 0;
8201+}
d337f35e 8202+
d33d7b00 8203+#else /* CONFIG_INET */
d337f35e 8204+
d33d7b00
AM
8205+static inline
8206+int nx_dev_visible(struct nx_info *n, struct net_device *d)
8207+{
8208+ return 1;
8209+}
d337f35e 8210+
d33d7b00
AM
8211+static inline
8212+int nx_v4_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s)
8213+{
8214+ return 1;
8215+}
d337f35e 8216+
d33d7b00
AM
8217+static inline
8218+int v4_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
8219+{
8220+ return 1;
8221+}
d337f35e 8222+
d33d7b00
AM
8223+static inline
8224+int nx_info_has_v4(struct nx_info *nxi)
8225+{
8226+ return 0;
8227+}
d337f35e 8228+
d33d7b00 8229+#endif /* CONFIG_INET */
d337f35e 8230+
d33d7b00
AM
8231+#define current_nx_info_has_v4() \
8232+ nx_info_has_v4(current_nx_info())
d337f35e 8233+
d33d7b00
AM
8234+#else
8235+// #warning duplicate inclusion
3bac966d 8236+#endif
cef7ea10
AM
8237diff -NurpP --minimal linux-4.9.82/include/linux/vs_inet6.h linux-4.9.82-vs2.3.9.7/include/linux/vs_inet6.h
8238--- linux-4.9.82/include/linux/vs_inet6.h 1970-01-01 00:00:00.000000000 +0000
8239+++ linux-4.9.82-vs2.3.9.7/include/linux/vs_inet6.h 2018-01-16 10:02:29.000000000 +0000
369dbd59 8240@@ -0,0 +1,264 @@
d33d7b00
AM
8241+#ifndef _VS_INET6_H
8242+#define _VS_INET6_H
4a036bed 8243+
d33d7b00
AM
8244+#include "vserver/base.h"
8245+#include "vserver/network.h"
8246+#include "vserver/debug.h"
d337f35e 8247+
d33d7b00 8248+#include <net/ipv6.h>
d337f35e 8249+
d33d7b00
AM
8250+#define NXAV6(a) &(a)->ip, &(a)->mask, (a)->prefix, (a)->type
8251+#define NXAV6_FMT "[%pI6/%pI6/%d:%04x]"
7e46296a 8252+
7e46296a 8253+
d33d7b00 8254+#ifdef CONFIG_IPV6
7e46296a 8255+
d33d7b00
AM
8256+static inline
8257+int v6_addr_match(struct nx_addr_v6 *nxa,
8258+ const struct in6_addr *addr, uint16_t mask)
8259+{
8260+ int ret = 0;
7e46296a 8261+
d33d7b00
AM
8262+ switch (nxa->type & mask) {
8263+ case NXA_TYPE_MASK:
8264+ ret = ipv6_masked_addr_cmp(&nxa->ip, &nxa->mask, addr);
8265+ break;
8266+ case NXA_TYPE_ADDR:
8267+ ret = ipv6_addr_equal(&nxa->ip, addr);
8268+ break;
8269+ case NXA_TYPE_ANY:
8270+ ret = 1;
8271+ break;
8272+ }
8273+ vxdprintk(VXD_CBIT(net, 0),
8274+ "v6_addr_match(%p" NXAV6_FMT ",%pI6,%04x) = %d",
8275+ nxa, NXAV6(nxa), addr, mask, ret);
8276+ return ret;
8277+}
7e46296a 8278+
d33d7b00
AM
8279+static inline
8280+int v6_addr_in_nx_info(struct nx_info *nxi,
8281+ const struct in6_addr *addr, uint16_t mask)
8282+{
8283+ struct nx_addr_v6 *nxa;
7a9e40b8 8284+ unsigned long irqflags;
d33d7b00 8285+ int ret = 1;
d337f35e 8286+
d33d7b00
AM
8287+ if (!nxi)
8288+ goto out;
4bf69007 8289+
7a9e40b8 8290+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
d33d7b00
AM
8291+ for (nxa = &nxi->v6; nxa; nxa = nxa->next)
8292+ if (v6_addr_match(nxa, addr, mask))
4bf69007 8293+ goto out_unlock;
d33d7b00 8294+ ret = 0;
4bf69007 8295+out_unlock:
7a9e40b8 8296+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
d33d7b00
AM
8297+out:
8298+ vxdprintk(VXD_CBIT(net, 0),
8299+ "v6_addr_in_nx_info(%p[#%u],%pI6,%04x) = %d",
8300+ nxi, nxi ? nxi->nx_id : 0, addr, mask, ret);
8301+ return ret;
8302+}
d337f35e 8303+
d33d7b00
AM
8304+static inline
8305+int v6_nx_addr_match(struct nx_addr_v6 *nxa, struct nx_addr_v6 *addr, uint16_t mask)
8306+{
8307+ /* FIXME: needs full range checks */
8308+ return v6_addr_match(nxa, &addr->ip, mask);
8309+}
d337f35e 8310+
d33d7b00
AM
8311+static inline
8312+int v6_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v6 *nxa, uint16_t mask)
8313+{
8314+ struct nx_addr_v6 *ptr;
7a9e40b8 8315+ unsigned long irqflags;
4bf69007 8316+ int ret = 1;
d337f35e 8317+
7a9e40b8 8318+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
d33d7b00
AM
8319+ for (ptr = &nxi->v6; ptr; ptr = ptr->next)
8320+ if (v6_nx_addr_match(ptr, nxa, mask))
4bf69007
AM
8321+ goto out_unlock;
8322+ ret = 0;
8323+out_unlock:
7a9e40b8 8324+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007 8325+ return ret;
d33d7b00 8326+}
d337f35e 8327+
d337f35e 8328+
d33d7b00
AM
8329+/*
8330+ * Check if a given address matches for a socket
8331+ *
8332+ * nxi: the socket's nx_info if any
8333+ * addr: to be verified address
8334+ */
8335+static inline
8336+int v6_sock_addr_match (
8337+ struct nx_info *nxi,
8338+ struct inet_sock *inet,
8339+ struct in6_addr *addr)
8340+{
8341+ struct sock *sk = &inet->sk;
c2e5f7c8 8342+ const struct in6_addr *saddr = inet6_rcv_saddr(sk);
d337f35e 8343+
d33d7b00
AM
8344+ if (!ipv6_addr_any(addr) &&
8345+ ipv6_addr_equal(saddr, addr))
8346+ return 1;
8347+ if (ipv6_addr_any(saddr))
8348+ return v6_addr_in_nx_info(nxi, addr, -1);
8349+ return 0;
8350+}
d337f35e 8351+
d33d7b00
AM
8352+/*
8353+ * check if address is covered by socket
8354+ *
8355+ * sk: the socket to check against
8356+ * addr: the address in question (must be != 0)
8357+ */
d337f35e 8358+
d33d7b00
AM
8359+static inline
8360+int __v6_addr_match_socket(const struct sock *sk, struct nx_addr_v6 *nxa)
8361+{
8362+ struct nx_info *nxi = sk->sk_nx_info;
c2e5f7c8 8363+ const struct in6_addr *saddr = inet6_rcv_saddr(sk);
d337f35e 8364+
d33d7b00
AM
8365+ vxdprintk(VXD_CBIT(net, 5),
8366+ "__v6_addr_in_socket(%p," NXAV6_FMT ") %p:%pI6 %p;%lx",
8367+ sk, NXAV6(nxa), nxi, saddr, sk->sk_socket,
8368+ (sk->sk_socket?sk->sk_socket->flags:0));
d337f35e 8369+
d33d7b00
AM
8370+ if (!ipv6_addr_any(saddr)) { /* direct address match */
8371+ return v6_addr_match(nxa, saddr, -1);
8372+ } else if (nxi) { /* match against nx_info */
8373+ return v6_nx_addr_in_nx_info(nxi, nxa, -1);
8374+ } else { /* unrestricted any socket */
8375+ return 1;
8376+ }
8377+}
d337f35e 8378+
d337f35e 8379+
d33d7b00 8380+/* inet related checks and helpers */
d337f35e 8381+
d337f35e 8382+
d33d7b00
AM
8383+struct in_ifaddr;
8384+struct net_device;
8385+struct sock;
d337f35e
JR
8386+
8387+
d33d7b00
AM
8388+#include <linux/netdevice.h>
8389+#include <linux/inetdevice.h>
8390+#include <net/inet_timewait_sock.h>
d337f35e 8391+
d337f35e 8392+
d33d7b00
AM
8393+int dev_in_nx_info(struct net_device *, struct nx_info *);
8394+int v6_dev_in_nx_info(struct net_device *, struct nx_info *);
8395+int nx_v6_addr_conflict(struct nx_info *, struct nx_info *);
d337f35e
JR
8396+
8397+
3bac966d 8398+
d33d7b00
AM
8399+static inline
8400+int v6_ifa_in_nx_info(struct inet6_ifaddr *ifa, struct nx_info *nxi)
adc1caaa 8401+{
d33d7b00
AM
8402+ if (!nxi)
8403+ return 1;
8404+ if (!ifa)
8405+ return 0;
8406+ return v6_addr_in_nx_info(nxi, &ifa->addr, -1);
8407+}
d337f35e 8408+
d33d7b00
AM
8409+static inline
8410+int nx_v6_ifa_visible(struct nx_info *nxi, struct inet6_ifaddr *ifa)
8411+{
8412+ vxdprintk(VXD_CBIT(net, 1), "nx_v6_ifa_visible(%p[#%u],%p) %d",
8413+ nxi, nxi ? nxi->nx_id : 0, ifa,
8414+ nxi ? v6_ifa_in_nx_info(ifa, nxi) : 0);
d337f35e 8415+
d33d7b00
AM
8416+ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
8417+ return 1;
8418+ if (v6_ifa_in_nx_info(ifa, nxi))
8419+ return 1;
8420+ return 0;
adc1caaa 8421+}
d337f35e 8422+
d337f35e 8423+
d33d7b00
AM
8424+struct nx_v6_sock_addr {
8425+ struct in6_addr saddr; /* Address used for validation */
8426+ struct in6_addr baddr; /* Address used for socket bind */
8427+};
8428+
8429+static inline
8430+int v6_map_sock_addr(struct inet_sock *inet, struct sockaddr_in6 *addr,
8431+ struct nx_v6_sock_addr *nsa)
8432+{
8433+ // struct sock *sk = &inet->sk;
8434+ // struct nx_info *nxi = sk->sk_nx_info;
8435+ struct in6_addr saddr = addr->sin6_addr;
8436+ struct in6_addr baddr = saddr;
3bac966d 8437+
d33d7b00
AM
8438+ nsa->saddr = saddr;
8439+ nsa->baddr = baddr;
8440+ return 0;
8441+}
3bac966d 8442+
d33d7b00
AM
8443+static inline
8444+void v6_set_sock_addr(struct inet_sock *inet, struct nx_v6_sock_addr *nsa)
8445+{
8446+ // struct sock *sk = &inet->sk;
8447+ // struct in6_addr *saddr = inet6_rcv_saddr(sk);
3bac966d 8448+
d33d7b00
AM
8449+ // *saddr = nsa->baddr;
8450+ // inet->inet_saddr = nsa->baddr;
8451+}
3bac966d 8452+
d33d7b00
AM
8453+static inline
8454+int nx_info_has_v6(struct nx_info *nxi)
8455+{
8456+ if (!nxi)
8457+ return 1;
8458+ if (NX_IPV6(nxi))
8459+ return 1;
8460+ return 0;
8461+}
3bac966d 8462+
d33d7b00 8463+#else /* CONFIG_IPV6 */
d337f35e 8464+
2380c486 8465+static inline
d33d7b00 8466+int nx_v6_dev_visible(struct nx_info *n, struct net_device *d)
2380c486 8467+{
d33d7b00 8468+ return 1;
d337f35e
JR
8469+}
8470+
3bac966d 8471+
adc1caaa 8472+static inline
d33d7b00 8473+int nx_v6_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s)
adc1caaa 8474+{
d33d7b00 8475+ return 1;
adc1caaa 8476+}
2380c486 8477+
d33d7b00
AM
8478+static inline
8479+int v6_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
8480+{
8481+ return 1;
8482+}
8483+
8484+static inline
8485+int nx_info_has_v6(struct nx_info *nxi)
8486+{
8487+ return 0;
8488+}
2380c486 8489+
369dbd59
AM
8490+static inline
8491+int v6_addr_in_nx_info(struct nx_info *nxi,
8492+ const struct in6_addr *addr, uint16_t mask)
8493+{
8494+ return 0;
8495+}
8496+
d33d7b00 8497+#endif /* CONFIG_IPV6 */
d337f35e 8498+
d33d7b00
AM
8499+#define current_nx_info_has_v6() \
8500+ nx_info_has_v6(current_nx_info())
3bac966d 8501+
d337f35e 8502+#else
d33d7b00 8503+#warning duplicate inclusion
d337f35e 8504+#endif
cef7ea10
AM
8505diff -NurpP --minimal linux-4.9.82/include/linux/vs_limit.h linux-4.9.82-vs2.3.9.7/include/linux/vs_limit.h
8506--- linux-4.9.82/include/linux/vs_limit.h 1970-01-01 00:00:00.000000000 +0000
8507+++ linux-4.9.82-vs2.3.9.7/include/linux/vs_limit.h 2018-01-10 02:50:49.000000000 +0000
d33d7b00
AM
8508@@ -0,0 +1,140 @@
8509+#ifndef _VS_LIMIT_H
8510+#define _VS_LIMIT_H
d337f35e 8511+
d33d7b00
AM
8512+#include "vserver/limit.h"
8513+#include "vserver/base.h"
8514+#include "vserver/context.h"
8515+#include "vserver/debug.h"
8516+#include "vserver/context.h"
8517+#include "vserver/limit_int.h"
d337f35e
JR
8518+
8519+
d33d7b00
AM
8520+#define vx_acc_cres(v, d, p, r) \
8521+ __vx_acc_cres(v, r, d, p, __FILE__, __LINE__)
d337f35e 8522+
d33d7b00
AM
8523+#define vx_acc_cres_cond(x, d, p, r) \
8524+ __vx_acc_cres(((x) == vx_current_xid()) ? current_vx_info() : 0, \
8525+ r, d, p, __FILE__, __LINE__)
d337f35e
JR
8526+
8527+
d33d7b00
AM
8528+#define vx_add_cres(v, a, p, r) \
8529+ __vx_add_cres(v, r, a, p, __FILE__, __LINE__)
8530+#define vx_sub_cres(v, a, p, r) vx_add_cres(v, -(a), p, r)
d337f35e 8531+
d33d7b00
AM
8532+#define vx_add_cres_cond(x, a, p, r) \
8533+ __vx_add_cres(((x) == vx_current_xid()) ? current_vx_info() : 0, \
8534+ r, a, p, __FILE__, __LINE__)
8535+#define vx_sub_cres_cond(x, a, p, r) vx_add_cres_cond(x, -(a), p, r)
d337f35e 8536+
d337f35e 8537+
d33d7b00 8538+/* process and file limits */
d337f35e 8539+
d33d7b00
AM
8540+#define vx_nproc_inc(p) \
8541+ vx_acc_cres((p)->vx_info, 1, p, RLIMIT_NPROC)
d337f35e 8542+
d33d7b00
AM
8543+#define vx_nproc_dec(p) \
8544+ vx_acc_cres((p)->vx_info,-1, p, RLIMIT_NPROC)
d337f35e 8545+
d33d7b00
AM
8546+#define vx_files_inc(f) \
8547+ vx_acc_cres_cond((f)->f_xid, 1, f, RLIMIT_NOFILE)
d337f35e 8548+
d33d7b00
AM
8549+#define vx_files_dec(f) \
8550+ vx_acc_cres_cond((f)->f_xid,-1, f, RLIMIT_NOFILE)
d337f35e 8551+
d33d7b00
AM
8552+#define vx_locks_inc(l) \
8553+ vx_acc_cres_cond((l)->fl_xid, 1, l, RLIMIT_LOCKS)
d337f35e 8554+
d33d7b00
AM
8555+#define vx_locks_dec(l) \
8556+ vx_acc_cres_cond((l)->fl_xid,-1, l, RLIMIT_LOCKS)
d337f35e 8557+
d33d7b00
AM
8558+#define vx_openfd_inc(f) \
8559+ vx_acc_cres(current_vx_info(), 1, (void *)(long)(f), VLIMIT_OPENFD)
d337f35e 8560+
d33d7b00
AM
8561+#define vx_openfd_dec(f) \
8562+ vx_acc_cres(current_vx_info(),-1, (void *)(long)(f), VLIMIT_OPENFD)
d337f35e 8563+
d337f35e 8564+
d33d7b00
AM
8565+#define vx_cres_avail(v, n, r) \
8566+ __vx_cres_avail(v, r, n, __FILE__, __LINE__)
d337f35e 8567+
d337f35e 8568+
d33d7b00
AM
8569+#define vx_nproc_avail(n) \
8570+ vx_cres_avail(current_vx_info(), n, RLIMIT_NPROC)
d337f35e 8571+
d33d7b00
AM
8572+#define vx_files_avail(n) \
8573+ vx_cres_avail(current_vx_info(), n, RLIMIT_NOFILE)
d337f35e 8574+
d33d7b00
AM
8575+#define vx_locks_avail(n) \
8576+ vx_cres_avail(current_vx_info(), n, RLIMIT_LOCKS)
d337f35e 8577+
d33d7b00
AM
8578+#define vx_openfd_avail(n) \
8579+ vx_cres_avail(current_vx_info(), n, VLIMIT_OPENFD)
d337f35e 8580+
d337f35e 8581+
d33d7b00 8582+/* dentry limits */
d337f35e 8583+
d33d7b00 8584+#define vx_dentry_inc(d) do { \
c2e5f7c8 8585+ if (d_count(d) == 1) \
d33d7b00
AM
8586+ vx_acc_cres(current_vx_info(), 1, d, VLIMIT_DENTRY); \
8587+ } while (0)
d337f35e 8588+
d33d7b00 8589+#define vx_dentry_dec(d) do { \
c2e5f7c8 8590+ if (d_count(d) == 0) \
d33d7b00
AM
8591+ vx_acc_cres(current_vx_info(),-1, d, VLIMIT_DENTRY); \
8592+ } while (0)
d337f35e 8593+
d33d7b00
AM
8594+#define vx_dentry_avail(n) \
8595+ vx_cres_avail(current_vx_info(), n, VLIMIT_DENTRY)
d337f35e 8596+
d337f35e 8597+
d33d7b00 8598+/* socket limits */
d337f35e 8599+
d33d7b00
AM
8600+#define vx_sock_inc(s) \
8601+ vx_acc_cres((s)->sk_vx_info, 1, s, VLIMIT_NSOCK)
d337f35e 8602+
d33d7b00
AM
8603+#define vx_sock_dec(s) \
8604+ vx_acc_cres((s)->sk_vx_info,-1, s, VLIMIT_NSOCK)
d337f35e 8605+
d33d7b00
AM
8606+#define vx_sock_avail(n) \
8607+ vx_cres_avail(current_vx_info(), n, VLIMIT_NSOCK)
d337f35e 8608+
d337f35e 8609+
d33d7b00 8610+/* ipc resource limits */
d337f35e 8611+
d33d7b00
AM
8612+#define vx_ipcmsg_add(v, u, a) \
8613+ vx_add_cres(v, a, u, RLIMIT_MSGQUEUE)
d337f35e 8614+
d33d7b00
AM
8615+#define vx_ipcmsg_sub(v, u, a) \
8616+ vx_sub_cres(v, a, u, RLIMIT_MSGQUEUE)
d337f35e 8617+
d33d7b00
AM
8618+#define vx_ipcmsg_avail(v, a) \
8619+ vx_cres_avail(v, a, RLIMIT_MSGQUEUE)
d337f35e 8620+
d337f35e 8621+
d33d7b00
AM
8622+#define vx_ipcshm_add(v, k, a) \
8623+ vx_add_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
d337f35e 8624+
d33d7b00
AM
8625+#define vx_ipcshm_sub(v, k, a) \
8626+ vx_sub_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
d337f35e 8627+
d33d7b00
AM
8628+#define vx_ipcshm_avail(v, a) \
8629+ vx_cres_avail(v, a, VLIMIT_SHMEM)
d337f35e
JR
8630+
8631+
d33d7b00
AM
8632+#define vx_semary_inc(a) \
8633+ vx_acc_cres(current_vx_info(), 1, a, VLIMIT_SEMARY)
d337f35e 8634+
d33d7b00
AM
8635+#define vx_semary_dec(a) \
8636+ vx_acc_cres(current_vx_info(), -1, a, VLIMIT_SEMARY)
d337f35e 8637+
d337f35e 8638+
d33d7b00
AM
8639+#define vx_nsems_add(a,n) \
8640+ vx_add_cres(current_vx_info(), n, a, VLIMIT_NSEMS)
d337f35e 8641+
d33d7b00
AM
8642+#define vx_nsems_sub(a,n) \
8643+ vx_sub_cres(current_vx_info(), n, a, VLIMIT_NSEMS)
d337f35e
JR
8644+
8645+
d33d7b00
AM
8646+#else
8647+#warning duplicate inclusion
8648+#endif
cef7ea10
AM
8649diff -NurpP --minimal linux-4.9.82/include/linux/vs_network.h linux-4.9.82-vs2.3.9.7/include/linux/vs_network.h
8650--- linux-4.9.82/include/linux/vs_network.h 1970-01-01 00:00:00.000000000 +0000
8651+++ linux-4.9.82-vs2.3.9.7/include/linux/vs_network.h 2018-01-10 02:50:49.000000000 +0000
d33d7b00
AM
8652@@ -0,0 +1,169 @@
8653+#ifndef _NX_VS_NETWORK_H
8654+#define _NX_VS_NETWORK_H
7e46296a 8655+
d33d7b00
AM
8656+#include "vserver/context.h"
8657+#include "vserver/network.h"
8658+#include "vserver/base.h"
8659+#include "vserver/check.h"
8660+#include "vserver/debug.h"
2380c486 8661+
d33d7b00 8662+#include <linux/sched.h>
2380c486 8663+
2380c486 8664+
d33d7b00 8665+#define get_nx_info(i) __get_nx_info(i, __FILE__, __LINE__)
2380c486 8666+
d33d7b00
AM
8667+static inline struct nx_info *__get_nx_info(struct nx_info *nxi,
8668+ const char *_file, int _line)
8669+{
8670+ if (!nxi)
8671+ return NULL;
d337f35e 8672+
d33d7b00
AM
8673+ vxlprintk(VXD_CBIT(nid, 2), "get_nx_info(%p[#%d.%d])",
8674+ nxi, nxi ? nxi->nx_id : 0,
8675+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
8676+ _file, _line);
d337f35e 8677+
d33d7b00
AM
8678+ atomic_inc(&nxi->nx_usecnt);
8679+ return nxi;
8680+}
d337f35e
JR
8681+
8682+
d33d7b00 8683+extern void free_nx_info(struct nx_info *);
d337f35e 8684+
d33d7b00 8685+#define put_nx_info(i) __put_nx_info(i, __FILE__, __LINE__)
d337f35e 8686+
d33d7b00
AM
8687+static inline void __put_nx_info(struct nx_info *nxi, const char *_file, int _line)
8688+{
8689+ if (!nxi)
8690+ return;
d337f35e 8691+
d33d7b00
AM
8692+ vxlprintk(VXD_CBIT(nid, 2), "put_nx_info(%p[#%d.%d])",
8693+ nxi, nxi ? nxi->nx_id : 0,
8694+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
8695+ _file, _line);
d337f35e 8696+
d33d7b00
AM
8697+ if (atomic_dec_and_test(&nxi->nx_usecnt))
8698+ free_nx_info(nxi);
8699+}
d337f35e 8700+
d337f35e 8701+
d33d7b00 8702+#define init_nx_info(p, i) __init_nx_info(p, i, __FILE__, __LINE__)
d337f35e 8703+
d33d7b00
AM
8704+static inline void __init_nx_info(struct nx_info **nxp, struct nx_info *nxi,
8705+ const char *_file, int _line)
8706+{
8707+ if (nxi) {
8708+ vxlprintk(VXD_CBIT(nid, 3),
8709+ "init_nx_info(%p[#%d.%d])",
8710+ nxi, nxi ? nxi->nx_id : 0,
8711+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
8712+ _file, _line);
d337f35e 8713+
d33d7b00
AM
8714+ atomic_inc(&nxi->nx_usecnt);
8715+ }
8716+ *nxp = nxi;
8717+}
d337f35e 8718+
d337f35e 8719+
d33d7b00 8720+#define set_nx_info(p, i) __set_nx_info(p, i, __FILE__, __LINE__)
d337f35e 8721+
d33d7b00
AM
8722+static inline void __set_nx_info(struct nx_info **nxp, struct nx_info *nxi,
8723+ const char *_file, int _line)
8724+{
8725+ struct nx_info *nxo;
d337f35e 8726+
d33d7b00
AM
8727+ if (!nxi)
8728+ return;
d337f35e 8729+
d33d7b00
AM
8730+ vxlprintk(VXD_CBIT(nid, 3), "set_nx_info(%p[#%d.%d])",
8731+ nxi, nxi ? nxi->nx_id : 0,
8732+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
8733+ _file, _line);
d337f35e 8734+
d33d7b00
AM
8735+ atomic_inc(&nxi->nx_usecnt);
8736+ nxo = xchg(nxp, nxi);
8737+ BUG_ON(nxo);
8738+}
d337f35e 8739+
d33d7b00 8740+#define clr_nx_info(p) __clr_nx_info(p, __FILE__, __LINE__)
d337f35e 8741+
d33d7b00
AM
8742+static inline void __clr_nx_info(struct nx_info **nxp,
8743+ const char *_file, int _line)
8744+{
8745+ struct nx_info *nxo;
d337f35e 8746+
d33d7b00
AM
8747+ nxo = xchg(nxp, NULL);
8748+ if (!nxo)
8749+ return;
d337f35e 8750+
d33d7b00
AM
8751+ vxlprintk(VXD_CBIT(nid, 3), "clr_nx_info(%p[#%d.%d])",
8752+ nxo, nxo ? nxo->nx_id : 0,
8753+ nxo ? atomic_read(&nxo->nx_usecnt) : 0,
8754+ _file, _line);
d337f35e 8755+
d33d7b00
AM
8756+ if (atomic_dec_and_test(&nxo->nx_usecnt))
8757+ free_nx_info(nxo);
8758+}
d337f35e
JR
8759+
8760+
d33d7b00 8761+#define claim_nx_info(v, p) __claim_nx_info(v, p, __FILE__, __LINE__)
d337f35e 8762+
d33d7b00
AM
8763+static inline void __claim_nx_info(struct nx_info *nxi,
8764+ struct task_struct *task, const char *_file, int _line)
8765+{
8766+ vxlprintk(VXD_CBIT(nid, 3), "claim_nx_info(%p[#%d.%d.%d]) %p",
8767+ nxi, nxi ? nxi->nx_id : 0,
8768+ nxi?atomic_read(&nxi->nx_usecnt):0,
8769+ nxi?atomic_read(&nxi->nx_tasks):0,
8770+ task, _file, _line);
d337f35e 8771+
d33d7b00
AM
8772+ atomic_inc(&nxi->nx_tasks);
8773+}
d337f35e 8774+
d337f35e 8775+
d33d7b00 8776+extern void unhash_nx_info(struct nx_info *);
d337f35e 8777+
d33d7b00 8778+#define release_nx_info(v, p) __release_nx_info(v, p, __FILE__, __LINE__)
d337f35e 8779+
d33d7b00
AM
8780+static inline void __release_nx_info(struct nx_info *nxi,
8781+ struct task_struct *task, const char *_file, int _line)
8782+{
8783+ vxlprintk(VXD_CBIT(nid, 3), "release_nx_info(%p[#%d.%d.%d]) %p",
8784+ nxi, nxi ? nxi->nx_id : 0,
8785+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
8786+ nxi ? atomic_read(&nxi->nx_tasks) : 0,
8787+ task, _file, _line);
ab30d09f 8788+
d33d7b00 8789+ might_sleep();
d337f35e 8790+
d33d7b00
AM
8791+ if (atomic_dec_and_test(&nxi->nx_tasks))
8792+ unhash_nx_info(nxi);
8793+}
d337f35e
JR
8794+
8795+
d33d7b00 8796+#define task_get_nx_info(i) __task_get_nx_info(i, __FILE__, __LINE__)
d337f35e 8797+
d33d7b00
AM
8798+static __inline__ struct nx_info *__task_get_nx_info(struct task_struct *p,
8799+ const char *_file, int _line)
8800+{
8801+ struct nx_info *nxi;
d337f35e 8802+
d33d7b00
AM
8803+ task_lock(p);
8804+ vxlprintk(VXD_CBIT(nid, 5), "task_get_nx_info(%p)",
8805+ p, _file, _line);
8806+ nxi = __get_nx_info(p->nx_info, _file, _line);
8807+ task_unlock(p);
8808+ return nxi;
8809+}
d337f35e 8810+
d337f35e 8811+
d33d7b00
AM
8812+static inline void exit_nx_info(struct task_struct *p)
8813+{
8814+ if (p->nx_info)
8815+ release_nx_info(p->nx_info, p);
8816+}
adc1caaa 8817+
d337f35e 8818+
2380c486 8819+#else
d33d7b00 8820+#warning duplicate inclusion
2380c486 8821+#endif
cef7ea10
AM
8822diff -NurpP --minimal linux-4.9.82/include/linux/vs_pid.h linux-4.9.82-vs2.3.9.7/include/linux/vs_pid.h
8823--- linux-4.9.82/include/linux/vs_pid.h 1970-01-01 00:00:00.000000000 +0000
8824+++ linux-4.9.82-vs2.3.9.7/include/linux/vs_pid.h 2018-01-10 02:50:49.000000000 +0000
b3b0d4fd 8825@@ -0,0 +1,50 @@
d33d7b00
AM
8826+#ifndef _VS_PID_H
8827+#define _VS_PID_H
d337f35e 8828+
d33d7b00
AM
8829+#include "vserver/base.h"
8830+#include "vserver/check.h"
8831+#include "vserver/context.h"
8832+#include "vserver/debug.h"
8833+#include "vserver/pid.h"
8834+#include <linux/pid_namespace.h>
d337f35e 8835+
d337f35e 8836+
d33d7b00 8837+#define VXF_FAKE_INIT (VXF_INFO_INIT | VXF_STATE_INIT)
d337f35e 8838+
d33d7b00
AM
8839+static inline
8840+int vx_proc_task_visible(struct task_struct *task)
8841+{
8842+ if ((task->pid == 1) &&
8843+ !vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT))
8844+ /* show a blend through init */
8845+ goto visible;
8846+ if (vx_check(vx_task_xid(task), VS_WATCH | VS_IDENT))
8847+ goto visible;
8848+ return 0;
8849+visible:
8850+ return 1;
8851+}
d337f35e 8852+
d33d7b00 8853+#define find_task_by_real_pid(pid) find_task_by_pid_ns(pid, &init_pid_ns)
d337f35e 8854+
d337f35e 8855+
d33d7b00
AM
8856+static inline
8857+struct task_struct *vx_get_proc_task(struct inode *inode, struct pid *pid)
8858+{
8859+ struct task_struct *task = get_pid_task(pid, PIDTYPE_PID);
d337f35e 8860+
d33d7b00
AM
8861+ if (task && !vx_proc_task_visible(task)) {
8862+ vxdprintk(VXD_CBIT(misc, 6),
8863+ "dropping task (get) %p[#%u,%u] for %p[#%u,%u]",
8864+ task, task->xid, task->pid,
8865+ current, current->xid, current->pid);
8866+ put_task_struct(task);
8867+ task = NULL;
8868+ }
8869+ return task;
8870+}
d337f35e 8871+
d337f35e 8872+
d33d7b00
AM
8873+#else
8874+#warning duplicate inclusion
8875+#endif
cef7ea10
AM
8876diff -NurpP --minimal linux-4.9.82/include/linux/vs_sched.h linux-4.9.82-vs2.3.9.7/include/linux/vs_sched.h
8877--- linux-4.9.82/include/linux/vs_sched.h 1970-01-01 00:00:00.000000000 +0000
8878+++ linux-4.9.82-vs2.3.9.7/include/linux/vs_sched.h 2018-01-10 02:50:49.000000000 +0000
d33d7b00
AM
8879@@ -0,0 +1,40 @@
8880+#ifndef _VS_SCHED_H
8881+#define _VS_SCHED_H
d337f35e 8882+
d33d7b00
AM
8883+#include "vserver/base.h"
8884+#include "vserver/context.h"
8885+#include "vserver/sched.h"
d337f35e
JR
8886+
8887+
d33d7b00
AM
8888+#define MAX_PRIO_BIAS 20
8889+#define MIN_PRIO_BIAS -20
d337f35e 8890+
d33d7b00
AM
8891+static inline
8892+int vx_adjust_prio(struct task_struct *p, int prio, int max_user)
8893+{
8894+ struct vx_info *vxi = p->vx_info;
d337f35e 8895+
d33d7b00
AM
8896+ if (vxi)
8897+ prio += vx_cpu(vxi, sched_pc).prio_bias;
8898+ return prio;
8899+}
d337f35e 8900+
d33d7b00
AM
8901+static inline void vx_account_user(struct vx_info *vxi,
8902+ cputime_t cputime, int nice)
8903+{
8904+ if (!vxi)
8905+ return;
8906+ vx_cpu(vxi, sched_pc).user_ticks += cputime;
8907+}
d337f35e 8908+
d33d7b00
AM
8909+static inline void vx_account_system(struct vx_info *vxi,
8910+ cputime_t cputime, int idle)
8911+{
8912+ if (!vxi)
8913+ return;
8914+ vx_cpu(vxi, sched_pc).sys_ticks += cputime;
8915+}
d337f35e 8916+
d33d7b00
AM
8917+#else
8918+#warning duplicate inclusion
8919+#endif
cef7ea10
AM
8920diff -NurpP --minimal linux-4.9.82/include/linux/vs_socket.h linux-4.9.82-vs2.3.9.7/include/linux/vs_socket.h
8921--- linux-4.9.82/include/linux/vs_socket.h 1970-01-01 00:00:00.000000000 +0000
8922+++ linux-4.9.82-vs2.3.9.7/include/linux/vs_socket.h 2018-01-10 02:50:49.000000000 +0000
d33d7b00
AM
8923@@ -0,0 +1,67 @@
8924+#ifndef _VS_SOCKET_H
8925+#define _VS_SOCKET_H
d337f35e 8926+
d33d7b00
AM
8927+#include "vserver/debug.h"
8928+#include "vserver/base.h"
8929+#include "vserver/cacct.h"
8930+#include "vserver/context.h"
8931+#include "vserver/tag.h"
d337f35e 8932+
d337f35e 8933+
d33d7b00 8934+/* socket accounting */
d337f35e 8935+
d33d7b00 8936+#include <linux/socket.h>
d337f35e 8937+
d33d7b00
AM
8938+static inline int vx_sock_type(int family)
8939+{
8940+ switch (family) {
8941+ case PF_UNSPEC:
8942+ return VXA_SOCK_UNSPEC;
8943+ case PF_UNIX:
8944+ return VXA_SOCK_UNIX;
8945+ case PF_INET:
8946+ return VXA_SOCK_INET;
8947+ case PF_INET6:
8948+ return VXA_SOCK_INET6;
8949+ case PF_PACKET:
8950+ return VXA_SOCK_PACKET;
8951+ default:
8952+ return VXA_SOCK_OTHER;
8953+ }
8954+}
d337f35e 8955+
d33d7b00
AM
8956+#define vx_acc_sock(v, f, p, s) \
8957+ __vx_acc_sock(v, f, p, s, __FILE__, __LINE__)
d337f35e 8958+
d33d7b00
AM
8959+static inline void __vx_acc_sock(struct vx_info *vxi,
8960+ int family, int pos, int size, char *file, int line)
8961+{
8962+ if (vxi) {
8963+ int type = vx_sock_type(family);
d337f35e 8964+
d33d7b00
AM
8965+ atomic_long_inc(&vxi->cacct.sock[type][pos].count);
8966+ atomic_long_add(size, &vxi->cacct.sock[type][pos].total);
8967+ }
8968+}
d337f35e 8969+
d33d7b00
AM
8970+#define vx_sock_recv(sk, s) \
8971+ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, s)
8972+#define vx_sock_send(sk, s) \
8973+ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, s)
8974+#define vx_sock_fail(sk, s) \
8975+ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, s)
d337f35e 8976+
d337f35e 8977+
d33d7b00
AM
8978+#define sock_vx_init(s) do { \
8979+ (s)->sk_xid = 0; \
8980+ (s)->sk_vx_info = NULL; \
8981+ } while (0)
d337f35e 8982+
d33d7b00
AM
8983+#define sock_nx_init(s) do { \
8984+ (s)->sk_nid = 0; \
8985+ (s)->sk_nx_info = NULL; \
8986+ } while (0)
d337f35e 8987+
d33d7b00
AM
8988+#else
8989+#warning duplicate inclusion
8990+#endif
cef7ea10
AM
8991diff -NurpP --minimal linux-4.9.82/include/linux/vs_tag.h linux-4.9.82-vs2.3.9.7/include/linux/vs_tag.h
8992--- linux-4.9.82/include/linux/vs_tag.h 1970-01-01 00:00:00.000000000 +0000
8993+++ linux-4.9.82-vs2.3.9.7/include/linux/vs_tag.h 2018-01-10 02:50:49.000000000 +0000
d33d7b00
AM
8994@@ -0,0 +1,47 @@
8995+#ifndef _VS_TAG_H
8996+#define _VS_TAG_H
d337f35e 8997+
d33d7b00 8998+#include <linux/vserver/tag.h>
d337f35e 8999+
d33d7b00 9000+/* check conditions */
d337f35e 9001+
d33d7b00
AM
9002+#define DX_ADMIN 0x0001
9003+#define DX_WATCH 0x0002
9004+#define DX_HOSTID 0x0008
d337f35e 9005+
d33d7b00 9006+#define DX_IDENT 0x0010
d337f35e 9007+
d33d7b00 9008+#define DX_ARG_MASK 0x0010
d337f35e 9009+
d337f35e 9010+
d33d7b00 9011+#define dx_task_tag(t) ((t)->tag)
d337f35e 9012+
d33d7b00 9013+#define dx_current_tag() dx_task_tag(current)
d337f35e 9014+
d33d7b00 9015+#define dx_check(c, m) __dx_check(dx_current_tag(), c, m)
d337f35e 9016+
d33d7b00 9017+#define dx_weak_check(c, m) ((m) ? dx_check(c, m) : 1)
d337f35e
JR
9018+
9019+
d33d7b00
AM
9020+/*
9021+ * check current context for ADMIN/WATCH and
9022+ * optionally against supplied argument
9023+ */
61333608 9024+static inline int __dx_check(vtag_t cid, vtag_t id, unsigned int mode)
d33d7b00
AM
9025+{
9026+ if (mode & DX_ARG_MASK) {
9027+ if ((mode & DX_IDENT) && (id == cid))
9028+ return 1;
9029+ }
9030+ return (((mode & DX_ADMIN) && (cid == 0)) ||
9031+ ((mode & DX_WATCH) && (cid == 1)) ||
9032+ ((mode & DX_HOSTID) && (id == 0)));
9033+}
d337f35e 9034+
d33d7b00
AM
9035+struct inode;
9036+int dx_permission(const struct inode *inode, int mask);
d337f35e 9037+
d337f35e 9038+
d33d7b00
AM
9039+#else
9040+#warning duplicate inclusion
9041+#endif
cef7ea10
AM
9042diff -NurpP --minimal linux-4.9.82/include/linux/vs_time.h linux-4.9.82-vs2.3.9.7/include/linux/vs_time.h
9043--- linux-4.9.82/include/linux/vs_time.h 1970-01-01 00:00:00.000000000 +0000
9044+++ linux-4.9.82-vs2.3.9.7/include/linux/vs_time.h 2018-01-16 00:51:52.000000000 +0000
cc23e853 9045@@ -0,0 +1,21 @@
d33d7b00
AM
9046+#ifndef _VS_TIME_H
9047+#define _VS_TIME_H
d337f35e 9048+
d337f35e 9049+
d33d7b00 9050+/* time faking stuff */
d337f35e 9051+
d33d7b00 9052+#ifdef CONFIG_VSERVER_VTIME
d337f35e 9053+
d33d7b00 9054+extern void vx_adjust_timespec(struct timespec *ts);
763640ca 9055+extern int vx_settimeofday(const struct timespec *ts);
369dbd59 9056+extern int vx_settimeofday64(const struct timespec64 *ts);
d337f35e 9057+
d33d7b00
AM
9058+#else
9059+#define vx_adjust_timespec(t) do { } while (0)
9060+#define vx_settimeofday(t) do_settimeofday(t)
cc23e853 9061+#define vx_settimeofday64(t) do_settimeofday64(t)
d33d7b00 9062+#endif
d337f35e 9063+
d33d7b00
AM
9064+#else
9065+#warning duplicate inclusion
9066+#endif
cef7ea10
AM
9067diff -NurpP --minimal linux-4.9.82/include/linux/vserver/base.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/base.h
9068--- linux-4.9.82/include/linux/vserver/base.h 1970-01-01 00:00:00.000000000 +0000
9069+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/base.h 2018-01-10 02:50:49.000000000 +0000
c2e5f7c8 9070@@ -0,0 +1,184 @@
4bf69007
AM
9071+#ifndef _VSERVER_BASE_H
9072+#define _VSERVER_BASE_H
d337f35e 9073+
d337f35e 9074+
d33d7b00 9075+/* context state changes */
d337f35e 9076+
d33d7b00
AM
9077+enum {
9078+ VSC_STARTUP = 1,
9079+ VSC_SHUTDOWN,
d337f35e 9080+
d33d7b00
AM
9081+ VSC_NETUP,
9082+ VSC_NETDOWN,
3bac966d 9083+};
d337f35e 9084+
d337f35e
JR
9085+
9086+
d33d7b00 9087+#define vx_task_xid(t) ((t)->xid)
d337f35e 9088+
d33d7b00 9089+#define vx_current_xid() vx_task_xid(current)
d337f35e 9090+
d33d7b00 9091+#define current_vx_info() (current->vx_info)
d337f35e 9092+
ba86f833 9093+
d33d7b00 9094+#define nx_task_nid(t) ((t)->nid)
ba86f833 9095+
d33d7b00 9096+#define nx_current_nid() nx_task_nid(current)
d337f35e 9097+
d33d7b00 9098+#define current_nx_info() (current->nx_info)
d337f35e 9099+
d337f35e 9100+
d33d7b00 9101+/* generic flag merging */
d337f35e 9102+
d33d7b00 9103+#define vs_check_flags(v, m, f) (((v) & (m)) ^ (f))
d337f35e 9104+
d33d7b00 9105+#define vs_mask_flags(v, f, m) (((v) & ~(m)) | ((f) & (m)))
d337f35e 9106+
d33d7b00 9107+#define vs_mask_mask(v, f, m) (((v) & ~(m)) | ((v) & (f) & (m)))
d337f35e 9108+
d33d7b00 9109+#define vs_check_bit(v, n) ((v) & (1LL << (n)))
d337f35e 9110+
d337f35e 9111+
d33d7b00 9112+/* context flags */
d337f35e 9113+
d33d7b00 9114+#define __vx_flags(v) ((v) ? (v)->vx_flags : 0)
d337f35e 9115+
d33d7b00 9116+#define vx_current_flags() __vx_flags(current_vx_info())
d337f35e 9117+
d33d7b00
AM
9118+#define vx_info_flags(v, m, f) \
9119+ vs_check_flags(__vx_flags(v), m, f)
d337f35e 9120+
d33d7b00
AM
9121+#define task_vx_flags(t, m, f) \
9122+ ((t) && vx_info_flags((t)->vx_info, m, f))
d337f35e 9123+
d33d7b00 9124+#define vx_flags(m, f) vx_info_flags(current_vx_info(), m, f)
d337f35e
JR
9125+
9126+
d33d7b00 9127+/* context caps */
d337f35e 9128+
d33d7b00 9129+#define __vx_ccaps(v) ((v) ? (v)->vx_ccaps : 0)
d337f35e 9130+
d33d7b00 9131+#define vx_current_ccaps() __vx_ccaps(current_vx_info())
d337f35e 9132+
d33d7b00 9133+#define vx_info_ccaps(v, c) (__vx_ccaps(v) & (c))
d337f35e 9134+
d33d7b00 9135+#define vx_ccaps(c) vx_info_ccaps(current_vx_info(), (c))
d337f35e 9136+
d337f35e
JR
9137+
9138+
d33d7b00 9139+/* network flags */
2380c486 9140+
d33d7b00 9141+#define __nx_flags(n) ((n) ? (n)->nx_flags : 0)
d337f35e 9142+
d33d7b00 9143+#define nx_current_flags() __nx_flags(current_nx_info())
d337f35e 9144+
d33d7b00
AM
9145+#define nx_info_flags(n, m, f) \
9146+ vs_check_flags(__nx_flags(n), m, f)
d337f35e 9147+
d33d7b00
AM
9148+#define task_nx_flags(t, m, f) \
9149+ ((t) && nx_info_flags((t)->nx_info, m, f))
d337f35e 9150+
d33d7b00 9151+#define nx_flags(m, f) nx_info_flags(current_nx_info(), m, f)
d337f35e 9152+
d337f35e 9153+
d33d7b00 9154+/* network caps */
d337f35e 9155+
d33d7b00 9156+#define __nx_ncaps(n) ((n) ? (n)->nx_ncaps : 0)
d337f35e 9157+
d33d7b00 9158+#define nx_current_ncaps() __nx_ncaps(current_nx_info())
d337f35e 9159+
d33d7b00 9160+#define nx_info_ncaps(n, c) (__nx_ncaps(n) & (c))
d337f35e 9161+
d33d7b00 9162+#define nx_ncaps(c) nx_info_ncaps(current_nx_info(), c)
d337f35e 9163+
d337f35e 9164+
d33d7b00 9165+/* context mask capabilities */
d337f35e 9166+
d33d7b00 9167+#define __vx_mcaps(v) ((v) ? (v)->vx_ccaps >> 32UL : ~0 )
d337f35e 9168+
d33d7b00 9169+#define vx_info_mcaps(v, c) (__vx_mcaps(v) & (c))
d337f35e 9170+
d33d7b00 9171+#define vx_mcaps(c) vx_info_mcaps(current_vx_info(), c)
d337f35e
JR
9172+
9173+
d33d7b00 9174+/* context bcap mask */
d337f35e 9175+
d33d7b00 9176+#define __vx_bcaps(v) ((v)->vx_bcaps)
d337f35e 9177+
d33d7b00 9178+#define vx_current_bcaps() __vx_bcaps(current_vx_info())
d337f35e 9179+
d337f35e 9180+
d33d7b00 9181+/* mask given bcaps */
adc1caaa 9182+
d33d7b00 9183+#define vx_info_mbcaps(v, c) ((v) ? cap_intersect(__vx_bcaps(v), c) : c)
2380c486 9184+
d33d7b00 9185+#define vx_mbcaps(c) vx_info_mbcaps(current_vx_info(), c)
d337f35e
JR
9186+
9187+
d33d7b00 9188+/* masked cap_bset */
2380c486 9189+
d33d7b00 9190+#define vx_info_cap_bset(v) vx_info_mbcaps(v, current->cap_bset)
2380c486 9191+
d33d7b00 9192+#define vx_current_cap_bset() vx_info_cap_bset(current_vx_info())
d337f35e 9193+
d33d7b00
AM
9194+#if 0
9195+#define vx_info_mbcap(v, b) \
9196+ (!vx_info_flags(v, VXF_STATE_SETUP, 0) ? \
9197+ vx_info_bcaps(v, b) : (b))
d337f35e 9198+
d33d7b00
AM
9199+#define task_vx_mbcap(t, b) \
9200+ vx_info_mbcap((t)->vx_info, (t)->b)
9201+
9202+#define vx_mbcap(b) task_vx_mbcap(current, b)
3bac966d 9203+#endif
d337f35e 9204+
d33d7b00 9205+#define vx_cap_raised(v, c, f) cap_raised(vx_info_mbcaps(v, c), f)
d337f35e 9206+
d33d7b00
AM
9207+#define vx_capable(b, c) (capable(b) || \
9208+ (cap_raised(current_cap(), b) && vx_ccaps(c)))
d337f35e 9209+
763640ca
JR
9210+#define vx_ns_capable(n, b, c) (ns_capable(n, b) || \
9211+ (cap_raised(current_cap(), b) && vx_ccaps(c)))
9212+
d33d7b00
AM
9213+#define nx_capable(b, c) (capable(b) || \
9214+ (cap_raised(current_cap(), b) && nx_ncaps(c)))
d337f35e 9215+
c2e5f7c8
JR
9216+#define nx_ns_capable(n, b, c) (ns_capable(n, b) || \
9217+ (cap_raised(current_cap(), b) && nx_ncaps(c)))
9218+
d33d7b00
AM
9219+#define vx_task_initpid(t, n) \
9220+ ((t)->vx_info && \
9221+ ((t)->vx_info->vx_initpid == (n)))
d337f35e 9222+
d33d7b00 9223+#define vx_current_initpid(n) vx_task_initpid(current, n)
d337f35e 9224+
d337f35e 9225+
d33d7b00 9226+/* context unshare mask */
d337f35e 9227+
d33d7b00 9228+#define __vx_umask(v) ((v)->vx_umask)
7e46296a 9229+
d33d7b00 9230+#define vx_current_umask() __vx_umask(current_vx_info())
7e46296a 9231+
d33d7b00
AM
9232+#define vx_can_unshare(b, f) (capable(b) || \
9233+ (cap_raised(current_cap(), b) && \
9234+ !((f) & ~vx_current_umask())))
7e46296a 9235+
b00e13aa
AM
9236+#define vx_ns_can_unshare(n, b, f) (ns_capable(n, b) || \
9237+ (cap_raised(current_cap(), b) && \
9238+ !((f) & ~vx_current_umask())))
7e46296a 9239+
265d6dcc
JR
9240+#define __vx_wmask(v) ((v)->vx_wmask)
9241+
9242+#define vx_current_wmask() __vx_wmask(current_vx_info())
9243+
9244+
d33d7b00 9245+#define __vx_state(v) ((v) ? ((v)->vx_state) : 0)
7e46296a 9246+
d33d7b00 9247+#define vx_info_state(v, m) (__vx_state(v) & (m))
d337f35e 9248+
d337f35e 9249+
d33d7b00 9250+#define __nx_state(n) ((n) ? ((n)->nx_state) : 0)
d337f35e 9251+
d33d7b00 9252+#define nx_info_state(n, m) (__nx_state(n) & (m))
d337f35e 9253+
d33d7b00 9254+#endif
cef7ea10
AM
9255diff -NurpP --minimal linux-4.9.82/include/linux/vserver/cacct.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/cacct.h
9256--- linux-4.9.82/include/linux/vserver/cacct.h 1970-01-01 00:00:00.000000000 +0000
9257+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/cacct.h 2018-01-10 02:50:49.000000000 +0000
d33d7b00 9258@@ -0,0 +1,15 @@
4bf69007
AM
9259+#ifndef _VSERVER_CACCT_H
9260+#define _VSERVER_CACCT_H
d337f35e 9261+
d337f35e 9262+
d33d7b00
AM
9263+enum sock_acc_field {
9264+ VXA_SOCK_UNSPEC = 0,
9265+ VXA_SOCK_UNIX,
9266+ VXA_SOCK_INET,
9267+ VXA_SOCK_INET6,
9268+ VXA_SOCK_PACKET,
9269+ VXA_SOCK_OTHER,
9270+ VXA_SOCK_SIZE /* array size */
9271+};
d337f35e 9272+
4bf69007 9273+#endif /* _VSERVER_CACCT_H */
cef7ea10
AM
9274diff -NurpP --minimal linux-4.9.82/include/linux/vserver/cacct_cmd.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/cacct_cmd.h
9275--- linux-4.9.82/include/linux/vserver/cacct_cmd.h 1970-01-01 00:00:00.000000000 +0000
9276+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/cacct_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
9277@@ -0,0 +1,10 @@
9278+#ifndef _VSERVER_CACCT_CMD_H
9279+#define _VSERVER_CACCT_CMD_H
d337f35e 9280+
d337f35e 9281+
3bac966d 9282+#include <linux/compiler.h>
4bf69007 9283+#include <uapi/vserver/cacct_cmd.h>
d337f35e 9284+
d33d7b00 9285+extern int vc_sock_stat(struct vx_info *, void __user *);
d337f35e 9286+
4bf69007 9287+#endif /* _VSERVER_CACCT_CMD_H */
cef7ea10
AM
9288diff -NurpP --minimal linux-4.9.82/include/linux/vserver/cacct_def.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/cacct_def.h
9289--- linux-4.9.82/include/linux/vserver/cacct_def.h 1970-01-01 00:00:00.000000000 +0000
9290+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/cacct_def.h 2018-01-10 02:50:49.000000000 +0000
d33d7b00 9291@@ -0,0 +1,43 @@
4bf69007
AM
9292+#ifndef _VSERVER_CACCT_DEF_H
9293+#define _VSERVER_CACCT_DEF_H
d337f35e 9294+
d33d7b00
AM
9295+#include <asm/atomic.h>
9296+#include <linux/vserver/cacct.h>
d337f35e
JR
9297+
9298+
d33d7b00
AM
9299+struct _vx_sock_acc {
9300+ atomic_long_t count;
9301+ atomic_long_t total;
9302+};
d337f35e 9303+
d33d7b00 9304+/* context sub struct */
d337f35e 9305+
d33d7b00
AM
9306+struct _vx_cacct {
9307+ struct _vx_sock_acc sock[VXA_SOCK_SIZE][3];
9308+ atomic_t slab[8];
9309+ atomic_t page[6][8];
9310+};
d337f35e 9311+
d33d7b00 9312+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 9313+
d33d7b00
AM
9314+static inline void __dump_vx_cacct(struct _vx_cacct *cacct)
9315+{
9316+ int i, j;
d337f35e 9317+
d33d7b00
AM
9318+ printk("\t_vx_cacct:");
9319+ for (i = 0; i < 6; i++) {
9320+ struct _vx_sock_acc *ptr = cacct->sock[i];
d337f35e 9321+
d33d7b00
AM
9322+ printk("\t [%d] =", i);
9323+ for (j = 0; j < 3; j++) {
9324+ printk(" [%d] = %8lu, %8lu", j,
9325+ atomic_long_read(&ptr[j].count),
9326+ atomic_long_read(&ptr[j].total));
9327+ }
9328+ printk("\n");
9329+ }
9330+}
2380c486 9331+
d33d7b00 9332+#endif
d337f35e 9333+
4bf69007 9334+#endif /* _VSERVER_CACCT_DEF_H */
cef7ea10
AM
9335diff -NurpP --minimal linux-4.9.82/include/linux/vserver/cacct_int.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/cacct_int.h
9336--- linux-4.9.82/include/linux/vserver/cacct_int.h 1970-01-01 00:00:00.000000000 +0000
9337+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/cacct_int.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
9338@@ -0,0 +1,17 @@
9339+#ifndef _VSERVER_CACCT_INT_H
9340+#define _VSERVER_CACCT_INT_H
d337f35e 9341+
d33d7b00
AM
9342+static inline
9343+unsigned long vx_sock_count(struct _vx_cacct *cacct, int type, int pos)
9344+{
9345+ return atomic_long_read(&cacct->sock[type][pos].count);
9346+}
d337f35e 9347+
d337f35e 9348+
d33d7b00
AM
9349+static inline
9350+unsigned long vx_sock_total(struct _vx_cacct *cacct, int type, int pos)
9351+{
9352+ return atomic_long_read(&cacct->sock[type][pos].total);
9353+}
d337f35e 9354+
4bf69007 9355+#endif /* _VSERVER_CACCT_INT_H */
cef7ea10
AM
9356diff -NurpP --minimal linux-4.9.82/include/linux/vserver/check.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/check.h
9357--- linux-4.9.82/include/linux/vserver/check.h 1970-01-01 00:00:00.000000000 +0000
9358+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/check.h 2018-01-10 02:50:49.000000000 +0000
d33d7b00 9359@@ -0,0 +1,89 @@
4bf69007
AM
9360+#ifndef _VSERVER_CHECK_H
9361+#define _VSERVER_CHECK_H
d337f35e 9362+
d337f35e 9363+
d33d7b00 9364+#define MAX_S_CONTEXT 65535 /* Arbitrary limit */
d337f35e 9365+
d33d7b00
AM
9366+#ifdef CONFIG_VSERVER_DYNAMIC_IDS
9367+#define MIN_D_CONTEXT 49152 /* dynamic contexts start here */
9368+#else
9369+#define MIN_D_CONTEXT 65536
9370+#endif
d337f35e 9371+
d33d7b00 9372+/* check conditions */
d337f35e 9373+
d33d7b00
AM
9374+#define VS_ADMIN 0x0001
9375+#define VS_WATCH 0x0002
9376+#define VS_HIDE 0x0004
9377+#define VS_HOSTID 0x0008
d337f35e 9378+
d33d7b00
AM
9379+#define VS_IDENT 0x0010
9380+#define VS_EQUIV 0x0020
9381+#define VS_PARENT 0x0040
9382+#define VS_CHILD 0x0080
d337f35e 9383+
d33d7b00 9384+#define VS_ARG_MASK 0x00F0
d337f35e 9385+
d33d7b00
AM
9386+#define VS_DYNAMIC 0x0100
9387+#define VS_STATIC 0x0200
d337f35e 9388+
d33d7b00 9389+#define VS_ATR_MASK 0x0F00
d337f35e 9390+
d33d7b00
AM
9391+#ifdef CONFIG_VSERVER_PRIVACY
9392+#define VS_ADMIN_P (0)
9393+#define VS_WATCH_P (0)
9394+#else
9395+#define VS_ADMIN_P VS_ADMIN
9396+#define VS_WATCH_P VS_WATCH
9397+#endif
d337f35e 9398+
d33d7b00
AM
9399+#define VS_HARDIRQ 0x1000
9400+#define VS_SOFTIRQ 0x2000
9401+#define VS_IRQ 0x4000
d337f35e 9402+
d33d7b00 9403+#define VS_IRQ_MASK 0xF000
d337f35e 9404+
d33d7b00 9405+#include <linux/hardirq.h>
d337f35e 9406+
d33d7b00
AM
9407+/*
9408+ * check current context for ADMIN/WATCH and
9409+ * optionally against supplied argument
9410+ */
9411+static inline int __vs_check(int cid, int id, unsigned int mode)
9412+{
9413+ if (mode & VS_ARG_MASK) {
9414+ if ((mode & VS_IDENT) && (id == cid))
9415+ return 1;
9416+ }
9417+ if (mode & VS_ATR_MASK) {
9418+ if ((mode & VS_DYNAMIC) &&
9419+ (id >= MIN_D_CONTEXT) &&
9420+ (id <= MAX_S_CONTEXT))
9421+ return 1;
9422+ if ((mode & VS_STATIC) &&
9423+ (id > 1) && (id < MIN_D_CONTEXT))
9424+ return 1;
9425+ }
9426+ if (mode & VS_IRQ_MASK) {
9427+ if ((mode & VS_IRQ) && unlikely(in_interrupt()))
9428+ return 1;
9429+ if ((mode & VS_HARDIRQ) && unlikely(in_irq()))
9430+ return 1;
9431+ if ((mode & VS_SOFTIRQ) && unlikely(in_softirq()))
9432+ return 1;
9433+ }
9434+ return (((mode & VS_ADMIN) && (cid == 0)) ||
9435+ ((mode & VS_WATCH) && (cid == 1)) ||
9436+ ((mode & VS_HOSTID) && (id == 0)));
9437+}
d337f35e 9438+
d33d7b00 9439+#define vx_check(c, m) __vs_check(vx_current_xid(), c, (m) | VS_IRQ)
d337f35e 9440+
d33d7b00 9441+#define vx_weak_check(c, m) ((m) ? vx_check(c, m) : 1)
2380c486 9442+
d337f35e 9443+
d33d7b00 9444+#define nx_check(c, m) __vs_check(nx_current_nid(), c, m)
d337f35e 9445+
d33d7b00 9446+#define nx_weak_check(c, m) ((m) ? nx_check(c, m) : 1)
d337f35e 9447+
d33d7b00 9448+#endif
cef7ea10
AM
9449diff -NurpP --minimal linux-4.9.82/include/linux/vserver/context.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/context.h
9450--- linux-4.9.82/include/linux/vserver/context.h 1970-01-01 00:00:00.000000000 +0000
9451+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/context.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
9452@@ -0,0 +1,110 @@
9453+#ifndef _VSERVER_CONTEXT_H
9454+#define _VSERVER_CONTEXT_H
d337f35e
JR
9455+
9456+
d33d7b00
AM
9457+#include <linux/list.h>
9458+#include <linux/spinlock.h>
9459+#include <linux/rcupdate.h>
4bf69007 9460+#include <uapi/vserver/context.h>
d337f35e 9461+
d33d7b00
AM
9462+#include "limit_def.h"
9463+#include "sched_def.h"
9464+#include "cvirt_def.h"
9465+#include "cacct_def.h"
9466+#include "device_def.h"
d337f35e 9467+
d33d7b00 9468+#define VX_SPACES 2
d337f35e 9469+
d33d7b00
AM
9470+struct _vx_info_pc {
9471+ struct _vx_sched_pc sched_pc;
9472+ struct _vx_cvirt_pc cvirt_pc;
9473+};
d337f35e 9474+
d33d7b00
AM
9475+struct _vx_space {
9476+ unsigned long vx_nsmask; /* assignment mask */
9477+ struct nsproxy *vx_nsproxy; /* private namespaces */
9478+ struct fs_struct *vx_fs; /* private namespace fs */
9479+ const struct cred *vx_cred; /* task credentials */
9480+};
d337f35e 9481+
d33d7b00
AM
9482+struct vx_info {
9483+ struct hlist_node vx_hlist; /* linked list of contexts */
61333608 9484+ vxid_t vx_id; /* context id */
d33d7b00
AM
9485+ atomic_t vx_usecnt; /* usage count */
9486+ atomic_t vx_tasks; /* tasks count */
9487+ struct vx_info *vx_parent; /* parent context */
9488+ int vx_state; /* context state */
d337f35e 9489+
d33d7b00 9490+ struct _vx_space space[VX_SPACES]; /* namespace store */
d337f35e 9491+
d33d7b00
AM
9492+ uint64_t vx_flags; /* context flags */
9493+ uint64_t vx_ccaps; /* context caps (vserver) */
763640ca 9494+ uint64_t vx_umask; /* unshare mask (guest) */
265d6dcc 9495+ uint64_t vx_wmask; /* warn mask (guest) */
d33d7b00 9496+ kernel_cap_t vx_bcaps; /* bounding caps (system) */
d337f35e 9497+
d33d7b00
AM
9498+ struct task_struct *vx_reaper; /* guest reaper process */
9499+ pid_t vx_initpid; /* PID of guest init */
9500+ int64_t vx_badness_bias; /* OOM points bias */
d337f35e 9501+
d33d7b00
AM
9502+ struct _vx_limit limit; /* vserver limits */
9503+ struct _vx_sched sched; /* vserver scheduler */
9504+ struct _vx_cvirt cvirt; /* virtual/bias stuff */
9505+ struct _vx_cacct cacct; /* context accounting */
d337f35e 9506+
d33d7b00 9507+ struct _vx_device dmap; /* default device map targets */
d337f35e 9508+
d33d7b00
AM
9509+#ifndef CONFIG_SMP
9510+ struct _vx_info_pc info_pc; /* per cpu data */
9511+#else
9512+ struct _vx_info_pc *ptr_pc; /* per cpu array */
9513+#endif
d337f35e 9514+
d33d7b00
AM
9515+ wait_queue_head_t vx_wait; /* context exit waitqueue */
9516+ int reboot_cmd; /* last sys_reboot() cmd */
9517+ int exit_code; /* last process exit code */
d337f35e 9518+
d33d7b00
AM
9519+ char vx_name[65]; /* vserver name */
9520+};
d337f35e 9521+
d33d7b00
AM
9522+#ifndef CONFIG_SMP
9523+#define vx_ptr_pc(vxi) (&(vxi)->info_pc)
9524+#define vx_per_cpu(vxi, v, id) vx_ptr_pc(vxi)->v
9525+#else
9526+#define vx_ptr_pc(vxi) ((vxi)->ptr_pc)
9527+#define vx_per_cpu(vxi, v, id) per_cpu_ptr(vx_ptr_pc(vxi), id)->v
9528+#endif
d337f35e 9529+
d33d7b00 9530+#define vx_cpu(vxi, v) vx_per_cpu(vxi, v, smp_processor_id())
d337f35e 9531+
d337f35e 9532+
d33d7b00
AM
9533+struct vx_info_save {
9534+ struct vx_info *vxi;
61333608 9535+ vxid_t xid;
d33d7b00 9536+};
d337f35e
JR
9537+
9538+
d33d7b00 9539+/* status flags */
d337f35e 9540+
d33d7b00
AM
9541+#define VXS_HASHED 0x0001
9542+#define VXS_PAUSED 0x0010
9543+#define VXS_SHUTDOWN 0x0100
9544+#define VXS_HELPER 0x1000
9545+#define VXS_RELEASED 0x8000
d337f35e 9546+
d337f35e 9547+
d33d7b00
AM
9548+extern void claim_vx_info(struct vx_info *, struct task_struct *);
9549+extern void release_vx_info(struct vx_info *, struct task_struct *);
adc1caaa 9550+
d33d7b00
AM
9551+extern struct vx_info *lookup_vx_info(int);
9552+extern struct vx_info *lookup_or_create_vx_info(int);
d337f35e 9553+
d33d7b00 9554+extern int get_xid_list(int, unsigned int *, int);
61333608 9555+extern int xid_is_hashed(vxid_t);
d337f35e 9556+
d33d7b00 9557+extern int vx_migrate_task(struct task_struct *, struct vx_info *, int);
d337f35e 9558+
d33d7b00 9559+extern long vs_state_change(struct vx_info *, unsigned int);
d337f35e 9560+
d337f35e 9561+
4bf69007 9562+#endif /* _VSERVER_CONTEXT_H */
cef7ea10
AM
9563diff -NurpP --minimal linux-4.9.82/include/linux/vserver/context_cmd.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/context_cmd.h
9564--- linux-4.9.82/include/linux/vserver/context_cmd.h 1970-01-01 00:00:00.000000000 +0000
9565+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/context_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
9566@@ -0,0 +1,33 @@
9567+#ifndef _VSERVER_CONTEXT_CMD_H
9568+#define _VSERVER_CONTEXT_CMD_H
d337f35e 9569+
4bf69007 9570+#include <uapi/vserver/context_cmd.h>
d337f35e 9571+
d33d7b00 9572+extern int vc_task_xid(uint32_t);
d337f35e 9573+
d33d7b00 9574+extern int vc_vx_info(struct vx_info *, void __user *);
d337f35e 9575+
d33d7b00 9576+extern int vc_ctx_stat(struct vx_info *, void __user *);
d337f35e 9577+
4bf69007
AM
9578+extern int vc_ctx_create(uint32_t, void __user *);
9579+extern int vc_ctx_migrate(struct vx_info *, void __user *);
d337f35e 9580+
4bf69007
AM
9581+extern int vc_get_cflags(struct vx_info *, void __user *);
9582+extern int vc_set_cflags(struct vx_info *, void __user *);
d337f35e 9583+
4bf69007
AM
9584+extern int vc_get_ccaps(struct vx_info *, void __user *);
9585+extern int vc_set_ccaps(struct vx_info *, void __user *);
d337f35e 9586+
4bf69007
AM
9587+extern int vc_get_bcaps(struct vx_info *, void __user *);
9588+extern int vc_set_bcaps(struct vx_info *, void __user *);
d337f35e 9589+
4bf69007
AM
9590+extern int vc_get_umask(struct vx_info *, void __user *);
9591+extern int vc_set_umask(struct vx_info *, void __user *);
d33d7b00 9592+
4bf69007
AM
9593+extern int vc_get_wmask(struct vx_info *, void __user *);
9594+extern int vc_set_wmask(struct vx_info *, void __user *);
d33d7b00 9595+
4bf69007
AM
9596+extern int vc_get_badness(struct vx_info *, void __user *);
9597+extern int vc_set_badness(struct vx_info *, void __user *);
d337f35e 9598+
4bf69007 9599+#endif /* _VSERVER_CONTEXT_CMD_H */
cef7ea10
AM
9600diff -NurpP --minimal linux-4.9.82/include/linux/vserver/cvirt.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/cvirt.h
9601--- linux-4.9.82/include/linux/vserver/cvirt.h 1970-01-01 00:00:00.000000000 +0000
9602+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/cvirt.h 2018-01-16 00:54:34.000000000 +0000
4bf69007
AM
9603@@ -0,0 +1,18 @@
9604+#ifndef _VSERVER_CVIRT_H
9605+#define _VSERVER_CVIRT_H
d337f35e 9606+
4bf69007 9607+struct timespec;
d337f35e 9608+
369dbd59 9609+void vx_vsi_boottime64(struct timespec64 *);
d337f35e 9610+
4bf69007 9611+void vx_vsi_uptime(struct timespec *, struct timespec *);
d337f35e 9612+
d337f35e 9613+
4bf69007 9614+struct vx_info;
d337f35e 9615+
4bf69007 9616+void vx_update_load(struct vx_info *);
d337f35e 9617+
d337f35e 9618+
4bf69007 9619+int vx_do_syslog(int, char __user *, int);
d337f35e 9620+
4bf69007 9621+#endif /* _VSERVER_CVIRT_H */
cef7ea10
AM
9622diff -NurpP --minimal linux-4.9.82/include/linux/vserver/cvirt_cmd.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/cvirt_cmd.h
9623--- linux-4.9.82/include/linux/vserver/cvirt_cmd.h 1970-01-01 00:00:00.000000000 +0000
9624+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/cvirt_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
9625@@ -0,0 +1,13 @@
9626+#ifndef _VSERVER_CVIRT_CMD_H
9627+#define _VSERVER_CVIRT_CMD_H
d337f35e 9628+
d337f35e 9629+
4bf69007
AM
9630+#include <linux/compiler.h>
9631+#include <uapi/vserver/cvirt_cmd.h>
d337f35e 9632+
4bf69007
AM
9633+extern int vc_set_vhi_name(struct vx_info *, void __user *);
9634+extern int vc_get_vhi_name(struct vx_info *, void __user *);
d337f35e 9635+
4bf69007 9636+extern int vc_virt_stat(struct vx_info *, void __user *);
d337f35e 9637+
4bf69007 9638+#endif /* _VSERVER_CVIRT_CMD_H */
cef7ea10
AM
9639diff -NurpP --minimal linux-4.9.82/include/linux/vserver/cvirt_def.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/cvirt_def.h
9640--- linux-4.9.82/include/linux/vserver/cvirt_def.h 1970-01-01 00:00:00.000000000 +0000
9641+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/cvirt_def.h 2018-01-10 10:07:41.000000000 +0000
4bf69007
AM
9642@@ -0,0 +1,80 @@
9643+#ifndef _VSERVER_CVIRT_DEF_H
9644+#define _VSERVER_CVIRT_DEF_H
d337f35e 9645+
d33d7b00
AM
9646+#include <linux/jiffies.h>
9647+#include <linux/spinlock.h>
9648+#include <linux/wait.h>
9649+#include <linux/time.h>
9650+#include <asm/atomic.h>
d337f35e 9651+
d337f35e 9652+
d33d7b00
AM
9653+struct _vx_usage_stat {
9654+ uint64_t user;
9655+ uint64_t nice;
9656+ uint64_t system;
9657+ uint64_t softirq;
9658+ uint64_t irq;
9659+ uint64_t idle;
9660+ uint64_t iowait;
9661+};
d337f35e 9662+
d33d7b00
AM
9663+struct _vx_syslog {
9664+ wait_queue_head_t log_wait;
9665+ spinlock_t logbuf_lock; /* lock for the log buffer */
d337f35e 9666+
d33d7b00
AM
9667+ unsigned long log_start; /* next char to be read by syslog() */
9668+ unsigned long con_start; /* next char to be sent to consoles */
9669+ unsigned long log_end; /* most-recently-written-char + 1 */
9670+ unsigned long logged_chars; /* #chars since last read+clear operation */
d337f35e 9671+
d33d7b00
AM
9672+ char log_buf[1024];
9673+};
d337f35e 9674+
d337f35e 9675+
d33d7b00 9676+/* context sub struct */
d337f35e 9677+
d33d7b00
AM
9678+struct _vx_cvirt {
9679+ atomic_t nr_threads; /* number of current threads */
9680+ atomic_t nr_running; /* number of running threads */
9681+ atomic_t nr_uninterruptible; /* number of uninterruptible threads */
d337f35e 9682+
d33d7b00
AM
9683+ atomic_t nr_onhold; /* processes on hold */
9684+ uint32_t onhold_last; /* jiffies when put on hold */
d337f35e 9685+
cc23e853
AM
9686+ struct timespec64 bias_ts; /* time offset to the host */
9687+ struct timespec64 bias_idle;
9688+ struct timespec64 bias_uptime; /* context creation point */
d33d7b00 9689+ uint64_t bias_clock; /* offset in clock_t */
3bac966d 9690+
d33d7b00
AM
9691+ spinlock_t load_lock; /* lock for the load averages */
9692+ atomic_t load_updates; /* nr of load updates done so far */
9693+ uint32_t load_last; /* last time load was calculated */
9694+ uint32_t load[3]; /* load averages 1,5,15 */
d337f35e 9695+
d33d7b00 9696+ atomic_t total_forks; /* number of forks so far */
d337f35e 9697+
d33d7b00
AM
9698+ struct _vx_syslog syslog;
9699+};
d337f35e 9700+
d33d7b00
AM
9701+struct _vx_cvirt_pc {
9702+ struct _vx_usage_stat cpustat;
9703+};
3bac966d 9704+
d337f35e 9705+
d33d7b00 9706+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 9707+
d33d7b00 9708+static inline void __dump_vx_cvirt(struct _vx_cvirt *cvirt)
3bac966d 9709+{
d33d7b00
AM
9710+ printk("\t_vx_cvirt:\n");
9711+ printk("\t threads: %4d, %4d, %4d, %4d\n",
9712+ atomic_read(&cvirt->nr_threads),
9713+ atomic_read(&cvirt->nr_running),
9714+ atomic_read(&cvirt->nr_uninterruptible),
9715+ atomic_read(&cvirt->nr_onhold));
9716+ /* add rest here */
9717+ printk("\t total_forks = %d\n", atomic_read(&cvirt->total_forks));
3bac966d 9718+}
d337f35e 9719+
d33d7b00 9720+#endif
d337f35e 9721+
4bf69007 9722+#endif /* _VSERVER_CVIRT_DEF_H */
cef7ea10
AM
9723diff -NurpP --minimal linux-4.9.82/include/linux/vserver/debug.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/debug.h
9724--- linux-4.9.82/include/linux/vserver/debug.h 1970-01-01 00:00:00.000000000 +0000
9725+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/debug.h 2018-01-10 02:50:49.000000000 +0000
a4a22af8 9726@@ -0,0 +1,146 @@
4bf69007
AM
9727+#ifndef _VSERVER_DEBUG_H
9728+#define _VSERVER_DEBUG_H
d337f35e 9729+
d337f35e 9730+
dd5f3080 9731+#define VXD_CBIT(n, m) (vs_debug_ ## n & (1 << (m)))
9732+#define VXD_CMIN(n, m) (vs_debug_ ## n > (m))
9733+#define VXD_MASK(n, m) (vs_debug_ ## n & (m))
d337f35e 9734+
d33d7b00
AM
9735+#define VXD_DEV(d) (d), (d)->bd_inode->i_ino, \
9736+ imajor((d)->bd_inode), iminor((d)->bd_inode)
9737+#define VXF_DEV "%p[%lu,%d:%d]"
d337f35e 9738+
d33d7b00
AM
9739+#if defined(CONFIG_QUOTES_UTF8)
9740+#define VS_Q_LQM "\xc2\xbb"
9741+#define VS_Q_RQM "\xc2\xab"
9742+#elif defined(CONFIG_QUOTES_ASCII)
9743+#define VS_Q_LQM "\x27"
9744+#define VS_Q_RQM "\x27"
9745+#else
9746+#define VS_Q_LQM "\xbb"
9747+#define VS_Q_RQM "\xab"
9748+#endif
d337f35e 9749+
d33d7b00 9750+#define VS_Q(f) VS_Q_LQM f VS_Q_RQM
d337f35e
JR
9751+
9752+
d33d7b00
AM
9753+#define vxd_path(p) \
9754+ ({ static char _buffer[PATH_MAX]; \
9755+ d_path(p, _buffer, sizeof(_buffer)); })
d337f35e 9756+
d33d7b00
AM
9757+#define vxd_cond_path(n) \
9758+ ((n) ? vxd_path(&(n)->path) : "<null>" )
d337f35e 9759+
d337f35e 9760+
d33d7b00 9761+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 9762+
dd5f3080 9763+extern unsigned int vs_debug_switch;
9764+extern unsigned int vs_debug_xid;
9765+extern unsigned int vs_debug_nid;
9766+extern unsigned int vs_debug_tag;
9767+extern unsigned int vs_debug_net;
9768+extern unsigned int vs_debug_limit;
9769+extern unsigned int vs_debug_cres;
9770+extern unsigned int vs_debug_dlim;
9771+extern unsigned int vs_debug_quota;
9772+extern unsigned int vs_debug_cvirt;
9773+extern unsigned int vs_debug_space;
9774+extern unsigned int vs_debug_perm;
9775+extern unsigned int vs_debug_misc;
d337f35e 9776+
d337f35e 9777+
d33d7b00
AM
9778+#define VX_LOGLEVEL "vxD: "
9779+#define VX_PROC_FMT "%p: "
9780+#define VX_PROCESS current
d337f35e 9781+
d33d7b00
AM
9782+#define vxdprintk(c, f, x...) \
9783+ do { \
9784+ if (c) \
9785+ printk(VX_LOGLEVEL VX_PROC_FMT f "\n", \
9786+ VX_PROCESS , ##x); \
9787+ } while (0)
d337f35e 9788+
d33d7b00
AM
9789+#define vxlprintk(c, f, x...) \
9790+ do { \
9791+ if (c) \
9792+ printk(VX_LOGLEVEL f " @%s:%d\n", x); \
9793+ } while (0)
d337f35e 9794+
d33d7b00
AM
9795+#define vxfprintk(c, f, x...) \
9796+ do { \
9797+ if (c) \
9798+ printk(VX_LOGLEVEL f " %s@%s:%d\n", x); \
9799+ } while (0)
d337f35e 9800+
d337f35e 9801+
d33d7b00 9802+struct vx_info;
d337f35e 9803+
d33d7b00
AM
9804+void dump_vx_info(struct vx_info *, int);
9805+void dump_vx_info_inactive(int);
d337f35e 9806+
d33d7b00 9807+#else /* CONFIG_VSERVER_DEBUG */
d337f35e 9808+
dd5f3080 9809+#define vs_debug_switch 0
9810+#define vs_debug_xid 0
9811+#define vs_debug_nid 0
9812+#define vs_debug_tag 0
9813+#define vs_debug_net 0
9814+#define vs_debug_limit 0
9815+#define vs_debug_cres 0
9816+#define vs_debug_dlim 0
9817+#define vs_debug_quota 0
9818+#define vs_debug_cvirt 0
9819+#define vs_debug_space 0
9820+#define vs_debug_perm 0
9821+#define vs_debug_misc 0
d337f35e 9822+
d33d7b00
AM
9823+#define vxdprintk(x...) do { } while (0)
9824+#define vxlprintk(x...) do { } while (0)
9825+#define vxfprintk(x...) do { } while (0)
2380c486 9826+
d33d7b00 9827+#endif /* CONFIG_VSERVER_DEBUG */
2380c486 9828+
d337f35e 9829+
d33d7b00 9830+#ifdef CONFIG_VSERVER_WARN
d337f35e 9831+
d33d7b00
AM
9832+#define VX_WARNLEVEL KERN_WARNING "vxW: "
9833+#define VX_WARN_TASK "[" VS_Q("%s") ",%u:#%u|%u|%u] "
9834+#define VX_WARN_XID "[xid #%u] "
9835+#define VX_WARN_NID "[nid #%u] "
9836+#define VX_WARN_TAG "[tag #%u] "
d337f35e 9837+
d33d7b00
AM
9838+#define vxwprintk(c, f, x...) \
9839+ do { \
9840+ if (c) \
9841+ printk(VX_WARNLEVEL f "\n", ##x); \
9842+ } while (0)
d337f35e 9843+
d33d7b00 9844+#else /* CONFIG_VSERVER_WARN */
d337f35e 9845+
d33d7b00 9846+#define vxwprintk(x...) do { } while (0)
d337f35e 9847+
d33d7b00 9848+#endif /* CONFIG_VSERVER_WARN */
d337f35e 9849+
d33d7b00
AM
9850+#define vxwprintk_task(c, f, x...) \
9851+ vxwprintk(c, VX_WARN_TASK f, \
9852+ current->comm, current->pid, \
a4a22af8
AM
9853+ current->xid, current->nid, \
9854+ current->tag, ##x)
d33d7b00
AM
9855+#define vxwprintk_xid(c, f, x...) \
9856+ vxwprintk(c, VX_WARN_XID f, current->xid, x)
9857+#define vxwprintk_nid(c, f, x...) \
9858+ vxwprintk(c, VX_WARN_NID f, current->nid, x)
9859+#define vxwprintk_tag(c, f, x...) \
9860+ vxwprintk(c, VX_WARN_TAG f, current->tag, x)
d337f35e 9861+
d33d7b00
AM
9862+#ifdef CONFIG_VSERVER_DEBUG
9863+#define vxd_assert_lock(l) assert_spin_locked(l)
9864+#define vxd_assert(c, f, x...) vxlprintk(!(c), \
9865+ "assertion [" f "] failed.", ##x, __FILE__, __LINE__)
9866+#else
9867+#define vxd_assert_lock(l) do { } while (0)
9868+#define vxd_assert(c, f, x...) do { } while (0)
9869+#endif
d337f35e 9870+
d337f35e 9871+
4bf69007 9872+#endif /* _VSERVER_DEBUG_H */
cef7ea10
AM
9873diff -NurpP --minimal linux-4.9.82/include/linux/vserver/debug_cmd.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/debug_cmd.h
9874--- linux-4.9.82/include/linux/vserver/debug_cmd.h 1970-01-01 00:00:00.000000000 +0000
9875+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/debug_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
9876@@ -0,0 +1,37 @@
9877+#ifndef _VSERVER_DEBUG_CMD_H
9878+#define _VSERVER_DEBUG_CMD_H
d337f35e 9879+
4bf69007 9880+#include <uapi/vserver/debug_cmd.h>
d337f35e
JR
9881+
9882+
d33d7b00 9883+#ifdef CONFIG_COMPAT
d337f35e 9884+
d33d7b00 9885+#include <asm/compat.h>
d337f35e 9886+
d33d7b00
AM
9887+struct vcmd_read_history_v0_x32 {
9888+ uint32_t index;
9889+ uint32_t count;
9890+ compat_uptr_t data_ptr;
3bac966d 9891+};
d337f35e 9892+
d33d7b00
AM
9893+struct vcmd_read_monitor_v0_x32 {
9894+ uint32_t index;
9895+ uint32_t count;
9896+ compat_uptr_t data_ptr;
3bac966d 9897+};
d337f35e 9898+
d33d7b00 9899+#endif /* CONFIG_COMPAT */
d337f35e 9900+
d33d7b00 9901+extern int vc_dump_history(uint32_t);
d337f35e 9902+
d33d7b00
AM
9903+extern int vc_read_history(uint32_t, void __user *);
9904+extern int vc_read_monitor(uint32_t, void __user *);
d337f35e 9905+
d33d7b00 9906+#ifdef CONFIG_COMPAT
d337f35e 9907+
d33d7b00
AM
9908+extern int vc_read_history_x32(uint32_t, void __user *);
9909+extern int vc_read_monitor_x32(uint32_t, void __user *);
d337f35e 9910+
d33d7b00 9911+#endif /* CONFIG_COMPAT */
d337f35e 9912+
4bf69007 9913+#endif /* _VSERVER_DEBUG_CMD_H */
cef7ea10
AM
9914diff -NurpP --minimal linux-4.9.82/include/linux/vserver/device.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/device.h
9915--- linux-4.9.82/include/linux/vserver/device.h 1970-01-01 00:00:00.000000000 +0000
9916+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/device.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
9917@@ -0,0 +1,9 @@
9918+#ifndef _VSERVER_DEVICE_H
9919+#define _VSERVER_DEVICE_H
d337f35e 9920+
d337f35e 9921+
4bf69007 9922+#include <uapi/vserver/device.h>
d337f35e 9923+
4bf69007 9924+#else /* _VSERVER_DEVICE_H */
d33d7b00 9925+#warning duplicate inclusion
4bf69007 9926+#endif /* _VSERVER_DEVICE_H */
cef7ea10
AM
9927diff -NurpP --minimal linux-4.9.82/include/linux/vserver/device_cmd.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/device_cmd.h
9928--- linux-4.9.82/include/linux/vserver/device_cmd.h 1970-01-01 00:00:00.000000000 +0000
9929+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/device_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
9930@@ -0,0 +1,31 @@
9931+#ifndef _VSERVER_DEVICE_CMD_H
9932+#define _VSERVER_DEVICE_CMD_H
d337f35e 9933+
4bf69007 9934+#include <uapi/vserver/device_cmd.h>
d337f35e 9935+
d337f35e 9936+
d33d7b00 9937+#ifdef CONFIG_COMPAT
d337f35e 9938+
d33d7b00 9939+#include <asm/compat.h>
3bac966d 9940+
d33d7b00
AM
9941+struct vcmd_set_mapping_v0_x32 {
9942+ compat_uptr_t device_ptr;
9943+ compat_uptr_t target_ptr;
9944+ uint32_t flags;
d337f35e
JR
9945+};
9946+
d33d7b00 9947+#endif /* CONFIG_COMPAT */
d337f35e 9948+
d33d7b00 9949+#include <linux/compiler.h>
d337f35e 9950+
d33d7b00
AM
9951+extern int vc_set_mapping(struct vx_info *, void __user *);
9952+extern int vc_unset_mapping(struct vx_info *, void __user *);
d337f35e 9953+
d33d7b00 9954+#ifdef CONFIG_COMPAT
d337f35e 9955+
d33d7b00
AM
9956+extern int vc_set_mapping_x32(struct vx_info *, void __user *);
9957+extern int vc_unset_mapping_x32(struct vx_info *, void __user *);
d337f35e 9958+
d33d7b00 9959+#endif /* CONFIG_COMPAT */
d337f35e 9960+
4bf69007 9961+#endif /* _VSERVER_DEVICE_CMD_H */
cef7ea10
AM
9962diff -NurpP --minimal linux-4.9.82/include/linux/vserver/device_def.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/device_def.h
9963--- linux-4.9.82/include/linux/vserver/device_def.h 1970-01-01 00:00:00.000000000 +0000
9964+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/device_def.h 2018-01-10 02:50:49.000000000 +0000
d33d7b00 9965@@ -0,0 +1,17 @@
4bf69007
AM
9966+#ifndef _VSERVER_DEVICE_DEF_H
9967+#define _VSERVER_DEVICE_DEF_H
d337f35e 9968+
d33d7b00 9969+#include <linux/types.h>
d337f35e 9970+
d33d7b00
AM
9971+struct vx_dmap_target {
9972+ dev_t target;
9973+ uint32_t flags;
9974+};
d337f35e 9975+
d33d7b00
AM
9976+struct _vx_device {
9977+#ifdef CONFIG_VSERVER_DEVICE
9978+ struct vx_dmap_target targets[2];
9979+#endif
9980+};
d337f35e 9981+
4bf69007 9982+#endif /* _VSERVER_DEVICE_DEF_H */
cef7ea10
AM
9983diff -NurpP --minimal linux-4.9.82/include/linux/vserver/dlimit.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/dlimit.h
9984--- linux-4.9.82/include/linux/vserver/dlimit.h 1970-01-01 00:00:00.000000000 +0000
9985+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/dlimit.h 2018-01-10 02:50:49.000000000 +0000
d33d7b00 9986@@ -0,0 +1,54 @@
4bf69007
AM
9987+#ifndef _VSERVER_DLIMIT_H
9988+#define _VSERVER_DLIMIT_H
d337f35e 9989+
d33d7b00 9990+#include "switch.h"
3bac966d 9991+
d337f35e 9992+
3bac966d 9993+#ifdef __KERNEL__
d337f35e 9994+
d33d7b00 9995+/* keep in sync with CDLIM_INFINITY */
d337f35e 9996+
d33d7b00 9997+#define DLIM_INFINITY (~0ULL)
d337f35e 9998+
d33d7b00
AM
9999+#include <linux/spinlock.h>
10000+#include <linux/rcupdate.h>
d337f35e 10001+
d33d7b00 10002+struct super_block;
d337f35e 10003+
d33d7b00
AM
10004+struct dl_info {
10005+ struct hlist_node dl_hlist; /* linked list of contexts */
10006+ struct rcu_head dl_rcu; /* the rcu head */
61333608 10007+ vtag_t dl_tag; /* context tag */
d33d7b00
AM
10008+ atomic_t dl_usecnt; /* usage count */
10009+ atomic_t dl_refcnt; /* reference count */
d337f35e 10010+
d33d7b00 10011+ struct super_block *dl_sb; /* associated superblock */
d337f35e 10012+
d33d7b00 10013+ spinlock_t dl_lock; /* protect the values */
d337f35e 10014+
d33d7b00
AM
10015+ unsigned long long dl_space_used; /* used space in bytes */
10016+ unsigned long long dl_space_total; /* maximum space in bytes */
10017+ unsigned long dl_inodes_used; /* used inodes */
10018+ unsigned long dl_inodes_total; /* maximum inodes */
d337f35e 10019+
d33d7b00
AM
10020+ unsigned int dl_nrlmult; /* non root limit mult */
10021+};
d337f35e 10022+
d33d7b00 10023+struct rcu_head;
d337f35e 10024+
d33d7b00
AM
10025+extern void rcu_free_dl_info(struct rcu_head *);
10026+extern void unhash_dl_info(struct dl_info *);
d337f35e 10027+
61333608 10028+extern struct dl_info *locate_dl_info(struct super_block *, vtag_t);
d337f35e 10029+
d337f35e 10030+
d33d7b00 10031+struct kstatfs;
d337f35e 10032+
d33d7b00 10033+extern void vx_vsi_statfs(struct super_block *, struct kstatfs *);
d337f35e 10034+
d33d7b00 10035+typedef uint64_t dlsize_t;
d337f35e 10036+
d33d7b00 10037+#endif /* __KERNEL__ */
4bf69007 10038+#else /* _VSERVER_DLIMIT_H */
d33d7b00 10039+#warning duplicate inclusion
4bf69007 10040+#endif /* _VSERVER_DLIMIT_H */
cef7ea10
AM
10041diff -NurpP --minimal linux-4.9.82/include/linux/vserver/dlimit_cmd.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/dlimit_cmd.h
10042--- linux-4.9.82/include/linux/vserver/dlimit_cmd.h 1970-01-01 00:00:00.000000000 +0000
10043+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/dlimit_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
10044@@ -0,0 +1,46 @@
10045+#ifndef _VSERVER_DLIMIT_CMD_H
10046+#define _VSERVER_DLIMIT_CMD_H
d337f35e 10047+
4bf69007 10048+#include <uapi/vserver/dlimit_cmd.h>
d337f35e 10049+
d337f35e 10050+
4bf69007 10051+#ifdef CONFIG_COMPAT
d337f35e 10052+
4bf69007 10053+#include <asm/compat.h>
2380c486 10054+
4bf69007
AM
10055+struct vcmd_ctx_dlimit_base_v0_x32 {
10056+ compat_uptr_t name_ptr;
d33d7b00
AM
10057+ uint32_t flags;
10058+};
adc1caaa 10059+
4bf69007
AM
10060+struct vcmd_ctx_dlimit_v0_x32 {
10061+ compat_uptr_t name_ptr;
d33d7b00
AM
10062+ uint32_t space_used; /* used space in kbytes */
10063+ uint32_t space_total; /* maximum space in kbytes */
10064+ uint32_t inodes_used; /* used inodes */
10065+ uint32_t inodes_total; /* maximum inodes */
10066+ uint32_t reserved; /* reserved for root in % */
10067+ uint32_t flags;
10068+};
d337f35e 10069+
4bf69007 10070+#endif /* CONFIG_COMPAT */
d337f35e 10071+
4bf69007 10072+#include <linux/compiler.h>
d337f35e 10073+
4bf69007
AM
10074+extern int vc_add_dlimit(uint32_t, void __user *);
10075+extern int vc_rem_dlimit(uint32_t, void __user *);
d337f35e 10076+
4bf69007
AM
10077+extern int vc_set_dlimit(uint32_t, void __user *);
10078+extern int vc_get_dlimit(uint32_t, void __user *);
d337f35e 10079+
4bf69007 10080+#ifdef CONFIG_COMPAT
d337f35e 10081+
4bf69007
AM
10082+extern int vc_add_dlimit_x32(uint32_t, void __user *);
10083+extern int vc_rem_dlimit_x32(uint32_t, void __user *);
2380c486 10084+
d33d7b00
AM
10085+extern int vc_set_dlimit_x32(uint32_t, void __user *);
10086+extern int vc_get_dlimit_x32(uint32_t, void __user *);
d337f35e 10087+
d33d7b00 10088+#endif /* CONFIG_COMPAT */
d337f35e 10089+
4bf69007 10090+#endif /* _VSERVER_DLIMIT_CMD_H */
cef7ea10
AM
10091diff -NurpP --minimal linux-4.9.82/include/linux/vserver/global.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/global.h
10092--- linux-4.9.82/include/linux/vserver/global.h 1970-01-01 00:00:00.000000000 +0000
10093+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/global.h 2018-01-13 03:51:55.000000000 +0000
cc23e853 10094@@ -0,0 +1,20 @@
4bf69007
AM
10095+#ifndef _VSERVER_GLOBAL_H
10096+#define _VSERVER_GLOBAL_H
d337f35e 10097+
d337f35e 10098+
d33d7b00
AM
10099+extern atomic_t vx_global_ctotal;
10100+extern atomic_t vx_global_cactive;
d337f35e 10101+
d33d7b00
AM
10102+extern atomic_t nx_global_ctotal;
10103+extern atomic_t nx_global_cactive;
d337f35e 10104+
d33d7b00
AM
10105+extern atomic_t vs_global_nsproxy;
10106+extern atomic_t vs_global_fs;
10107+extern atomic_t vs_global_mnt_ns;
10108+extern atomic_t vs_global_uts_ns;
cc23e853 10109+extern atomic_t vs_global_ipc_ns;
d33d7b00
AM
10110+extern atomic_t vs_global_user_ns;
10111+extern atomic_t vs_global_pid_ns;
d337f35e
JR
10112+
10113+
4bf69007 10114+#endif /* _VSERVER_GLOBAL_H */
cef7ea10
AM
10115diff -NurpP --minimal linux-4.9.82/include/linux/vserver/history.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/history.h
10116--- linux-4.9.82/include/linux/vserver/history.h 1970-01-01 00:00:00.000000000 +0000
10117+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/history.h 2018-01-10 02:50:49.000000000 +0000
d33d7b00 10118@@ -0,0 +1,197 @@
4bf69007
AM
10119+#ifndef _VSERVER_HISTORY_H
10120+#define _VSERVER_HISTORY_H
d337f35e 10121+
d337f35e 10122+
d33d7b00
AM
10123+enum {
10124+ VXH_UNUSED = 0,
10125+ VXH_THROW_OOPS = 1,
d337f35e 10126+
d33d7b00
AM
10127+ VXH_GET_VX_INFO,
10128+ VXH_PUT_VX_INFO,
10129+ VXH_INIT_VX_INFO,
10130+ VXH_SET_VX_INFO,
10131+ VXH_CLR_VX_INFO,
10132+ VXH_CLAIM_VX_INFO,
10133+ VXH_RELEASE_VX_INFO,
10134+ VXH_ALLOC_VX_INFO,
10135+ VXH_DEALLOC_VX_INFO,
10136+ VXH_HASH_VX_INFO,
10137+ VXH_UNHASH_VX_INFO,
10138+ VXH_LOC_VX_INFO,
10139+ VXH_LOOKUP_VX_INFO,
10140+ VXH_CREATE_VX_INFO,
10141+};
d337f35e 10142+
d33d7b00
AM
10143+struct _vxhe_vxi {
10144+ struct vx_info *ptr;
10145+ unsigned xid;
10146+ unsigned usecnt;
10147+ unsigned tasks;
10148+};
d337f35e 10149+
d33d7b00
AM
10150+struct _vxhe_set_clr {
10151+ void *data;
10152+};
d337f35e 10153+
d33d7b00
AM
10154+struct _vxhe_loc_lookup {
10155+ unsigned arg;
10156+};
d337f35e 10157+
d33d7b00
AM
10158+struct _vx_hist_entry {
10159+ void *loc;
10160+ unsigned short seq;
10161+ unsigned short type;
10162+ struct _vxhe_vxi vxi;
10163+ union {
10164+ struct _vxhe_set_clr sc;
10165+ struct _vxhe_loc_lookup ll;
10166+ };
3bac966d 10167+};
d337f35e 10168+
d33d7b00 10169+#ifdef CONFIG_VSERVER_HISTORY
d337f35e 10170+
d33d7b00 10171+extern unsigned volatile int vxh_active;
d337f35e 10172+
d33d7b00 10173+struct _vx_hist_entry *vxh_advance(void *loc);
d337f35e 10174+
d337f35e 10175+
d33d7b00
AM
10176+static inline
10177+void __vxh_copy_vxi(struct _vx_hist_entry *entry, struct vx_info *vxi)
10178+{
10179+ entry->vxi.ptr = vxi;
10180+ if (vxi) {
10181+ entry->vxi.usecnt = atomic_read(&vxi->vx_usecnt);
10182+ entry->vxi.tasks = atomic_read(&vxi->vx_tasks);
10183+ entry->vxi.xid = vxi->vx_id;
10184+ }
10185+}
d337f35e 10186+
d337f35e 10187+
d33d7b00 10188+#define __HERE__ current_text_addr()
d337f35e 10189+
d33d7b00
AM
10190+#define __VXH_BODY(__type, __data, __here) \
10191+ struct _vx_hist_entry *entry; \
10192+ \
10193+ preempt_disable(); \
10194+ entry = vxh_advance(__here); \
10195+ __data; \
10196+ entry->type = __type; \
10197+ preempt_enable();
d337f35e 10198+
d337f35e 10199+
d33d7b00 10200+ /* pass vxi only */
d337f35e 10201+
d33d7b00
AM
10202+#define __VXH_SMPL \
10203+ __vxh_copy_vxi(entry, vxi)
d337f35e 10204+
d33d7b00
AM
10205+static inline
10206+void __vxh_smpl(struct vx_info *vxi, int __type, void *__here)
10207+{
10208+ __VXH_BODY(__type, __VXH_SMPL, __here)
10209+}
d337f35e 10210+
d33d7b00 10211+ /* pass vxi and data (void *) */
d337f35e 10212+
d33d7b00
AM
10213+#define __VXH_DATA \
10214+ __vxh_copy_vxi(entry, vxi); \
10215+ entry->sc.data = data
d337f35e 10216+
d33d7b00
AM
10217+static inline
10218+void __vxh_data(struct vx_info *vxi, void *data,
10219+ int __type, void *__here)
3bac966d 10220+{
d33d7b00 10221+ __VXH_BODY(__type, __VXH_DATA, __here)
3bac966d 10222+}
d337f35e 10223+
d33d7b00 10224+ /* pass vxi and arg (long) */
d337f35e 10225+
d33d7b00
AM
10226+#define __VXH_LONG \
10227+ __vxh_copy_vxi(entry, vxi); \
10228+ entry->ll.arg = arg
d337f35e 10229+
d33d7b00
AM
10230+static inline
10231+void __vxh_long(struct vx_info *vxi, long arg,
10232+ int __type, void *__here)
10233+{
10234+ __VXH_BODY(__type, __VXH_LONG, __here)
10235+}
d337f35e 10236+
d337f35e 10237+
d33d7b00
AM
10238+static inline
10239+void __vxh_throw_oops(void *__here)
10240+{
10241+ __VXH_BODY(VXH_THROW_OOPS, {}, __here);
10242+ /* prevent further acquisition */
10243+ vxh_active = 0;
10244+}
d337f35e 10245+
d337f35e 10246+
d33d7b00 10247+#define vxh_throw_oops() __vxh_throw_oops(__HERE__);
d337f35e 10248+
d33d7b00
AM
10249+#define __vxh_get_vx_info(v, h) __vxh_smpl(v, VXH_GET_VX_INFO, h);
10250+#define __vxh_put_vx_info(v, h) __vxh_smpl(v, VXH_PUT_VX_INFO, h);
d337f35e 10251+
d33d7b00
AM
10252+#define __vxh_init_vx_info(v, d, h) \
10253+ __vxh_data(v, d, VXH_INIT_VX_INFO, h);
10254+#define __vxh_set_vx_info(v, d, h) \
10255+ __vxh_data(v, d, VXH_SET_VX_INFO, h);
10256+#define __vxh_clr_vx_info(v, d, h) \
10257+ __vxh_data(v, d, VXH_CLR_VX_INFO, h);
d337f35e 10258+
d33d7b00
AM
10259+#define __vxh_claim_vx_info(v, d, h) \
10260+ __vxh_data(v, d, VXH_CLAIM_VX_INFO, h);
10261+#define __vxh_release_vx_info(v, d, h) \
10262+ __vxh_data(v, d, VXH_RELEASE_VX_INFO, h);
d337f35e 10263+
d33d7b00
AM
10264+#define vxh_alloc_vx_info(v) \
10265+ __vxh_smpl(v, VXH_ALLOC_VX_INFO, __HERE__);
10266+#define vxh_dealloc_vx_info(v) \
10267+ __vxh_smpl(v, VXH_DEALLOC_VX_INFO, __HERE__);
d337f35e 10268+
d33d7b00
AM
10269+#define vxh_hash_vx_info(v) \
10270+ __vxh_smpl(v, VXH_HASH_VX_INFO, __HERE__);
10271+#define vxh_unhash_vx_info(v) \
10272+ __vxh_smpl(v, VXH_UNHASH_VX_INFO, __HERE__);
d337f35e 10273+
d33d7b00
AM
10274+#define vxh_loc_vx_info(v, l) \
10275+ __vxh_long(v, l, VXH_LOC_VX_INFO, __HERE__);
10276+#define vxh_lookup_vx_info(v, l) \
10277+ __vxh_long(v, l, VXH_LOOKUP_VX_INFO, __HERE__);
10278+#define vxh_create_vx_info(v, l) \
10279+ __vxh_long(v, l, VXH_CREATE_VX_INFO, __HERE__);
d337f35e 10280+
d33d7b00 10281+extern void vxh_dump_history(void);
d337f35e 10282+
d337f35e 10283+
d33d7b00 10284+#else /* CONFIG_VSERVER_HISTORY */
2380c486 10285+
d33d7b00 10286+#define __HERE__ 0
d337f35e 10287+
d33d7b00 10288+#define vxh_throw_oops() do { } while (0)
d337f35e 10289+
d33d7b00
AM
10290+#define __vxh_get_vx_info(v, h) do { } while (0)
10291+#define __vxh_put_vx_info(v, h) do { } while (0)
d337f35e 10292+
d33d7b00
AM
10293+#define __vxh_init_vx_info(v, d, h) do { } while (0)
10294+#define __vxh_set_vx_info(v, d, h) do { } while (0)
10295+#define __vxh_clr_vx_info(v, d, h) do { } while (0)
d337f35e 10296+
d33d7b00
AM
10297+#define __vxh_claim_vx_info(v, d, h) do { } while (0)
10298+#define __vxh_release_vx_info(v, d, h) do { } while (0)
3bac966d 10299+
d33d7b00
AM
10300+#define vxh_alloc_vx_info(v) do { } while (0)
10301+#define vxh_dealloc_vx_info(v) do { } while (0)
d337f35e 10302+
d33d7b00
AM
10303+#define vxh_hash_vx_info(v) do { } while (0)
10304+#define vxh_unhash_vx_info(v) do { } while (0)
d337f35e 10305+
d33d7b00
AM
10306+#define vxh_loc_vx_info(v, l) do { } while (0)
10307+#define vxh_lookup_vx_info(v, l) do { } while (0)
10308+#define vxh_create_vx_info(v, l) do { } while (0)
d337f35e 10309+
d33d7b00 10310+#define vxh_dump_history() do { } while (0)
d337f35e 10311+
d337f35e 10312+
d33d7b00 10313+#endif /* CONFIG_VSERVER_HISTORY */
d337f35e 10314+
4bf69007 10315+#endif /* _VSERVER_HISTORY_H */
cef7ea10
AM
10316diff -NurpP --minimal linux-4.9.82/include/linux/vserver/inode.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/inode.h
10317--- linux-4.9.82/include/linux/vserver/inode.h 1970-01-01 00:00:00.000000000 +0000
10318+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/inode.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
10319@@ -0,0 +1,19 @@
10320+#ifndef _VSERVER_INODE_H
10321+#define _VSERVER_INODE_H
d337f35e 10322+
4bf69007 10323+#include <uapi/vserver/inode.h>
d337f35e 10324+
d337f35e 10325+
d33d7b00
AM
10326+#ifdef CONFIG_VSERVER_PROC_SECURE
10327+#define IATTR_PROC_DEFAULT ( IATTR_ADMIN | IATTR_HIDE )
10328+#define IATTR_PROC_SYMLINK ( IATTR_ADMIN )
10329+#else
10330+#define IATTR_PROC_DEFAULT ( IATTR_ADMIN )
10331+#define IATTR_PROC_SYMLINK ( IATTR_ADMIN )
10332+#endif
d337f35e 10333+
d33d7b00 10334+#define vx_hide_check(c, m) (((m) & IATTR_HIDE) ? vx_check(c, m) : 1)
d337f35e 10335+
4bf69007 10336+#else /* _VSERVER_INODE_H */
3bac966d 10337+#warning duplicate inclusion
4bf69007 10338+#endif /* _VSERVER_INODE_H */
cef7ea10
AM
10339diff -NurpP --minimal linux-4.9.82/include/linux/vserver/inode_cmd.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/inode_cmd.h
10340--- linux-4.9.82/include/linux/vserver/inode_cmd.h 1970-01-01 00:00:00.000000000 +0000
10341+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/inode_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
10342@@ -0,0 +1,36 @@
10343+#ifndef _VSERVER_INODE_CMD_H
10344+#define _VSERVER_INODE_CMD_H
d337f35e 10345+
4bf69007 10346+#include <uapi/vserver/inode_cmd.h>
d337f35e 10347+
d337f35e
JR
10348+
10349+
d33d7b00 10350+#ifdef CONFIG_COMPAT
d337f35e 10351+
d33d7b00 10352+#include <asm/compat.h>
d337f35e 10353+
d33d7b00
AM
10354+struct vcmd_ctx_iattr_v1_x32 {
10355+ compat_uptr_t name_ptr;
10356+ uint32_t tag;
10357+ uint32_t flags;
10358+ uint32_t mask;
10359+};
d337f35e 10360+
d33d7b00 10361+#endif /* CONFIG_COMPAT */
d337f35e 10362+
d33d7b00 10363+#include <linux/compiler.h>
d337f35e 10364+
d33d7b00
AM
10365+extern int vc_get_iattr(void __user *);
10366+extern int vc_set_iattr(void __user *);
d337f35e 10367+
d33d7b00
AM
10368+extern int vc_fget_iattr(uint32_t, void __user *);
10369+extern int vc_fset_iattr(uint32_t, void __user *);
d337f35e 10370+
d33d7b00 10371+#ifdef CONFIG_COMPAT
d337f35e 10372+
d33d7b00
AM
10373+extern int vc_get_iattr_x32(void __user *);
10374+extern int vc_set_iattr_x32(void __user *);
d337f35e 10375+
d33d7b00 10376+#endif /* CONFIG_COMPAT */
d337f35e 10377+
4bf69007 10378+#endif /* _VSERVER_INODE_CMD_H */
cef7ea10
AM
10379diff -NurpP --minimal linux-4.9.82/include/linux/vserver/limit.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/limit.h
10380--- linux-4.9.82/include/linux/vserver/limit.h 1970-01-01 00:00:00.000000000 +0000
10381+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/limit.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 10382@@ -0,0 +1,67 @@
4bf69007
AM
10383+#ifndef _VSERVER_LIMIT_H
10384+#define _VSERVER_LIMIT_H
d337f35e 10385+
4bf69007 10386+#include <uapi/vserver/limit.h>
d337f35e 10387+
d337f35e 10388+
d33d7b00 10389+#define VLIM_NOCHECK ((1L << VLIMIT_DENTRY) | (1L << RLIMIT_RSS))
d337f35e 10390+
d33d7b00 10391+/* keep in sync with CRLIM_INFINITY */
d337f35e 10392+
d33d7b00 10393+#define VLIM_INFINITY (~0ULL)
d337f35e 10394+
d33d7b00
AM
10395+#include <asm/atomic.h>
10396+#include <asm/resource.h>
d337f35e 10397+
d33d7b00
AM
10398+#ifndef RLIM_INFINITY
10399+#warning RLIM_INFINITY is undefined
10400+#endif
d337f35e 10401+
d33d7b00 10402+#define __rlim_val(l, r, v) ((l)->res[r].v)
d337f35e 10403+
d33d7b00
AM
10404+#define __rlim_soft(l, r) __rlim_val(l, r, soft)
10405+#define __rlim_hard(l, r) __rlim_val(l, r, hard)
d337f35e 10406+
d33d7b00
AM
10407+#define __rlim_rcur(l, r) __rlim_val(l, r, rcur)
10408+#define __rlim_rmin(l, r) __rlim_val(l, r, rmin)
10409+#define __rlim_rmax(l, r) __rlim_val(l, r, rmax)
d337f35e 10410+
d33d7b00
AM
10411+#define __rlim_lhit(l, r) __rlim_val(l, r, lhit)
10412+#define __rlim_hit(l, r) atomic_inc(&__rlim_lhit(l, r))
d337f35e 10413+
d33d7b00
AM
10414+typedef atomic_long_t rlim_atomic_t;
10415+typedef unsigned long rlim_t;
d337f35e 10416+
d33d7b00
AM
10417+#define __rlim_get(l, r) atomic_long_read(&__rlim_rcur(l, r))
10418+#define __rlim_set(l, r, v) atomic_long_set(&__rlim_rcur(l, r), v)
10419+#define __rlim_inc(l, r) atomic_long_inc(&__rlim_rcur(l, r))
10420+#define __rlim_dec(l, r) atomic_long_dec(&__rlim_rcur(l, r))
10421+#define __rlim_add(l, r, v) atomic_long_add(v, &__rlim_rcur(l, r))
10422+#define __rlim_sub(l, r, v) atomic_long_sub(v, &__rlim_rcur(l, r))
d337f35e 10423+
d337f35e 10424+
d33d7b00
AM
10425+#if (RLIM_INFINITY == VLIM_INFINITY)
10426+#define VX_VLIM(r) ((long long)(long)(r))
10427+#define VX_RLIM(v) ((rlim_t)(v))
3bac966d 10428+#else
d33d7b00
AM
10429+#define VX_VLIM(r) (((r) == RLIM_INFINITY) \
10430+ ? VLIM_INFINITY : (long long)(r))
10431+#define VX_RLIM(v) (((v) == VLIM_INFINITY) \
10432+ ? RLIM_INFINITY : (rlim_t)(v))
3bac966d 10433+#endif
d337f35e 10434+
d33d7b00 10435+struct sysinfo;
d337f35e 10436+
cc23e853 10437+#ifdef CONFIG_MEMCG
d33d7b00
AM
10438+void vx_vsi_meminfo(struct sysinfo *);
10439+void vx_vsi_swapinfo(struct sysinfo *);
10440+long vx_vsi_cached(struct sysinfo *);
cc23e853
AM
10441+#else /* !CONFIG_MEMCG */
10442+#define vx_vsi_meminfo(s) do { } while (0)
10443+#define vx_vsi_swapinfo(s) do { } while (0)
10444+#define vx_vsi_cached(s) (0L)
10445+#endif /* !CONFIG_MEMCG */
d337f35e 10446+
d33d7b00 10447+#define NUM_LIMITS 24
d337f35e 10448+
4bf69007 10449+#endif /* _VSERVER_LIMIT_H */
cef7ea10
AM
10450diff -NurpP --minimal linux-4.9.82/include/linux/vserver/limit_cmd.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/limit_cmd.h
10451--- linux-4.9.82/include/linux/vserver/limit_cmd.h 1970-01-01 00:00:00.000000000 +0000
10452+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/limit_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
10453@@ -0,0 +1,35 @@
10454+#ifndef _VSERVER_LIMIT_CMD_H
10455+#define _VSERVER_LIMIT_CMD_H
d337f35e 10456+
4bf69007 10457+#include <uapi/vserver/limit_cmd.h>
d337f35e 10458+
d337f35e 10459+
d33d7b00 10460+#ifdef CONFIG_IA32_EMULATION
d337f35e 10461+
d33d7b00
AM
10462+struct vcmd_ctx_rlimit_v0_x32 {
10463+ uint32_t id;
10464+ uint64_t minimum;
10465+ uint64_t softlimit;
10466+ uint64_t maximum;
10467+} __attribute__ ((packed));
d337f35e 10468+
d33d7b00 10469+#endif /* CONFIG_IA32_EMULATION */
d337f35e 10470+
d33d7b00 10471+#include <linux/compiler.h>
d337f35e 10472+
d33d7b00
AM
10473+extern int vc_get_rlimit_mask(uint32_t, void __user *);
10474+extern int vc_get_rlimit(struct vx_info *, void __user *);
10475+extern int vc_set_rlimit(struct vx_info *, void __user *);
10476+extern int vc_reset_hits(struct vx_info *, void __user *);
10477+extern int vc_reset_minmax(struct vx_info *, void __user *);
d337f35e 10478+
d33d7b00 10479+extern int vc_rlimit_stat(struct vx_info *, void __user *);
d337f35e 10480+
d33d7b00 10481+#ifdef CONFIG_IA32_EMULATION
d337f35e 10482+
d33d7b00
AM
10483+extern int vc_get_rlimit_x32(struct vx_info *, void __user *);
10484+extern int vc_set_rlimit_x32(struct vx_info *, void __user *);
adc1caaa 10485+
d33d7b00 10486+#endif /* CONFIG_IA32_EMULATION */
d337f35e 10487+
4bf69007 10488+#endif /* _VSERVER_LIMIT_CMD_H */
cef7ea10
AM
10489diff -NurpP --minimal linux-4.9.82/include/linux/vserver/limit_def.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/limit_def.h
10490--- linux-4.9.82/include/linux/vserver/limit_def.h 1970-01-01 00:00:00.000000000 +0000
10491+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/limit_def.h 2018-01-10 02:50:49.000000000 +0000
d33d7b00 10492@@ -0,0 +1,47 @@
4bf69007
AM
10493+#ifndef _VSERVER_LIMIT_DEF_H
10494+#define _VSERVER_LIMIT_DEF_H
d337f35e 10495+
d33d7b00
AM
10496+#include <asm/atomic.h>
10497+#include <asm/resource.h>
d337f35e 10498+
d33d7b00 10499+#include "limit.h"
d337f35e 10500+
d337f35e 10501+
d33d7b00
AM
10502+struct _vx_res_limit {
10503+ rlim_t soft; /* Context soft limit */
10504+ rlim_t hard; /* Context hard limit */
d337f35e 10505+
d33d7b00
AM
10506+ rlim_atomic_t rcur; /* Current value */
10507+ rlim_t rmin; /* Context minimum */
10508+ rlim_t rmax; /* Context maximum */
d337f35e 10509+
d33d7b00
AM
10510+ atomic_t lhit; /* Limit hits */
10511+};
d337f35e 10512+
d33d7b00 10513+/* context sub struct */
2380c486 10514+
d33d7b00
AM
10515+struct _vx_limit {
10516+ struct _vx_res_limit res[NUM_LIMITS];
10517+};
adc1caaa 10518+
d33d7b00 10519+#ifdef CONFIG_VSERVER_DEBUG
adc1caaa 10520+
d33d7b00 10521+static inline void __dump_vx_limit(struct _vx_limit *limit)
3bac966d 10522+{
d33d7b00 10523+ int i;
d337f35e 10524+
d33d7b00
AM
10525+ printk("\t_vx_limit:");
10526+ for (i = 0; i < NUM_LIMITS; i++) {
10527+ printk("\t [%2d] = %8lu %8lu/%8lu, %8ld/%8ld, %8d\n",
10528+ i, (unsigned long)__rlim_get(limit, i),
10529+ (unsigned long)__rlim_rmin(limit, i),
10530+ (unsigned long)__rlim_rmax(limit, i),
10531+ (long)__rlim_soft(limit, i),
10532+ (long)__rlim_hard(limit, i),
10533+ atomic_read(&__rlim_lhit(limit, i)));
10534+ }
3bac966d 10535+}
d337f35e 10536+
d33d7b00 10537+#endif
d337f35e 10538+
4bf69007 10539+#endif /* _VSERVER_LIMIT_DEF_H */
cef7ea10
AM
10540diff -NurpP --minimal linux-4.9.82/include/linux/vserver/limit_int.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/limit_int.h
10541--- linux-4.9.82/include/linux/vserver/limit_int.h 1970-01-01 00:00:00.000000000 +0000
10542+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/limit_int.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
10543@@ -0,0 +1,193 @@
10544+#ifndef _VSERVER_LIMIT_INT_H
10545+#define _VSERVER_LIMIT_INT_H
d337f35e 10546+
d33d7b00
AM
10547+#define VXD_RCRES_COND(r) VXD_CBIT(cres, r)
10548+#define VXD_RLIMIT_COND(r) VXD_CBIT(limit, r)
d337f35e 10549+
d33d7b00 10550+extern const char *vlimit_name[NUM_LIMITS];
2380c486 10551+
d33d7b00
AM
10552+static inline void __vx_acc_cres(struct vx_info *vxi,
10553+ int res, int dir, void *_data, char *_file, int _line)
10554+{
10555+ if (VXD_RCRES_COND(res))
10556+ vxlprintk(1, "vx_acc_cres[%5d,%s,%2d]: %5ld%s (%p)",
10557+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
10558+ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
10559+ (dir > 0) ? "++" : "--", _data, _file, _line);
10560+ if (!vxi)
10561+ return;
d337f35e 10562+
d33d7b00
AM
10563+ if (dir > 0)
10564+ __rlim_inc(&vxi->limit, res);
10565+ else
10566+ __rlim_dec(&vxi->limit, res);
10567+}
d337f35e 10568+
d33d7b00
AM
10569+static inline void __vx_add_cres(struct vx_info *vxi,
10570+ int res, int amount, void *_data, char *_file, int _line)
10571+{
10572+ if (VXD_RCRES_COND(res))
10573+ vxlprintk(1, "vx_add_cres[%5d,%s,%2d]: %5ld += %5d (%p)",
10574+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
10575+ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
10576+ amount, _data, _file, _line);
10577+ if (amount == 0)
10578+ return;
10579+ if (!vxi)
10580+ return;
10581+ __rlim_add(&vxi->limit, res, amount);
10582+}
d337f35e 10583+
3bac966d 10584+static inline
d33d7b00 10585+int __vx_cres_adjust_max(struct _vx_limit *limit, int res, rlim_t value)
3bac966d 10586+{
d33d7b00 10587+ int cond = (value > __rlim_rmax(limit, res));
d337f35e 10588+
d33d7b00
AM
10589+ if (cond)
10590+ __rlim_rmax(limit, res) = value;
10591+ return cond;
3bac966d 10592+}
d337f35e 10593+
3bac966d 10594+static inline
d33d7b00 10595+int __vx_cres_adjust_min(struct _vx_limit *limit, int res, rlim_t value)
3bac966d 10596+{
d33d7b00 10597+ int cond = (value < __rlim_rmin(limit, res));
d337f35e 10598+
d33d7b00
AM
10599+ if (cond)
10600+ __rlim_rmin(limit, res) = value;
10601+ return cond;
3bac966d 10602+}
d337f35e 10603+
3bac966d 10604+static inline
d33d7b00 10605+void __vx_cres_fixup(struct _vx_limit *limit, int res, rlim_t value)
3bac966d 10606+{
d33d7b00
AM
10607+ if (!__vx_cres_adjust_max(limit, res, value))
10608+ __vx_cres_adjust_min(limit, res, value);
3bac966d 10609+}
d337f35e 10610+
2380c486 10611+
d33d7b00
AM
10612+/* return values:
10613+ +1 ... no limit hit
10614+ -1 ... over soft limit
10615+ 0 ... over hard limit */
d337f35e 10616+
d33d7b00
AM
10617+static inline int __vx_cres_avail(struct vx_info *vxi,
10618+ int res, int num, char *_file, int _line)
3bac966d 10619+{
d33d7b00
AM
10620+ struct _vx_limit *limit;
10621+ rlim_t value;
d337f35e 10622+
d33d7b00
AM
10623+ if (VXD_RLIMIT_COND(res))
10624+ vxlprintk(1, "vx_cres_avail[%5d,%s,%2d]: %5ld/%5ld > %5ld + %5d",
10625+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
10626+ (vxi ? (long)__rlim_soft(&vxi->limit, res) : -1),
10627+ (vxi ? (long)__rlim_hard(&vxi->limit, res) : -1),
10628+ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
10629+ num, _file, _line);
10630+ if (!vxi)
3bac966d 10631+ return 1;
d337f35e 10632+
d33d7b00
AM
10633+ limit = &vxi->limit;
10634+ value = __rlim_get(limit, res);
d337f35e 10635+
d33d7b00
AM
10636+ if (!__vx_cres_adjust_max(limit, res, value))
10637+ __vx_cres_adjust_min(limit, res, value);
d337f35e 10638+
d33d7b00 10639+ if (num == 0)
3bac966d 10640+ return 1;
d337f35e 10641+
d33d7b00
AM
10642+ if (__rlim_soft(limit, res) == RLIM_INFINITY)
10643+ return -1;
10644+ if (value + num <= __rlim_soft(limit, res))
10645+ return -1;
d337f35e 10646+
d33d7b00 10647+ if (__rlim_hard(limit, res) == RLIM_INFINITY)
3bac966d 10648+ return 1;
d33d7b00 10649+ if (value + num <= __rlim_hard(limit, res))
3bac966d 10650+ return 1;
d33d7b00
AM
10651+
10652+ __rlim_hit(limit, res);
3bac966d
AM
10653+ return 0;
10654+}
d337f35e 10655+
d337f35e 10656+
d33d7b00 10657+static const int VLA_RSS[] = { RLIMIT_RSS, VLIMIT_ANON, VLIMIT_MAPPED, 0 };
d337f35e 10658+
3bac966d 10659+static inline
d33d7b00 10660+rlim_t __vx_cres_array_sum(struct _vx_limit *limit, const int *array)
3bac966d 10661+{
d33d7b00
AM
10662+ rlim_t value, sum = 0;
10663+ int res;
d337f35e 10664+
d33d7b00
AM
10665+ while ((res = *array++)) {
10666+ value = __rlim_get(limit, res);
10667+ __vx_cres_fixup(limit, res, value);
10668+ sum += value;
10669+ }
10670+ return sum;
3bac966d 10671+}
d337f35e 10672+
3bac966d 10673+static inline
d33d7b00 10674+rlim_t __vx_cres_array_fixup(struct _vx_limit *limit, const int *array)
3bac966d 10675+{
d33d7b00
AM
10676+ rlim_t value = __vx_cres_array_sum(limit, array + 1);
10677+ int res = *array;
d337f35e 10678+
d33d7b00
AM
10679+ if (value == __rlim_get(limit, res))
10680+ return value;
10681+
10682+ __rlim_set(limit, res, value);
10683+ /* now adjust min/max */
10684+ if (!__vx_cres_adjust_max(limit, res, value))
10685+ __vx_cres_adjust_min(limit, res, value);
10686+
10687+ return value;
3bac966d 10688+}
d337f35e 10689+
d33d7b00
AM
10690+static inline int __vx_cres_array_avail(struct vx_info *vxi,
10691+ const int *array, int num, char *_file, int _line)
3bac966d 10692+{
d33d7b00
AM
10693+ struct _vx_limit *limit;
10694+ rlim_t value = 0;
10695+ int res;
10696+
10697+ if (num == 0)
3bac966d 10698+ return 1;
d33d7b00 10699+ if (!vxi)
3bac966d 10700+ return 1;
d337f35e 10701+
d33d7b00
AM
10702+ limit = &vxi->limit;
10703+ res = *array;
10704+ value = __vx_cres_array_sum(limit, array + 1);
d337f35e 10705+
d33d7b00
AM
10706+ __rlim_set(limit, res, value);
10707+ __vx_cres_fixup(limit, res, value);
10708+
10709+ return __vx_cres_avail(vxi, res, num, _file, _line);
3bac966d 10710+}
d337f35e 10711+
d337f35e 10712+
d33d7b00 10713+static inline void vx_limit_fixup(struct _vx_limit *limit, int id)
3bac966d 10714+{
d33d7b00
AM
10715+ rlim_t value;
10716+ int res;
d337f35e 10717+
d33d7b00
AM
10718+ /* complex resources first */
10719+ if ((id < 0) || (id == RLIMIT_RSS))
10720+ __vx_cres_array_fixup(limit, VLA_RSS);
d337f35e 10721+
d33d7b00
AM
10722+ for (res = 0; res < NUM_LIMITS; res++) {
10723+ if ((id > 0) && (res != id))
10724+ continue;
10725+
10726+ value = __rlim_get(limit, res);
10727+ __vx_cres_fixup(limit, res, value);
10728+
10729+ /* not supposed to happen, maybe warn? */
10730+ if (__rlim_rmax(limit, res) > __rlim_hard(limit, res))
10731+ __rlim_rmax(limit, res) = __rlim_hard(limit, res);
10732+ }
3bac966d 10733+}
d337f35e
JR
10734+
10735+
4bf69007 10736+#endif /* _VSERVER_LIMIT_INT_H */
cef7ea10
AM
10737diff -NurpP --minimal linux-4.9.82/include/linux/vserver/monitor.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/monitor.h
10738--- linux-4.9.82/include/linux/vserver/monitor.h 1970-01-01 00:00:00.000000000 +0000
10739+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/monitor.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
10740@@ -0,0 +1,6 @@
10741+#ifndef _VSERVER_MONITOR_H
10742+#define _VSERVER_MONITOR_H
d337f35e 10743+
4bf69007 10744+#include <uapi/vserver/monitor.h>
d337f35e 10745+
4bf69007 10746+#endif /* _VSERVER_MONITOR_H */
cef7ea10
AM
10747diff -NurpP --minimal linux-4.9.82/include/linux/vserver/network.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/network.h
10748--- linux-4.9.82/include/linux/vserver/network.h 1970-01-01 00:00:00.000000000 +0000
10749+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/network.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
10750@@ -0,0 +1,76 @@
10751+#ifndef _VSERVER_NETWORK_H
10752+#define _VSERVER_NETWORK_H
d337f35e 10753+
d337f35e 10754+
4bf69007
AM
10755+#include <linux/list.h>
10756+#include <linux/spinlock.h>
10757+#include <linux/rcupdate.h>
10758+#include <linux/in.h>
10759+#include <linux/in6.h>
10760+#include <asm/atomic.h>
10761+#include <uapi/vserver/network.h>
d337f35e 10762+
4bf69007
AM
10763+struct nx_addr_v4 {
10764+ struct nx_addr_v4 *next;
10765+ struct in_addr ip[2];
10766+ struct in_addr mask;
10767+ uint16_t type;
10768+ uint16_t flags;
10769+};
d337f35e 10770+
4bf69007
AM
10771+struct nx_addr_v6 {
10772+ struct nx_addr_v6 *next;
10773+ struct in6_addr ip;
10774+ struct in6_addr mask;
10775+ uint32_t prefix;
10776+ uint16_t type;
10777+ uint16_t flags;
10778+};
d337f35e 10779+
4bf69007
AM
10780+struct nx_info {
10781+ struct hlist_node nx_hlist; /* linked list of nxinfos */
61333608 10782+ vnid_t nx_id; /* vnet id */
4bf69007
AM
10783+ atomic_t nx_usecnt; /* usage count */
10784+ atomic_t nx_tasks; /* tasks count */
10785+ int nx_state; /* context state */
d337f35e 10786+
4bf69007
AM
10787+ uint64_t nx_flags; /* network flag word */
10788+ uint64_t nx_ncaps; /* network capabilities */
d337f35e 10789+
4bf69007
AM
10790+ spinlock_t addr_lock; /* protect address changes */
10791+ struct in_addr v4_lback; /* Loopback address */
10792+ struct in_addr v4_bcast; /* Broadcast address */
10793+ struct nx_addr_v4 v4; /* First/Single ipv4 address */
10794+#ifdef CONFIG_IPV6
10795+ struct nx_addr_v6 v6; /* First/Single ipv6 address */
10796+#endif
10797+ char nx_name[65]; /* network context name */
d33d7b00 10798+};
d337f35e 10799+
d337f35e 10800+
4bf69007 10801+/* status flags */
d337f35e 10802+
4bf69007
AM
10803+#define NXS_HASHED 0x0001
10804+#define NXS_SHUTDOWN 0x0100
10805+#define NXS_RELEASED 0x8000
d337f35e 10806+
4bf69007 10807+extern struct nx_info *lookup_nx_info(int);
d337f35e 10808+
4bf69007 10809+extern int get_nid_list(int, unsigned int *, int);
61333608 10810+extern int nid_is_hashed(vnid_t);
d337f35e 10811+
4bf69007 10812+extern int nx_migrate_task(struct task_struct *, struct nx_info *);
d337f35e 10813+
4bf69007 10814+extern long vs_net_change(struct nx_info *, unsigned int);
d337f35e 10815+
4bf69007 10816+struct sock;
d337f35e 10817+
d337f35e 10818+
4bf69007
AM
10819+#define NX_IPV4(n) ((n)->v4.type != NXA_TYPE_NONE)
10820+#ifdef CONFIG_IPV6
10821+#define NX_IPV6(n) ((n)->v6.type != NXA_TYPE_NONE)
10822+#else
10823+#define NX_IPV6(n) (0)
10824+#endif
d337f35e 10825+
4bf69007 10826+#endif /* _VSERVER_NETWORK_H */
cef7ea10
AM
10827diff -NurpP --minimal linux-4.9.82/include/linux/vserver/network_cmd.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/network_cmd.h
10828--- linux-4.9.82/include/linux/vserver/network_cmd.h 1970-01-01 00:00:00.000000000 +0000
10829+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/network_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
10830@@ -0,0 +1,37 @@
10831+#ifndef _VSERVER_NETWORK_CMD_H
10832+#define _VSERVER_NETWORK_CMD_H
d337f35e 10833+
4bf69007 10834+#include <uapi/vserver/network_cmd.h>
d337f35e 10835+
4bf69007 10836+extern int vc_task_nid(uint32_t);
d337f35e 10837+
4bf69007 10838+extern int vc_nx_info(struct nx_info *, void __user *);
d337f35e 10839+
4bf69007
AM
10840+extern int vc_net_create(uint32_t, void __user *);
10841+extern int vc_net_migrate(struct nx_info *, void __user *);
d337f35e 10842+
4bf69007
AM
10843+extern int vc_net_add(struct nx_info *, void __user *);
10844+extern int vc_net_remove(struct nx_info *, void __user *);
d337f35e 10845+
4bf69007
AM
10846+extern int vc_net_add_ipv4_v1(struct nx_info *, void __user *);
10847+extern int vc_net_add_ipv4(struct nx_info *, void __user *);
d337f35e 10848+
4bf69007
AM
10849+extern int vc_net_rem_ipv4_v1(struct nx_info *, void __user *);
10850+extern int vc_net_rem_ipv4(struct nx_info *, void __user *);
d337f35e 10851+
4bf69007
AM
10852+extern int vc_net_add_ipv6(struct nx_info *, void __user *);
10853+extern int vc_net_remove_ipv6(struct nx_info *, void __user *);
d337f35e 10854+
4bf69007
AM
10855+extern int vc_add_match_ipv4(struct nx_info *, void __user *);
10856+extern int vc_get_match_ipv4(struct nx_info *, void __user *);
d33d7b00 10857+
4bf69007
AM
10858+extern int vc_add_match_ipv6(struct nx_info *, void __user *);
10859+extern int vc_get_match_ipv6(struct nx_info *, void __user *);
d337f35e 10860+
4bf69007
AM
10861+extern int vc_get_nflags(struct nx_info *, void __user *);
10862+extern int vc_set_nflags(struct nx_info *, void __user *);
d337f35e 10863+
4bf69007
AM
10864+extern int vc_get_ncaps(struct nx_info *, void __user *);
10865+extern int vc_set_ncaps(struct nx_info *, void __user *);
d337f35e 10866+
4bf69007 10867+#endif /* _VSERVER_CONTEXT_CMD_H */
cef7ea10
AM
10868diff -NurpP --minimal linux-4.9.82/include/linux/vserver/percpu.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/percpu.h
10869--- linux-4.9.82/include/linux/vserver/percpu.h 1970-01-01 00:00:00.000000000 +0000
10870+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/percpu.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
10871@@ -0,0 +1,14 @@
10872+#ifndef _VSERVER_PERCPU_H
10873+#define _VSERVER_PERCPU_H
d337f35e 10874+
4bf69007
AM
10875+#include "cvirt_def.h"
10876+#include "sched_def.h"
d337f35e 10877+
4bf69007
AM
10878+struct _vx_percpu {
10879+ struct _vx_cvirt_pc cvirt;
10880+ struct _vx_sched_pc sched;
10881+};
9795bf04 10882+
4bf69007 10883+#define PERCPU_PERCTX (sizeof(struct _vx_percpu))
d337f35e 10884+
4bf69007 10885+#endif /* _VSERVER_PERCPU_H */
cef7ea10
AM
10886diff -NurpP --minimal linux-4.9.82/include/linux/vserver/pid.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/pid.h
10887--- linux-4.9.82/include/linux/vserver/pid.h 1970-01-01 00:00:00.000000000 +0000
10888+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/pid.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
10889@@ -0,0 +1,51 @@
10890+#ifndef _VSERVER_PID_H
10891+#define _VSERVER_PID_H
d337f35e 10892+
4bf69007 10893+/* pid faking stuff */
d337f35e 10894+
4bf69007
AM
10895+#define vx_info_map_pid(v, p) \
10896+ __vx_info_map_pid((v), (p), __func__, __FILE__, __LINE__)
10897+#define vx_info_map_tgid(v,p) vx_info_map_pid(v,p)
10898+#define vx_map_pid(p) vx_info_map_pid(current_vx_info(), p)
10899+#define vx_map_tgid(p) vx_map_pid(p)
d337f35e 10900+
4bf69007
AM
10901+static inline int __vx_info_map_pid(struct vx_info *vxi, int pid,
10902+ const char *func, const char *file, int line)
10903+{
10904+ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
10905+ vxfprintk(VXD_CBIT(cvirt, 2),
10906+ "vx_map_tgid: %p/%llx: %d -> %d",
10907+ vxi, (long long)vxi->vx_flags, pid,
10908+ (pid && pid == vxi->vx_initpid) ? 1 : pid,
10909+ func, file, line);
10910+ if (pid == 0)
10911+ return 0;
10912+ if (pid == vxi->vx_initpid)
10913+ return 1;
10914+ }
10915+ return pid;
10916+}
d337f35e 10917+
4bf69007
AM
10918+#define vx_info_rmap_pid(v, p) \
10919+ __vx_info_rmap_pid((v), (p), __func__, __FILE__, __LINE__)
10920+#define vx_rmap_pid(p) vx_info_rmap_pid(current_vx_info(), p)
10921+#define vx_rmap_tgid(p) vx_rmap_pid(p)
d337f35e 10922+
4bf69007
AM
10923+static inline int __vx_info_rmap_pid(struct vx_info *vxi, int pid,
10924+ const char *func, const char *file, int line)
10925+{
10926+ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
10927+ vxfprintk(VXD_CBIT(cvirt, 2),
10928+ "vx_rmap_tgid: %p/%llx: %d -> %d",
10929+ vxi, (long long)vxi->vx_flags, pid,
10930+ (pid == 1) ? vxi->vx_initpid : pid,
10931+ func, file, line);
10932+ if ((pid == 1) && vxi->vx_initpid)
10933+ return vxi->vx_initpid;
10934+ if (pid == vxi->vx_initpid)
10935+ return ~0U;
10936+ }
10937+ return pid;
10938+}
d337f35e 10939+
4bf69007 10940+#endif
cef7ea10
AM
10941diff -NurpP --minimal linux-4.9.82/include/linux/vserver/sched.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/sched.h
10942--- linux-4.9.82/include/linux/vserver/sched.h 1970-01-01 00:00:00.000000000 +0000
10943+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/sched.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
10944@@ -0,0 +1,23 @@
10945+#ifndef _VSERVER_SCHED_H
10946+#define _VSERVER_SCHED_H
d337f35e 10947+
d337f35e 10948+
d33d7b00 10949+#ifdef __KERNEL__
d337f35e 10950+
4bf69007 10951+struct timespec;
d337f35e 10952+
4bf69007 10953+void vx_vsi_uptime(struct timespec *, struct timespec *);
d337f35e
JR
10954+
10955+
4bf69007 10956+struct vx_info;
d337f35e 10957+
4bf69007 10958+void vx_update_load(struct vx_info *);
d337f35e 10959+
d337f35e 10960+
4bf69007
AM
10961+void vx_update_sched_param(struct _vx_sched *sched,
10962+ struct _vx_sched_pc *sched_pc);
d337f35e 10963+
4bf69007
AM
10964+#endif /* __KERNEL__ */
10965+#else /* _VSERVER_SCHED_H */
10966+#warning duplicate inclusion
10967+#endif /* _VSERVER_SCHED_H */
cef7ea10
AM
10968diff -NurpP --minimal linux-4.9.82/include/linux/vserver/sched_cmd.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/sched_cmd.h
10969--- linux-4.9.82/include/linux/vserver/sched_cmd.h 1970-01-01 00:00:00.000000000 +0000
10970+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/sched_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
10971@@ -0,0 +1,11 @@
10972+#ifndef _VSERVER_SCHED_CMD_H
10973+#define _VSERVER_SCHED_CMD_H
2380c486 10974+
2380c486 10975+
4bf69007
AM
10976+#include <linux/compiler.h>
10977+#include <uapi/vserver/sched_cmd.h>
d337f35e 10978+
4bf69007
AM
10979+extern int vc_set_prio_bias(struct vx_info *, void __user *);
10980+extern int vc_get_prio_bias(struct vx_info *, void __user *);
d337f35e 10981+
4bf69007 10982+#endif /* _VSERVER_SCHED_CMD_H */
cef7ea10
AM
10983diff -NurpP --minimal linux-4.9.82/include/linux/vserver/sched_def.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/sched_def.h
10984--- linux-4.9.82/include/linux/vserver/sched_def.h 1970-01-01 00:00:00.000000000 +0000
10985+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/sched_def.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
10986@@ -0,0 +1,38 @@
10987+#ifndef _VSERVER_SCHED_DEF_H
10988+#define _VSERVER_SCHED_DEF_H
d33d7b00 10989+
4bf69007
AM
10990+#include <linux/spinlock.h>
10991+#include <linux/jiffies.h>
10992+#include <linux/cpumask.h>
10993+#include <asm/atomic.h>
10994+#include <asm/param.h>
d33d7b00 10995+
d337f35e 10996+
4bf69007 10997+/* context sub struct */
d337f35e 10998+
4bf69007
AM
10999+struct _vx_sched {
11000+ int prio_bias; /* bias offset for priority */
d337f35e 11001+
4bf69007
AM
11002+ cpumask_t update; /* CPUs which should update */
11003+};
d337f35e 11004+
4bf69007
AM
11005+struct _vx_sched_pc {
11006+ int prio_bias; /* bias offset for priority */
d337f35e 11007+
4bf69007
AM
11008+ uint64_t user_ticks; /* token tick events */
11009+ uint64_t sys_ticks; /* token tick events */
11010+ uint64_t hold_ticks; /* token ticks paused */
11011+};
d337f35e 11012+
d337f35e 11013+
4bf69007 11014+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 11015+
4bf69007
AM
11016+static inline void __dump_vx_sched(struct _vx_sched *sched)
11017+{
11018+ printk("\t_vx_sched:\n");
11019+ printk("\t priority = %4d\n", sched->prio_bias);
11020+}
d337f35e 11021+
4bf69007
AM
11022+#endif
11023+
11024+#endif /* _VSERVER_SCHED_DEF_H */
cef7ea10
AM
11025diff -NurpP --minimal linux-4.9.82/include/linux/vserver/signal.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/signal.h
11026--- linux-4.9.82/include/linux/vserver/signal.h 1970-01-01 00:00:00.000000000 +0000
11027+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/signal.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11028@@ -0,0 +1,14 @@
11029+#ifndef _VSERVER_SIGNAL_H
11030+#define _VSERVER_SIGNAL_H
d337f35e 11031+
d337f35e 11032+
d33d7b00 11033+#ifdef __KERNEL__
4bf69007
AM
11034+
11035+struct vx_info;
11036+
11037+int vx_info_kill(struct vx_info *, int, int);
d337f35e 11038+
d33d7b00 11039+#endif /* __KERNEL__ */
4bf69007
AM
11040+#else /* _VSERVER_SIGNAL_H */
11041+#warning duplicate inclusion
11042+#endif /* _VSERVER_SIGNAL_H */
cef7ea10
AM
11043diff -NurpP --minimal linux-4.9.82/include/linux/vserver/signal_cmd.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/signal_cmd.h
11044--- linux-4.9.82/include/linux/vserver/signal_cmd.h 1970-01-01 00:00:00.000000000 +0000
11045+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/signal_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11046@@ -0,0 +1,14 @@
11047+#ifndef _VSERVER_SIGNAL_CMD_H
11048+#define _VSERVER_SIGNAL_CMD_H
d337f35e 11049+
4bf69007 11050+#include <uapi/vserver/signal_cmd.h>
d337f35e 11051+
d337f35e 11052+
4bf69007
AM
11053+extern int vc_ctx_kill(struct vx_info *, void __user *);
11054+extern int vc_wait_exit(struct vx_info *, void __user *);
d337f35e
JR
11055+
11056+
4bf69007
AM
11057+extern int vc_get_pflags(uint32_t pid, void __user *);
11058+extern int vc_set_pflags(uint32_t pid, void __user *);
adc1caaa 11059+
4bf69007 11060+#endif /* _VSERVER_SIGNAL_CMD_H */
cef7ea10
AM
11061diff -NurpP --minimal linux-4.9.82/include/linux/vserver/space.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/space.h
11062--- linux-4.9.82/include/linux/vserver/space.h 1970-01-01 00:00:00.000000000 +0000
11063+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/space.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11064@@ -0,0 +1,12 @@
11065+#ifndef _VSERVER_SPACE_H
11066+#define _VSERVER_SPACE_H
d337f35e 11067+
4bf69007 11068+#include <linux/types.h>
d337f35e 11069+
4bf69007 11070+struct vx_info;
d337f35e 11071+
4bf69007 11072+int vx_set_space(struct vx_info *vxi, unsigned long mask, unsigned index);
9f7054f1 11073+
4bf69007
AM
11074+#else /* _VSERVER_SPACE_H */
11075+#warning duplicate inclusion
11076+#endif /* _VSERVER_SPACE_H */
cef7ea10
AM
11077diff -NurpP --minimal linux-4.9.82/include/linux/vserver/space_cmd.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/space_cmd.h
11078--- linux-4.9.82/include/linux/vserver/space_cmd.h 1970-01-01 00:00:00.000000000 +0000
11079+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/space_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11080@@ -0,0 +1,13 @@
11081+#ifndef _VSERVER_SPACE_CMD_H
11082+#define _VSERVER_SPACE_CMD_H
9f7054f1 11083+
4bf69007 11084+#include <uapi/vserver/space_cmd.h>
d337f35e 11085+
d337f35e 11086+
4bf69007
AM
11087+extern int vc_enter_space_v1(struct vx_info *, void __user *);
11088+extern int vc_set_space_v1(struct vx_info *, void __user *);
11089+extern int vc_enter_space(struct vx_info *, void __user *);
11090+extern int vc_set_space(struct vx_info *, void __user *);
11091+extern int vc_get_space_mask(void __user *, int);
d337f35e 11092+
4bf69007 11093+#endif /* _VSERVER_SPACE_CMD_H */
cef7ea10
AM
11094diff -NurpP --minimal linux-4.9.82/include/linux/vserver/switch.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/switch.h
11095--- linux-4.9.82/include/linux/vserver/switch.h 1970-01-01 00:00:00.000000000 +0000
11096+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/switch.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11097@@ -0,0 +1,8 @@
11098+#ifndef _VSERVER_SWITCH_H
11099+#define _VSERVER_SWITCH_H
d337f35e 11100+
d337f35e 11101+
4bf69007
AM
11102+#include <linux/errno.h>
11103+#include <uapi/vserver/switch.h>
2380c486 11104+
4bf69007 11105+#endif /* _VSERVER_SWITCH_H */
cef7ea10
AM
11106diff -NurpP --minimal linux-4.9.82/include/linux/vserver/tag.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/tag.h
11107--- linux-4.9.82/include/linux/vserver/tag.h 1970-01-01 00:00:00.000000000 +0000
11108+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/tag.h 2018-01-10 02:50:49.000000000 +0000
a4a22af8 11109@@ -0,0 +1,160 @@
4bf69007
AM
11110+#ifndef _DX_TAG_H
11111+#define _DX_TAG_H
d337f35e 11112+
4bf69007 11113+#include <linux/types.h>
a4a22af8 11114+#include <linux/uidgid.h>
d337f35e 11115+
d337f35e 11116+
4bf69007 11117+#define DX_TAG(in) (IS_TAGGED(in))
9f7054f1 11118+
d337f35e 11119+
4bf69007
AM
11120+#ifdef CONFIG_TAG_NFSD
11121+#define DX_TAG_NFSD 1
11122+#else
11123+#define DX_TAG_NFSD 0
11124+#endif
2380c486 11125+
2380c486 11126+
4bf69007 11127+#ifdef CONFIG_TAGGING_NONE
d337f35e 11128+
4bf69007
AM
11129+#define MAX_UID 0xFFFFFFFF
11130+#define MAX_GID 0xFFFFFFFF
d337f35e 11131+
4bf69007 11132+#define INOTAG_TAG(cond, uid, gid, tag) (0)
d337f35e 11133+
4bf69007
AM
11134+#define TAGINO_UID(cond, uid, tag) (uid)
11135+#define TAGINO_GID(cond, gid, tag) (gid)
d337f35e 11136+
4bf69007 11137+#endif
d337f35e 11138+
d337f35e 11139+
4bf69007 11140+#ifdef CONFIG_TAGGING_GID16
d337f35e 11141+
4bf69007
AM
11142+#define MAX_UID 0xFFFFFFFF
11143+#define MAX_GID 0x0000FFFF
d337f35e 11144+
4bf69007
AM
11145+#define INOTAG_TAG(cond, uid, gid, tag) \
11146+ ((cond) ? (((gid) >> 16) & 0xFFFF) : 0)
d337f35e 11147+
4bf69007
AM
11148+#define TAGINO_UID(cond, uid, tag) (uid)
11149+#define TAGINO_GID(cond, gid, tag) \
11150+ ((cond) ? (((gid) & 0xFFFF) | ((tag) << 16)) : (gid))
d337f35e 11151+
4bf69007 11152+#endif
d337f35e 11153+
d337f35e 11154+
4bf69007 11155+#ifdef CONFIG_TAGGING_ID24
d337f35e 11156+
4bf69007
AM
11157+#define MAX_UID 0x00FFFFFF
11158+#define MAX_GID 0x00FFFFFF
d337f35e 11159+
4bf69007
AM
11160+#define INOTAG_TAG(cond, uid, gid, tag) \
11161+ ((cond) ? ((((uid) >> 16) & 0xFF00) | (((gid) >> 24) & 0xFF)) : 0)
d337f35e 11162+
4bf69007
AM
11163+#define TAGINO_UID(cond, uid, tag) \
11164+ ((cond) ? (((uid) & 0xFFFFFF) | (((tag) & 0xFF00) << 16)) : (uid))
11165+#define TAGINO_GID(cond, gid, tag) \
11166+ ((cond) ? (((gid) & 0xFFFFFF) | (((tag) & 0x00FF) << 24)) : (gid))
d337f35e 11167+
4bf69007 11168+#endif
d337f35e 11169+
d337f35e 11170+
4bf69007 11171+#ifdef CONFIG_TAGGING_UID16
d337f35e 11172+
4bf69007
AM
11173+#define MAX_UID 0x0000FFFF
11174+#define MAX_GID 0xFFFFFFFF
3bac966d 11175+
4bf69007
AM
11176+#define INOTAG_TAG(cond, uid, gid, tag) \
11177+ ((cond) ? (((uid) >> 16) & 0xFFFF) : 0)
d337f35e 11178+
4bf69007
AM
11179+#define TAGINO_UID(cond, uid, tag) \
11180+ ((cond) ? (((uid) & 0xFFFF) | ((tag) << 16)) : (uid))
11181+#define TAGINO_GID(cond, gid, tag) (gid)
d337f35e 11182+
d33d7b00 11183+#endif
d337f35e
JR
11184+
11185+
4bf69007 11186+#ifdef CONFIG_TAGGING_INTERN
d337f35e 11187+
4bf69007
AM
11188+#define MAX_UID 0xFFFFFFFF
11189+#define MAX_GID 0xFFFFFFFF
d337f35e 11190+
4bf69007
AM
11191+#define INOTAG_TAG(cond, uid, gid, tag) \
11192+ ((cond) ? (tag) : 0)
d337f35e 11193+
4bf69007
AM
11194+#define TAGINO_UID(cond, uid, tag) (uid)
11195+#define TAGINO_GID(cond, gid, tag) (gid)
d337f35e 11196+
4bf69007 11197+#endif
d337f35e 11198+
d337f35e 11199+
4bf69007
AM
11200+#ifndef CONFIG_TAGGING_NONE
11201+#define dx_current_fstag(sb) \
11202+ ((sb)->s_flags & MS_TAGGED ? dx_current_tag() : 0)
11203+#else
11204+#define dx_current_fstag(sb) (0)
11205+#endif
d337f35e 11206+
4bf69007
AM
11207+#ifndef CONFIG_TAGGING_INTERN
11208+#define TAGINO_TAG(cond, tag) (0)
11209+#else
11210+#define TAGINO_TAG(cond, tag) ((cond) ? (tag) : 0)
11211+#endif
d337f35e 11212+
a4a22af8
AM
11213+#define TAGINO_KUID(cond, kuid, ktag) \
11214+ KUIDT_INIT(TAGINO_UID(cond, __kuid_val(kuid), __ktag_val(ktag)))
11215+#define TAGINO_KGID(cond, kgid, ktag) \
11216+ KGIDT_INIT(TAGINO_GID(cond, __kgid_val(kgid), __ktag_val(ktag)))
11217+#define TAGINO_KTAG(cond, ktag) \
11218+ KTAGT_INIT(TAGINO_TAG(cond, __ktag_val(ktag)))
11219+
11220+
4bf69007
AM
11221+#define INOTAG_UID(cond, uid, gid) \
11222+ ((cond) ? ((uid) & MAX_UID) : (uid))
11223+#define INOTAG_GID(cond, uid, gid) \
11224+ ((cond) ? ((gid) & MAX_GID) : (gid))
d337f35e 11225+
a4a22af8
AM
11226+#define INOTAG_KUID(cond, kuid, kgid) \
11227+ KUIDT_INIT(INOTAG_UID(cond, __kuid_val(kuid), __kgid_val(kgid)))
11228+#define INOTAG_KGID(cond, kuid, kgid) \
11229+ KGIDT_INIT(INOTAG_GID(cond, __kuid_val(kuid), __kgid_val(kgid)))
11230+#define INOTAG_KTAG(cond, kuid, kgid, ktag) \
11231+ KTAGT_INIT(INOTAG_TAG(cond, \
11232+ __kuid_val(kuid), __kgid_val(kgid), __ktag_val(ktag)))
11233+
d337f35e 11234+
4bf69007 11235+static inline uid_t dx_map_uid(uid_t uid)
3bac966d 11236+{
4bf69007
AM
11237+ if ((uid > MAX_UID) && (uid != -1))
11238+ uid = -2;
11239+ return (uid & MAX_UID);
d33d7b00 11240+}
d337f35e 11241+
4bf69007
AM
11242+static inline gid_t dx_map_gid(gid_t gid)
11243+{
11244+ if ((gid > MAX_GID) && (gid != -1))
11245+ gid = -2;
11246+ return (gid & MAX_GID);
11247+}
d337f35e 11248+
4bf69007
AM
11249+struct peer_tag {
11250+ int32_t xid;
11251+ int32_t nid;
d33d7b00 11252+};
d337f35e 11253+
4bf69007 11254+#define dx_notagcheck(sb) ((sb) && ((sb)->s_flags & MS_NOTAGCHECK))
2380c486 11255+
61333608 11256+int dx_parse_tag(char *string, vtag_t *tag, int remove, int *mnt_flags,
4bf69007 11257+ unsigned long *flags);
d337f35e 11258+
4bf69007 11259+#ifdef CONFIG_PROPAGATE
d337f35e 11260+
4bf69007 11261+void __dx_propagate_tag(struct nameidata *nd, struct inode *inode);
d337f35e 11262+
4bf69007 11263+#define dx_propagate_tag(n, i) __dx_propagate_tag(n, i)
d337f35e 11264+
4bf69007
AM
11265+#else
11266+#define dx_propagate_tag(n, i) do { } while (0)
11267+#endif
d337f35e 11268+
4bf69007 11269+#endif /* _DX_TAG_H */
cef7ea10
AM
11270diff -NurpP --minimal linux-4.9.82/include/linux/vserver/tag_cmd.h linux-4.9.82-vs2.3.9.7/include/linux/vserver/tag_cmd.h
11271--- linux-4.9.82/include/linux/vserver/tag_cmd.h 1970-01-01 00:00:00.000000000 +0000
11272+++ linux-4.9.82-vs2.3.9.7/include/linux/vserver/tag_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11273@@ -0,0 +1,10 @@
11274+#ifndef _VSERVER_TAG_CMD_H
11275+#define _VSERVER_TAG_CMD_H
d337f35e 11276+
4bf69007 11277+#include <uapi/vserver/tag_cmd.h>
d337f35e 11278+
4bf69007 11279+extern int vc_task_tag(uint32_t);
3bac966d 11280+
4bf69007 11281+extern int vc_tag_migrate(uint32_t);
3bac966d 11282+
4bf69007 11283+#endif /* _VSERVER_TAG_CMD_H */
cef7ea10
AM
11284diff -NurpP --minimal linux-4.9.82/include/net/addrconf.h linux-4.9.82-vs2.3.9.7/include/net/addrconf.h
11285--- linux-4.9.82/include/net/addrconf.h 2018-02-22 21:18:55.000000000 +0000
11286+++ linux-4.9.82-vs2.3.9.7/include/net/addrconf.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 11287@@ -85,7 +85,7 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str
c2e5f7c8
JR
11288
11289 int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev,
11290 const struct in6_addr *daddr, unsigned int srcprefs,
11291- struct in6_addr *saddr);
11292+ struct in6_addr *saddr, struct nx_info *nxi);
11293 int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
bb20add7 11294 u32 banned_flags);
c2e5f7c8 11295 int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
cef7ea10
AM
11296diff -NurpP --minimal linux-4.9.82/include/net/af_unix.h linux-4.9.82-vs2.3.9.7/include/net/af_unix.h
11297--- linux-4.9.82/include/net/af_unix.h 2016-12-11 19:17:54.000000000 +0000
11298+++ linux-4.9.82-vs2.3.9.7/include/net/af_unix.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11299@@ -4,6 +4,7 @@
11300 #include <linux/socket.h>
11301 #include <linux/un.h>
11302 #include <linux/mutex.h>
cc23e853 11303+// #include <linux/vs_base.h>
4bf69007
AM
11304 #include <net/sock.h>
11305
cc23e853 11306 void unix_inflight(struct user_struct *user, struct file *fp);
cef7ea10
AM
11307diff -NurpP --minimal linux-4.9.82/include/net/inet_timewait_sock.h linux-4.9.82-vs2.3.9.7/include/net/inet_timewait_sock.h
11308--- linux-4.9.82/include/net/inet_timewait_sock.h 2016-12-11 19:17:54.000000000 +0000
11309+++ linux-4.9.82-vs2.3.9.7/include/net/inet_timewait_sock.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 11310@@ -71,6 +71,10 @@ struct inet_timewait_sock {
b00e13aa 11311 #define tw_num __tw_common.skc_num
cc23e853
AM
11312 #define tw_cookie __tw_common.skc_cookie
11313 #define tw_dr __tw_common.skc_tw_dr
4bf69007
AM
11314+#define tw_xid __tw_common.skc_xid
11315+#define tw_vx_info __tw_common.skc_vx_info
11316+#define tw_nid __tw_common.skc_nid
11317+#define tw_nx_info __tw_common.skc_nx_info
b00e13aa 11318
4bf69007
AM
11319 int tw_timeout;
11320 volatile unsigned char tw_substate;
cef7ea10
AM
11321diff -NurpP --minimal linux-4.9.82/include/net/ip6_route.h linux-4.9.82-vs2.3.9.7/include/net/ip6_route.h
11322--- linux-4.9.82/include/net/ip6_route.h 2018-02-22 21:18:55.000000000 +0000
11323+++ linux-4.9.82-vs2.3.9.7/include/net/ip6_route.h 2018-01-13 06:10:51.000000000 +0000
cc23e853
AM
11324@@ -26,6 +26,7 @@ struct route_info {
11325 #include <linux/ip.h>
11326 #include <linux/ipv6.h>
11327 #include <linux/route.h>
11328+#include <linux/vs_inet6.h>
11329
11330 #define RT6_LOOKUP_F_IFACE 0x00000001
11331 #define RT6_LOOKUP_F_REACHABLE 0x00000002
11332@@ -98,17 +99,19 @@ int ip6_del_rt(struct rt6_info *);
11333 static inline int ip6_route_get_saddr(struct net *net, struct rt6_info *rt,
11334 const struct in6_addr *daddr,
11335 unsigned int prefs,
11336- struct in6_addr *saddr)
11337+ struct in6_addr *saddr,
11338+ struct nx_info *nxi)
11339 {
11340 struct inet6_dev *idev =
11341 rt ? ip6_dst_idev((struct dst_entry *)rt) : NULL;
11342 int err = 0;
11343
11344- if (rt && rt->rt6i_prefsrc.plen)
11345+ if (rt && rt->rt6i_prefsrc.plen && (!nxi ||
11346+ v6_addr_in_nx_info(nxi, &rt->rt6i_prefsrc.addr, NXA_TYPE_ADDR)))
11347 *saddr = rt->rt6i_prefsrc.addr;
11348 else
11349 err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
11350- daddr, prefs, saddr);
11351+ daddr, prefs, saddr, nxi);
11352
11353 return err;
11354 }
cef7ea10
AM
11355diff -NurpP --minimal linux-4.9.82/include/net/route.h linux-4.9.82-vs2.3.9.7/include/net/route.h
11356--- linux-4.9.82/include/net/route.h 2016-12-11 19:17:54.000000000 +0000
11357+++ linux-4.9.82-vs2.3.9.7/include/net/route.h 2018-01-10 07:57:27.000000000 +0000
cc23e853 11358@@ -225,6 +225,9 @@ static inline void ip_rt_put(struct rtab
b00e13aa 11359 dst_release(&rt->dst);
4bf69007
AM
11360 }
11361
11362+#include <linux/vs_base.h>
11363+#include <linux/vs_inet.h>
d337f35e 11364+
4bf69007
AM
11365 #define IPTOS_RT_MASK (IPTOS_TOS_MASK & ~3)
11366
11367 extern const __u8 ip_tos2prio[16];
cc23e853 11368@@ -272,6 +275,9 @@ static inline void ip_route_connect_init
4bf69007
AM
11369 protocol, flow_flags, dst, src, dport, sport);
11370 }
11371
11372+extern struct rtable *ip_v4_find_src(struct net *net, struct nx_info *,
11373+ struct flowi4 *);
d337f35e 11374+
4bf69007
AM
11375 static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
11376 __be32 dst, __be32 src, u32 tos,
11377 int oif, u8 protocol,
cc23e853 11378@@ -280,11 +286,25 @@ static inline struct rtable *ip_route_co
4bf69007
AM
11379 {
11380 struct net *net = sock_net(sk);
11381 struct rtable *rt;
11382+ struct nx_info *nx_info = current_nx_info();
11383
11384 ip_route_connect_init(fl4, dst, src, tos, oif, protocol,
f15949f2 11385 sport, dport, sk);
4bf69007
AM
11386
11387- if (!dst || !src) {
11388+ if (sk)
11389+ nx_info = sk->sk_nx_info;
d337f35e 11390+
4bf69007
AM
11391+ vxdprintk(VXD_CBIT(net, 4),
11392+ "ip_route_connect(%p) %p,%p;%lx",
11393+ sk, nx_info, sk->sk_socket,
11394+ (sk->sk_socket?sk->sk_socket->flags:0));
d337f35e 11395+
4bf69007
AM
11396+ rt = ip_v4_find_src(net, nx_info, fl4);
11397+ if (IS_ERR(rt))
11398+ return rt;
11399+ ip_rt_put(rt);
d337f35e 11400+
4bf69007
AM
11401+ if (!fl4->daddr || !fl4->saddr) {
11402 rt = __ip_route_output_key(net, fl4);
11403 if (IS_ERR(rt))
11404 return rt;
cef7ea10
AM
11405diff -NurpP --minimal linux-4.9.82/include/net/sock.h linux-4.9.82-vs2.3.9.7/include/net/sock.h
11406--- linux-4.9.82/include/net/sock.h 2018-02-22 21:18:55.000000000 +0000
11407+++ linux-4.9.82-vs2.3.9.7/include/net/sock.h 2018-01-10 02:50:49.000000000 +0000
cc23e853
AM
11408@@ -187,6 +187,10 @@ struct sock_common {
11409 struct in6_addr skc_v6_daddr;
11410 struct in6_addr skc_v6_rcv_saddr;
4bf69007 11411 #endif
61333608 11412+ vxid_t skc_xid;
4bf69007 11413+ struct vx_info *skc_vx_info;
61333608 11414+ vnid_t skc_nid;
4bf69007 11415+ struct nx_info *skc_nx_info;
c2e5f7c8 11416
cc23e853
AM
11417 atomic64_t skc_cookie;
11418
11419@@ -336,8 +340,12 @@ struct sock {
4bf69007
AM
11420 #define sk_prot __sk_common.skc_prot
11421 #define sk_net __sk_common.skc_net
c2e5f7c8
JR
11422 #define sk_v6_daddr __sk_common.skc_v6_daddr
11423-#define sk_v6_rcv_saddr __sk_common.skc_v6_rcv_saddr
11424+#define sk_v6_rcv_saddr __sk_common.skc_v6_rcv_saddr
cc23e853 11425 #define sk_cookie __sk_common.skc_cookie
4bf69007
AM
11426+#define sk_xid __sk_common.skc_xid
11427+#define sk_vx_info __sk_common.skc_vx_info
11428+#define sk_nid __sk_common.skc_nid
11429+#define sk_nx_info __sk_common.skc_nx_info
cc23e853
AM
11430 #define sk_incoming_cpu __sk_common.skc_incoming_cpu
11431 #define sk_flags __sk_common.skc_flags
11432 #define sk_rxhash __sk_common.skc_rxhash
cef7ea10
AM
11433diff -NurpP --minimal linux-4.9.82/include/uapi/Kbuild linux-4.9.82-vs2.3.9.7/include/uapi/Kbuild
11434--- linux-4.9.82/include/uapi/Kbuild 2016-12-11 19:17:54.000000000 +0000
11435+++ linux-4.9.82-vs2.3.9.7/include/uapi/Kbuild 2018-01-10 02:50:49.000000000 +0000
bb20add7 11436@@ -13,3 +13,4 @@ header-y += drm/
4bf69007
AM
11437 header-y += xen/
11438 header-y += scsi/
bb20add7 11439 header-y += misc/
4bf69007 11440+header-y += vserver/
cef7ea10
AM
11441diff -NurpP --minimal linux-4.9.82/include/uapi/linux/btrfs_tree.h linux-4.9.82-vs2.3.9.7/include/uapi/linux/btrfs_tree.h
11442--- linux-4.9.82/include/uapi/linux/btrfs_tree.h 2016-12-11 19:17:54.000000000 +0000
11443+++ linux-4.9.82-vs2.3.9.7/include/uapi/linux/btrfs_tree.h 2018-01-13 01:45:34.000000000 +0000
cc23e853
AM
11444@@ -563,11 +563,14 @@ struct btrfs_inode_item {
11445 /* modification sequence number for NFS */
11446 __le64 sequence;
11447
11448+ __le16 tag;
11449 /*
11450 * a little future expansion, for more than this we can
11451 * just grow the inode item and version it
11452 */
11453- __le64 reserved[4];
11454+ __le16 reserved16;
11455+ __le32 reserved32;
11456+ __le64 reserved[3];
11457 struct btrfs_timespec atime;
11458 struct btrfs_timespec ctime;
11459 struct btrfs_timespec mtime;
cef7ea10
AM
11460diff -NurpP --minimal linux-4.9.82/include/uapi/linux/capability.h linux-4.9.82-vs2.3.9.7/include/uapi/linux/capability.h
11461--- linux-4.9.82/include/uapi/linux/capability.h 2016-12-11 19:17:54.000000000 +0000
11462+++ linux-4.9.82-vs2.3.9.7/include/uapi/linux/capability.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 11463@@ -257,6 +257,7 @@ struct vfs_cap_data {
4bf69007
AM
11464 arbitrary SCSI commands */
11465 /* Allow setting encryption key on loopback filesystem */
11466 /* Allow setting zone reclaim policy */
11467+/* Allow the selection of a security context */
11468
11469 #define CAP_SYS_ADMIN 21
11470
cc23e853 11471@@ -352,7 +353,12 @@ struct vfs_cap_data {
4bf69007 11472
bb20add7 11473 #define CAP_LAST_CAP CAP_AUDIT_READ
4bf69007
AM
11474
11475-#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
11476+/* Allow context manipulations */
11477+/* Allow changing context info on files */
d337f35e 11478+
4bf69007 11479+#define CAP_CONTEXT 63
d337f35e 11480+
4bf69007
AM
11481+#define cap_valid(x) ((x) >= 0 && ((x) <= CAP_LAST_CAP || (x) == CAP_CONTEXT))
11482
11483 /*
11484 * Bit location of each capability (used by user-space library and kernel)
cef7ea10
AM
11485diff -NurpP --minimal linux-4.9.82/include/uapi/linux/fs.h linux-4.9.82-vs2.3.9.7/include/uapi/linux/fs.h
11486--- linux-4.9.82/include/uapi/linux/fs.h 2018-02-22 21:18:55.000000000 +0000
11487+++ linux-4.9.82-vs2.3.9.7/include/uapi/linux/fs.h 2018-01-10 08:09:10.000000000 +0000
cc23e853 11488@@ -130,6 +130,9 @@ struct inodes_stat_t {
4bf69007
AM
11489 #define MS_I_VERSION (1<<23) /* Update inode I_version field */
11490 #define MS_STRICTATIME (1<<24) /* Always perform atime updates */
cc23e853 11491 #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */
b00e13aa
AM
11492+#define MS_TAGGED (1<<8) /* use generic inode tagging */
11493+#define MS_NOTAGCHECK (1<<9) /* don't check tags */
cc23e853 11494+#define MS_TAGID (1<<26) /* use specific tag for this mount */
b00e13aa
AM
11495
11496 /* These sb flags are internal to the kernel */
cc23e853
AM
11497 #define MS_SUBMOUNT (1<<26)
11498@@ -313,13 +316,16 @@ struct fscrypt_policy {
11499 #define FS_EA_INODE_FL 0x00200000 /* Inode used for large EA */
11500 #define FS_EOFBLOCKS_FL 0x00400000 /* Reserved for ext4 */
4bf69007
AM
11501 #define FS_NOCOW_FL 0x00800000 /* Do not cow file */
11502+#define FS_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */
cc23e853
AM
11503 #define FS_INLINE_DATA_FL 0x10000000 /* Reserved for ext4 */
11504 #define FS_PROJINHERIT_FL 0x20000000 /* Create with parents projid */
4bf69007
AM
11505 #define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
11506
11507-#define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
11508-#define FS_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
11509+#define FS_BARRIER_FL 0x04000000 /* Barrier for chroot() */
11510+#define FS_COW_FL 0x20000000 /* Copy on Write marker */
11511
11512+#define FS_FL_USER_VISIBLE 0x0103DFFF /* User visible flags */
11513+#define FS_FL_USER_MODIFIABLE 0x010380FF /* User modifiable flags */
11514
11515 #define SYNC_FILE_RANGE_WAIT_BEFORE 1
11516 #define SYNC_FILE_RANGE_WRITE 2
cef7ea10
AM
11517diff -NurpP --minimal linux-4.9.82/include/uapi/linux/gfs2_ondisk.h linux-4.9.82-vs2.3.9.7/include/uapi/linux/gfs2_ondisk.h
11518--- linux-4.9.82/include/uapi/linux/gfs2_ondisk.h 2016-12-11 19:17:54.000000000 +0000
11519+++ linux-4.9.82-vs2.3.9.7/include/uapi/linux/gfs2_ondisk.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11520@@ -225,6 +225,9 @@ enum {
11521 gfs2fl_Sync = 8,
11522 gfs2fl_System = 9,
11523 gfs2fl_TopLevel = 10,
11524+ gfs2fl_IXUnlink = 16,
11525+ gfs2fl_Barrier = 17,
11526+ gfs2fl_Cow = 18,
11527 gfs2fl_TruncInProg = 29,
11528 gfs2fl_InheritDirectio = 30,
11529 gfs2fl_InheritJdata = 31,
11530@@ -242,6 +245,9 @@ enum {
11531 #define GFS2_DIF_SYNC 0x00000100
11532 #define GFS2_DIF_SYSTEM 0x00000200 /* New in gfs2 */
11533 #define GFS2_DIF_TOPDIR 0x00000400 /* New in gfs2 */
11534+#define GFS2_DIF_IXUNLINK 0x00010000
11535+#define GFS2_DIF_BARRIER 0x00020000
11536+#define GFS2_DIF_COW 0x00040000
11537 #define GFS2_DIF_TRUNC_IN_PROG 0x20000000 /* New in gfs2 */
11538 #define GFS2_DIF_INHERIT_DIRECTIO 0x40000000 /* only in gfs1 */
11539 #define GFS2_DIF_INHERIT_JDATA 0x80000000
cef7ea10
AM
11540diff -NurpP --minimal linux-4.9.82/include/uapi/linux/if_tun.h linux-4.9.82-vs2.3.9.7/include/uapi/linux/if_tun.h
11541--- linux-4.9.82/include/uapi/linux/if_tun.h 2016-12-11 19:17:54.000000000 +0000
11542+++ linux-4.9.82-vs2.3.9.7/include/uapi/linux/if_tun.h 2018-01-10 02:50:49.000000000 +0000
cc23e853
AM
11543@@ -56,6 +56,7 @@
11544 */
11545 #define TUNSETVNETBE _IOW('T', 222, int)
11546 #define TUNGETVNETBE _IOR('T', 223, int)
11547+#define TUNSETNID _IOW('T', 224, int)
4bf69007
AM
11548
11549 /* TUNSETIFF ifr flags */
11550 #define IFF_TUN 0x0001
cef7ea10
AM
11551diff -NurpP --minimal linux-4.9.82/include/uapi/linux/major.h linux-4.9.82-vs2.3.9.7/include/uapi/linux/major.h
11552--- linux-4.9.82/include/uapi/linux/major.h 2016-12-11 19:17:54.000000000 +0000
11553+++ linux-4.9.82-vs2.3.9.7/include/uapi/linux/major.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11554@@ -15,6 +15,7 @@
11555 #define HD_MAJOR IDE0_MAJOR
11556 #define PTY_SLAVE_MAJOR 3
11557 #define TTY_MAJOR 4
11558+#define VROOT_MAJOR 4
11559 #define TTYAUX_MAJOR 5
11560 #define LP_MAJOR 6
11561 #define VCS_MAJOR 7
cef7ea10
AM
11562diff -NurpP --minimal linux-4.9.82/include/uapi/linux/nfs_mount.h linux-4.9.82-vs2.3.9.7/include/uapi/linux/nfs_mount.h
11563--- linux-4.9.82/include/uapi/linux/nfs_mount.h 2016-12-11 19:17:54.000000000 +0000
11564+++ linux-4.9.82-vs2.3.9.7/include/uapi/linux/nfs_mount.h 2018-01-10 02:50:49.000000000 +0000
4bf69007 11565@@ -63,7 +63,8 @@ struct nfs_mount_data {
c2e5f7c8 11566 #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 non-text parsed mount data only */
4bf69007
AM
11567 #define NFS_MOUNT_NORDIRPLUS 0x4000 /* 5 */
11568 #define NFS_MOUNT_UNSHARED 0x8000 /* 5 */
11569-#define NFS_MOUNT_FLAGMASK 0xFFFF
11570+#define NFS_MOUNT_TAGGED 0x10000 /* context tagging */
11571+#define NFS_MOUNT_FLAGMASK 0x1FFFF
11572
11573 /* The following are for internal use only */
11574 #define NFS_MOUNT_LOOKUP_CACHE_NONEG 0x10000
cef7ea10
AM
11575diff -NurpP --minimal linux-4.9.82/include/uapi/linux/reboot.h linux-4.9.82-vs2.3.9.7/include/uapi/linux/reboot.h
11576--- linux-4.9.82/include/uapi/linux/reboot.h 2016-12-11 19:17:54.000000000 +0000
11577+++ linux-4.9.82-vs2.3.9.7/include/uapi/linux/reboot.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11578@@ -33,7 +33,7 @@
11579 #define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
11580 #define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2
11581 #define LINUX_REBOOT_CMD_KEXEC 0x45584543
11582-
11583+#define LINUX_REBOOT_CMD_OOM 0xDEADBEEF
11584
11585
11586 #endif /* _UAPI_LINUX_REBOOT_H */
cef7ea10
AM
11587diff -NurpP --minimal linux-4.9.82/include/uapi/linux/sysctl.h linux-4.9.82-vs2.3.9.7/include/uapi/linux/sysctl.h
11588--- linux-4.9.82/include/uapi/linux/sysctl.h 2016-12-11 19:17:54.000000000 +0000
11589+++ linux-4.9.82-vs2.3.9.7/include/uapi/linux/sysctl.h 2018-01-10 02:50:49.000000000 +0000
cc23e853 11590@@ -58,6 +58,7 @@ enum
4bf69007
AM
11591 CTL_ABI=9, /* Binary emulation */
11592 CTL_CPU=10, /* CPU stuff (speed scaling, etc) */
11593 CTL_ARLAN=254, /* arlan wireless driver */
11594+ CTL_VSERVER=4242, /* Linux-VServer debug */
11595 CTL_S390DBF=5677, /* s390 debug */
11596 CTL_SUNRPC=7249, /* sunrpc debug */
11597 CTL_PM=9899, /* frv power management */
cc23e853 11598@@ -92,6 +93,7 @@ enum
4bf69007
AM
11599
11600 KERN_PANIC=15, /* int: panic timeout */
11601 KERN_REALROOTDEV=16, /* real root device to mount after initrd */
11602+ KERN_VSHELPER=17, /* string: path to vshelper policy agent */
11603
11604 KERN_SPARC_REBOOT=21, /* reboot command on Sparc */
11605 KERN_CTLALTDEL=22, /* int: allow ctl-alt-del to reboot */
cef7ea10
AM
11606diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/Kbuild linux-4.9.82-vs2.3.9.7/include/uapi/vserver/Kbuild
11607--- linux-4.9.82/include/uapi/vserver/Kbuild 1970-01-01 00:00:00.000000000 +0000
11608+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/Kbuild 2018-01-10 02:50:49.000000000 +0000
4bf69007 11609@@ -0,0 +1,9 @@
d337f35e 11610+
4bf69007
AM
11611+header-y += context_cmd.h network_cmd.h space_cmd.h \
11612+ cacct_cmd.h cvirt_cmd.h limit_cmd.h dlimit_cmd.h \
11613+ inode_cmd.h tag_cmd.h sched_cmd.h signal_cmd.h \
11614+ debug_cmd.h device_cmd.h
2380c486 11615+
4bf69007
AM
11616+header-y += switch.h context.h network.h monitor.h \
11617+ limit.h inode.h device.h
2380c486 11618+
cef7ea10
AM
11619diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/cacct_cmd.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/cacct_cmd.h
11620--- linux-4.9.82/include/uapi/vserver/cacct_cmd.h 1970-01-01 00:00:00.000000000 +0000
11621+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/cacct_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11622@@ -0,0 +1,15 @@
11623+#ifndef _UAPI_VS_CACCT_CMD_H
11624+#define _UAPI_VS_CACCT_CMD_H
d337f35e
JR
11625+
11626+
4bf69007 11627+/* virtual host info name commands */
d337f35e 11628+
4bf69007 11629+#define VCMD_sock_stat VC_CMD(VSTAT, 5, 0)
d337f35e 11630+
4bf69007
AM
11631+struct vcmd_sock_stat_v0 {
11632+ uint32_t field;
11633+ uint32_t count[3];
11634+ uint64_t total[3];
11635+};
d337f35e 11636+
4bf69007 11637+#endif /* _UAPI_VS_CACCT_CMD_H */
cef7ea10
AM
11638diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/context.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/context.h
11639--- linux-4.9.82/include/uapi/vserver/context.h 1970-01-01 00:00:00.000000000 +0000
11640+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/context.h 2018-01-10 02:50:49.000000000 +0000
b00e13aa 11641@@ -0,0 +1,81 @@
4bf69007
AM
11642+#ifndef _UAPI_VS_CONTEXT_H
11643+#define _UAPI_VS_CONTEXT_H
d337f35e 11644+
4bf69007
AM
11645+#include <linux/types.h>
11646+#include <linux/capability.h>
d337f35e
JR
11647+
11648+
4bf69007 11649+/* context flags */
d337f35e 11650+
4bf69007
AM
11651+#define VXF_INFO_SCHED 0x00000002
11652+#define VXF_INFO_NPROC 0x00000004
11653+#define VXF_INFO_PRIVATE 0x00000008
d337f35e 11654+
4bf69007
AM
11655+#define VXF_INFO_INIT 0x00000010
11656+#define VXF_INFO_HIDE 0x00000020
11657+#define VXF_INFO_ULIMIT 0x00000040
11658+#define VXF_INFO_NSPACE 0x00000080
d337f35e 11659+
4bf69007
AM
11660+#define VXF_SCHED_HARD 0x00000100
11661+#define VXF_SCHED_PRIO 0x00000200
11662+#define VXF_SCHED_PAUSE 0x00000400
2380c486 11663+
4bf69007
AM
11664+#define VXF_VIRT_MEM 0x00010000
11665+#define VXF_VIRT_UPTIME 0x00020000
11666+#define VXF_VIRT_CPU 0x00040000
11667+#define VXF_VIRT_LOAD 0x00080000
11668+#define VXF_VIRT_TIME 0x00100000
d337f35e 11669+
4bf69007
AM
11670+#define VXF_HIDE_MOUNT 0x01000000
11671+/* was VXF_HIDE_NETIF 0x02000000 */
11672+#define VXF_HIDE_VINFO 0x04000000
d337f35e 11673+
4bf69007
AM
11674+#define VXF_STATE_SETUP (1ULL << 32)
11675+#define VXF_STATE_INIT (1ULL << 33)
11676+#define VXF_STATE_ADMIN (1ULL << 34)
d337f35e 11677+
4bf69007
AM
11678+#define VXF_SC_HELPER (1ULL << 36)
11679+#define VXF_REBOOT_KILL (1ULL << 37)
11680+#define VXF_PERSISTENT (1ULL << 38)
d337f35e 11681+
4bf69007
AM
11682+#define VXF_FORK_RSS (1ULL << 48)
11683+#define VXF_PROLIFIC (1ULL << 49)
d337f35e 11684+
4bf69007 11685+#define VXF_IGNEG_NICE (1ULL << 52)
d337f35e 11686+
4bf69007 11687+#define VXF_ONE_TIME (0x0007ULL << 32)
d337f35e 11688+
4bf69007 11689+#define VXF_INIT_SET (VXF_STATE_SETUP | VXF_STATE_INIT | VXF_STATE_ADMIN)
d337f35e
JR
11690+
11691+
4bf69007 11692+/* context migration */
d337f35e 11693+
4bf69007
AM
11694+#define VXM_SET_INIT 0x00000001
11695+#define VXM_SET_REAPER 0x00000002
d337f35e 11696+
4bf69007 11697+/* context caps */
d337f35e 11698+
4bf69007
AM
11699+#define VXC_SET_UTSNAME 0x00000001
11700+#define VXC_SET_RLIMIT 0x00000002
11701+#define VXC_FS_SECURITY 0x00000004
11702+#define VXC_FS_TRUSTED 0x00000008
11703+#define VXC_TIOCSTI 0x00000010
2380c486 11704+
4bf69007
AM
11705+/* was VXC_RAW_ICMP 0x00000100 */
11706+#define VXC_SYSLOG 0x00001000
11707+#define VXC_OOM_ADJUST 0x00002000
11708+#define VXC_AUDIT_CONTROL 0x00004000
d337f35e 11709+
c2e5f7c8
JR
11710+#define VXC_SECURE_MOUNT 0x00010000
11711+/* #define VXC_SECURE_REMOUNT 0x00020000 */
4bf69007 11712+#define VXC_BINARY_MOUNT 0x00040000
b00e13aa 11713+#define VXC_DEV_MOUNT 0x00080000
d337f35e 11714+
4bf69007
AM
11715+#define VXC_QUOTA_CTL 0x00100000
11716+#define VXC_ADMIN_MAPPER 0x00200000
11717+#define VXC_ADMIN_CLOOP 0x00400000
d337f35e 11718+
4bf69007
AM
11719+#define VXC_KTHREAD 0x01000000
11720+#define VXC_NAMESPACE 0x02000000
d337f35e 11721+
4bf69007 11722+#endif /* _UAPI_VS_CONTEXT_H */
cef7ea10
AM
11723diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/context_cmd.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/context_cmd.h
11724--- linux-4.9.82/include/uapi/vserver/context_cmd.h 1970-01-01 00:00:00.000000000 +0000
11725+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/context_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11726@@ -0,0 +1,115 @@
11727+#ifndef _UAPI_VS_CONTEXT_CMD_H
11728+#define _UAPI_VS_CONTEXT_CMD_H
d33d7b00
AM
11729+
11730+
4bf69007 11731+/* vinfo commands */
3bac966d 11732+
4bf69007 11733+#define VCMD_task_xid VC_CMD(VINFO, 1, 0)
3bac966d 11734+
3bac966d 11735+
4bf69007 11736+#define VCMD_vx_info VC_CMD(VINFO, 5, 0)
3bac966d 11737+
4bf69007
AM
11738+struct vcmd_vx_info_v0 {
11739+ uint32_t xid;
11740+ uint32_t initpid;
11741+ /* more to come */
11742+};
3bac966d
AM
11743+
11744+
4bf69007 11745+#define VCMD_ctx_stat VC_CMD(VSTAT, 0, 0)
3bac966d 11746+
4bf69007
AM
11747+struct vcmd_ctx_stat_v0 {
11748+ uint32_t usecnt;
11749+ uint32_t tasks;
11750+ /* more to come */
11751+};
3bac966d 11752+
3bac966d 11753+
4bf69007 11754+/* context commands */
3bac966d 11755+
4bf69007
AM
11756+#define VCMD_ctx_create_v0 VC_CMD(VPROC, 1, 0)
11757+#define VCMD_ctx_create VC_CMD(VPROC, 1, 1)
3bac966d 11758+
4bf69007
AM
11759+struct vcmd_ctx_create {
11760+ uint64_t flagword;
11761+};
3bac966d 11762+
4bf69007
AM
11763+#define VCMD_ctx_migrate_v0 VC_CMD(PROCMIG, 1, 0)
11764+#define VCMD_ctx_migrate VC_CMD(PROCMIG, 1, 1)
3bac966d 11765+
4bf69007
AM
11766+struct vcmd_ctx_migrate {
11767+ uint64_t flagword;
11768+};
3bac966d 11769+
d33d7b00 11770+
d33d7b00 11771+
4bf69007 11772+/* flag commands */
d33d7b00 11773+
4bf69007
AM
11774+#define VCMD_get_cflags VC_CMD(FLAGS, 1, 0)
11775+#define VCMD_set_cflags VC_CMD(FLAGS, 2, 0)
d33d7b00 11776+
4bf69007
AM
11777+struct vcmd_ctx_flags_v0 {
11778+ uint64_t flagword;
11779+ uint64_t mask;
11780+};
3bac966d
AM
11781+
11782+
3bac966d 11783+
4bf69007 11784+/* context caps commands */
3bac966d 11785+
4bf69007
AM
11786+#define VCMD_get_ccaps VC_CMD(FLAGS, 3, 1)
11787+#define VCMD_set_ccaps VC_CMD(FLAGS, 4, 1)
d33d7b00 11788+
4bf69007
AM
11789+struct vcmd_ctx_caps_v1 {
11790+ uint64_t ccaps;
11791+ uint64_t cmask;
11792+};
d33d7b00 11793+
d33d7b00
AM
11794+
11795+
4bf69007 11796+/* bcaps commands */
d33d7b00 11797+
4bf69007
AM
11798+#define VCMD_get_bcaps VC_CMD(FLAGS, 9, 0)
11799+#define VCMD_set_bcaps VC_CMD(FLAGS, 10, 0)
d33d7b00 11800+
4bf69007
AM
11801+struct vcmd_bcaps {
11802+ uint64_t bcaps;
11803+ uint64_t bmask;
11804+};
3bac966d 11805+
d33d7b00 11806+
d33d7b00 11807+
4bf69007 11808+/* umask commands */
d33d7b00 11809+
4bf69007
AM
11810+#define VCMD_get_umask VC_CMD(FLAGS, 13, 0)
11811+#define VCMD_set_umask VC_CMD(FLAGS, 14, 0)
3bac966d 11812+
4bf69007
AM
11813+struct vcmd_umask {
11814+ uint64_t umask;
11815+ uint64_t mask;
11816+};
d33d7b00 11817+
d33d7b00
AM
11818+
11819+
4bf69007 11820+/* wmask commands */
d33d7b00 11821+
4bf69007
AM
11822+#define VCMD_get_wmask VC_CMD(FLAGS, 15, 0)
11823+#define VCMD_set_wmask VC_CMD(FLAGS, 16, 0)
d33d7b00 11824+
4bf69007
AM
11825+struct vcmd_wmask {
11826+ uint64_t wmask;
11827+ uint64_t mask;
d33d7b00
AM
11828+};
11829+
d33d7b00 11830+
d33d7b00 11831+
4bf69007 11832+/* OOM badness */
d33d7b00 11833+
4bf69007
AM
11834+#define VCMD_get_badness VC_CMD(MEMCTRL, 5, 0)
11835+#define VCMD_set_badness VC_CMD(MEMCTRL, 6, 0)
d33d7b00 11836+
4bf69007
AM
11837+struct vcmd_badness_v0 {
11838+ int64_t bias;
11839+};
d33d7b00 11840+
4bf69007 11841+#endif /* _UAPI_VS_CONTEXT_CMD_H */
cef7ea10
AM
11842diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/cvirt_cmd.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/cvirt_cmd.h
11843--- linux-4.9.82/include/uapi/vserver/cvirt_cmd.h 1970-01-01 00:00:00.000000000 +0000
11844+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/cvirt_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11845@@ -0,0 +1,41 @@
11846+#ifndef _UAPI_VS_CVIRT_CMD_H
11847+#define _UAPI_VS_CVIRT_CMD_H
d33d7b00 11848+
d33d7b00 11849+
4bf69007 11850+/* virtual host info name commands */
d33d7b00 11851+
4bf69007
AM
11852+#define VCMD_set_vhi_name VC_CMD(VHOST, 1, 0)
11853+#define VCMD_get_vhi_name VC_CMD(VHOST, 2, 0)
d33d7b00 11854+
4bf69007
AM
11855+struct vcmd_vhi_name_v0 {
11856+ uint32_t field;
11857+ char name[65];
11858+};
d33d7b00 11859+
d33d7b00 11860+
4bf69007
AM
11861+enum vhi_name_field {
11862+ VHIN_CONTEXT = 0,
11863+ VHIN_SYSNAME,
11864+ VHIN_NODENAME,
11865+ VHIN_RELEASE,
11866+ VHIN_VERSION,
11867+ VHIN_MACHINE,
11868+ VHIN_DOMAINNAME,
11869+};
d33d7b00 11870+
d33d7b00 11871+
d33d7b00 11872+
4bf69007 11873+#define VCMD_virt_stat VC_CMD(VSTAT, 3, 0)
d33d7b00 11874+
4bf69007
AM
11875+struct vcmd_virt_stat_v0 {
11876+ uint64_t offset;
11877+ uint64_t uptime;
11878+ uint32_t nr_threads;
11879+ uint32_t nr_running;
11880+ uint32_t nr_uninterruptible;
11881+ uint32_t nr_onhold;
11882+ uint32_t nr_forks;
11883+ uint32_t load[3];
11884+};
2380c486 11885+
4bf69007 11886+#endif /* _UAPI_VS_CVIRT_CMD_H */
cef7ea10
AM
11887diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/debug_cmd.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/debug_cmd.h
11888--- linux-4.9.82/include/uapi/vserver/debug_cmd.h 1970-01-01 00:00:00.000000000 +0000
11889+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/debug_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11890@@ -0,0 +1,24 @@
11891+#ifndef _UAPI_VS_DEBUG_CMD_H
11892+#define _UAPI_VS_DEBUG_CMD_H
537831f9 11893+
537831f9 11894+
4bf69007 11895+/* debug commands */
537831f9 11896+
4bf69007 11897+#define VCMD_dump_history VC_CMD(DEBUG, 1, 0)
537831f9 11898+
4bf69007
AM
11899+#define VCMD_read_history VC_CMD(DEBUG, 5, 0)
11900+#define VCMD_read_monitor VC_CMD(DEBUG, 6, 0)
537831f9 11901+
4bf69007
AM
11902+struct vcmd_read_history_v0 {
11903+ uint32_t index;
11904+ uint32_t count;
11905+ char __user *data;
11906+};
537831f9 11907+
4bf69007
AM
11908+struct vcmd_read_monitor_v0 {
11909+ uint32_t index;
11910+ uint32_t count;
11911+ char __user *data;
11912+};
537831f9 11913+
4bf69007 11914+#endif /* _UAPI_VS_DEBUG_CMD_H */
cef7ea10
AM
11915diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/device.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/device.h
11916--- linux-4.9.82/include/uapi/vserver/device.h 1970-01-01 00:00:00.000000000 +0000
11917+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/device.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11918@@ -0,0 +1,12 @@
11919+#ifndef _UAPI_VS_DEVICE_H
11920+#define _UAPI_VS_DEVICE_H
d337f35e 11921+
d337f35e 11922+
4bf69007
AM
11923+#define DATTR_CREATE 0x00000001
11924+#define DATTR_OPEN 0x00000002
d337f35e 11925+
4bf69007 11926+#define DATTR_REMAP 0x00000010
d337f35e 11927+
4bf69007 11928+#define DATTR_MASK 0x00000013
ec22aa5c 11929+
4bf69007 11930+#endif /* _UAPI_VS_DEVICE_H */
cef7ea10
AM
11931diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/device_cmd.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/device_cmd.h
11932--- linux-4.9.82/include/uapi/vserver/device_cmd.h 1970-01-01 00:00:00.000000000 +0000
11933+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/device_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11934@@ -0,0 +1,16 @@
11935+#ifndef _UAPI_VS_DEVICE_CMD_H
11936+#define _UAPI_VS_DEVICE_CMD_H
2380c486 11937+
1163e6ab 11938+
4bf69007 11939+/* device vserver commands */
1163e6ab 11940+
4bf69007
AM
11941+#define VCMD_set_mapping VC_CMD(DEVICE, 1, 0)
11942+#define VCMD_unset_mapping VC_CMD(DEVICE, 2, 0)
e915af4e 11943+
4bf69007
AM
11944+struct vcmd_set_mapping_v0 {
11945+ const char __user *device;
11946+ const char __user *target;
11947+ uint32_t flags;
11948+};
e915af4e 11949+
4bf69007 11950+#endif /* _UAPI_VS_DEVICE_CMD_H */
cef7ea10
AM
11951diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/dlimit_cmd.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/dlimit_cmd.h
11952--- linux-4.9.82/include/uapi/vserver/dlimit_cmd.h 1970-01-01 00:00:00.000000000 +0000
11953+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/dlimit_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
11954@@ -0,0 +1,67 @@
11955+#ifndef _UAPI_VS_DLIMIT_CMD_H
11956+#define _UAPI_VS_DLIMIT_CMD_H
e915af4e 11957+
42bc425c 11958+
4bf69007 11959+/* dlimit vserver commands */
d337f35e 11960+
4bf69007
AM
11961+#define VCMD_add_dlimit VC_CMD(DLIMIT, 1, 0)
11962+#define VCMD_rem_dlimit VC_CMD(DLIMIT, 2, 0)
d337f35e 11963+
4bf69007
AM
11964+#define VCMD_set_dlimit VC_CMD(DLIMIT, 5, 0)
11965+#define VCMD_get_dlimit VC_CMD(DLIMIT, 6, 0)
d337f35e 11966+
4bf69007
AM
11967+struct vcmd_ctx_dlimit_base_v0 {
11968+ const char __user *name;
11969+ uint32_t flags;
11970+};
11971+
11972+struct vcmd_ctx_dlimit_v0 {
11973+ const char __user *name;
11974+ uint32_t space_used; /* used space in kbytes */
11975+ uint32_t space_total; /* maximum space in kbytes */
11976+ uint32_t inodes_used; /* used inodes */
11977+ uint32_t inodes_total; /* maximum inodes */
11978+ uint32_t reserved; /* reserved for root in % */
11979+ uint32_t flags;
11980+};
11981+
11982+#define CDLIM_UNSET ((uint32_t)0UL)
11983+#define CDLIM_INFINITY ((uint32_t)~0UL)
11984+#define CDLIM_KEEP ((uint32_t)~1UL)
11985+
11986+#define DLIME_UNIT 0
11987+#define DLIME_KILO 1
11988+#define DLIME_MEGA 2
11989+#define DLIME_GIGA 3
11990+
11991+#define DLIMF_SHIFT 0x10
11992+
11993+#define DLIMS_USED 0
11994+#define DLIMS_TOTAL 2
11995+
11996+static inline
11997+uint64_t dlimit_space_32to64(uint32_t val, uint32_t flags, int shift)
2380c486 11998+{
4bf69007
AM
11999+ int exp = (flags & DLIMF_SHIFT) ?
12000+ (flags >> shift) & DLIME_GIGA : DLIME_KILO;
12001+ return ((uint64_t)val) << (10 * exp);
2380c486
JR
12002+}
12003+
4bf69007
AM
12004+static inline
12005+uint32_t dlimit_space_64to32(uint64_t val, uint32_t *flags, int shift)
2380c486 12006+{
4bf69007 12007+ int exp = 0;
ec22aa5c 12008+
4bf69007
AM
12009+ if (*flags & DLIMF_SHIFT) {
12010+ while (val > (1LL << 32) && (exp < 3)) {
12011+ val >>= 10;
12012+ exp++;
12013+ }
12014+ *flags &= ~(DLIME_GIGA << shift);
12015+ *flags |= exp << shift;
12016+ } else
12017+ val >>= 10;
12018+ return val;
2380c486
JR
12019+}
12020+
4bf69007 12021+#endif /* _UAPI_VS_DLIMIT_CMD_H */
cef7ea10
AM
12022diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/inode.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/inode.h
12023--- linux-4.9.82/include/uapi/vserver/inode.h 1970-01-01 00:00:00.000000000 +0000
12024+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/inode.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
12025@@ -0,0 +1,23 @@
12026+#ifndef _UAPI_VS_INODE_H
12027+#define _UAPI_VS_INODE_H
2380c486 12028+
d337f35e 12029+
4bf69007 12030+#define IATTR_TAG 0x01000000
2380c486 12031+
4bf69007
AM
12032+#define IATTR_ADMIN 0x00000001
12033+#define IATTR_WATCH 0x00000002
12034+#define IATTR_HIDE 0x00000004
12035+#define IATTR_FLAGS 0x00000007
2380c486 12036+
4bf69007
AM
12037+#define IATTR_BARRIER 0x00010000
12038+#define IATTR_IXUNLINK 0x00020000
12039+#define IATTR_IMMUTABLE 0x00040000
12040+#define IATTR_COW 0x00080000
d337f35e 12041+
ec22aa5c 12042+
4bf69007 12043+/* inode ioctls */
ec22aa5c 12044+
4bf69007
AM
12045+#define FIOC_GETXFLG _IOR('x', 5, long)
12046+#define FIOC_SETXFLG _IOW('x', 6, long)
d337f35e 12047+
4bf69007 12048+#endif /* _UAPI_VS_INODE_H */
cef7ea10
AM
12049diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/inode_cmd.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/inode_cmd.h
12050--- linux-4.9.82/include/uapi/vserver/inode_cmd.h 1970-01-01 00:00:00.000000000 +0000
12051+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/inode_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
12052@@ -0,0 +1,26 @@
12053+#ifndef _UAPI_VS_INODE_CMD_H
12054+#define _UAPI_VS_INODE_CMD_H
d337f35e 12055+
db55b927 12056+
4bf69007 12057+/* inode vserver commands */
2c8c5bc5 12058+
4bf69007
AM
12059+#define VCMD_get_iattr VC_CMD(INODE, 1, 1)
12060+#define VCMD_set_iattr VC_CMD(INODE, 2, 1)
2bf5ad28 12061+
4bf69007
AM
12062+#define VCMD_fget_iattr VC_CMD(INODE, 3, 0)
12063+#define VCMD_fset_iattr VC_CMD(INODE, 4, 0)
4a036bed 12064+
4bf69007
AM
12065+struct vcmd_ctx_iattr_v1 {
12066+ const char __user *name;
12067+ uint32_t tag;
12068+ uint32_t flags;
12069+ uint32_t mask;
12070+};
4a036bed 12071+
4bf69007
AM
12072+struct vcmd_ctx_fiattr_v0 {
12073+ uint32_t tag;
12074+ uint32_t flags;
12075+ uint32_t mask;
12076+};
4a036bed 12077+
4bf69007 12078+#endif /* _UAPI_VS_INODE_CMD_H */
cef7ea10
AM
12079diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/limit.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/limit.h
12080--- linux-4.9.82/include/uapi/vserver/limit.h 1970-01-01 00:00:00.000000000 +0000
12081+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/limit.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
12082@@ -0,0 +1,14 @@
12083+#ifndef _UAPI_VS_LIMIT_H
12084+#define _UAPI_VS_LIMIT_H
4a036bed 12085+
42bc425c 12086+
4bf69007
AM
12087+#define VLIMIT_NSOCK 16
12088+#define VLIMIT_OPENFD 17
12089+#define VLIMIT_ANON 18
12090+#define VLIMIT_SHMEM 19
12091+#define VLIMIT_SEMARY 20
12092+#define VLIMIT_NSEMS 21
12093+#define VLIMIT_DENTRY 22
12094+#define VLIMIT_MAPPED 23
adc1caaa 12095+
4bf69007 12096+#endif /* _UAPI_VS_LIMIT_H */
cef7ea10
AM
12097diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/limit_cmd.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/limit_cmd.h
12098--- linux-4.9.82/include/uapi/vserver/limit_cmd.h 1970-01-01 00:00:00.000000000 +0000
12099+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/limit_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
12100@@ -0,0 +1,40 @@
12101+#ifndef _UAPI_VS_LIMIT_CMD_H
12102+#define _UAPI_VS_LIMIT_CMD_H
adc1caaa 12103+
adc1caaa 12104+
4bf69007 12105+/* rlimit vserver commands */
adc1caaa 12106+
4bf69007
AM
12107+#define VCMD_get_rlimit VC_CMD(RLIMIT, 1, 0)
12108+#define VCMD_set_rlimit VC_CMD(RLIMIT, 2, 0)
12109+#define VCMD_get_rlimit_mask VC_CMD(RLIMIT, 3, 0)
12110+#define VCMD_reset_hits VC_CMD(RLIMIT, 7, 0)
12111+#define VCMD_reset_minmax VC_CMD(RLIMIT, 9, 0)
adc1caaa 12112+
4bf69007
AM
12113+struct vcmd_ctx_rlimit_v0 {
12114+ uint32_t id;
12115+ uint64_t minimum;
12116+ uint64_t softlimit;
12117+ uint64_t maximum;
12118+};
d33d7b00 12119+
4bf69007
AM
12120+struct vcmd_ctx_rlimit_mask_v0 {
12121+ uint32_t minimum;
12122+ uint32_t softlimit;
12123+ uint32_t maximum;
12124+};
d33d7b00 12125+
4bf69007 12126+#define VCMD_rlimit_stat VC_CMD(VSTAT, 1, 0)
d33d7b00 12127+
4bf69007
AM
12128+struct vcmd_rlimit_stat_v0 {
12129+ uint32_t id;
12130+ uint32_t hits;
12131+ uint64_t value;
12132+ uint64_t minimum;
12133+ uint64_t maximum;
12134+};
d33d7b00 12135+
4bf69007
AM
12136+#define CRLIM_UNSET (0ULL)
12137+#define CRLIM_INFINITY (~0ULL)
12138+#define CRLIM_KEEP (~1ULL)
d33d7b00 12139+
4bf69007 12140+#endif /* _UAPI_VS_LIMIT_CMD_H */
cef7ea10
AM
12141diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/monitor.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/monitor.h
12142--- linux-4.9.82/include/uapi/vserver/monitor.h 1970-01-01 00:00:00.000000000 +0000
12143+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/monitor.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
12144@@ -0,0 +1,96 @@
12145+#ifndef _UAPI_VS_MONITOR_H
12146+#define _UAPI_VS_MONITOR_H
d33d7b00 12147+
4bf69007 12148+#include <linux/types.h>
d33d7b00 12149+
d33d7b00 12150+
4bf69007
AM
12151+enum {
12152+ VXM_UNUSED = 0,
d33d7b00 12153+
4bf69007 12154+ VXM_SYNC = 0x10,
d33d7b00 12155+
4bf69007
AM
12156+ VXM_UPDATE = 0x20,
12157+ VXM_UPDATE_1,
12158+ VXM_UPDATE_2,
d33d7b00 12159+
4bf69007
AM
12160+ VXM_RQINFO_1 = 0x24,
12161+ VXM_RQINFO_2,
d33d7b00 12162+
4bf69007
AM
12163+ VXM_ACTIVATE = 0x40,
12164+ VXM_DEACTIVATE,
12165+ VXM_IDLE,
d33d7b00 12166+
4bf69007
AM
12167+ VXM_HOLD = 0x44,
12168+ VXM_UNHOLD,
d33d7b00 12169+
4bf69007
AM
12170+ VXM_MIGRATE = 0x48,
12171+ VXM_RESCHED,
d33d7b00 12172+
4bf69007
AM
12173+ /* all other bits are flags */
12174+ VXM_SCHED = 0x80,
12175+};
d33d7b00 12176+
4bf69007
AM
12177+struct _vxm_update_1 {
12178+ uint32_t tokens_max;
12179+ uint32_t fill_rate;
12180+ uint32_t interval;
12181+};
d33d7b00 12182+
4bf69007
AM
12183+struct _vxm_update_2 {
12184+ uint32_t tokens_min;
12185+ uint32_t fill_rate;
12186+ uint32_t interval;
12187+};
d33d7b00 12188+
4bf69007
AM
12189+struct _vxm_rqinfo_1 {
12190+ uint16_t running;
12191+ uint16_t onhold;
12192+ uint16_t iowait;
12193+ uint16_t uintr;
12194+ uint32_t idle_tokens;
12195+};
d33d7b00 12196+
4bf69007
AM
12197+struct _vxm_rqinfo_2 {
12198+ uint32_t norm_time;
12199+ uint32_t idle_time;
12200+ uint32_t idle_skip;
12201+};
d33d7b00 12202+
4bf69007
AM
12203+struct _vxm_sched {
12204+ uint32_t tokens;
12205+ uint32_t norm_time;
12206+ uint32_t idle_time;
12207+};
d33d7b00 12208+
4bf69007
AM
12209+struct _vxm_task {
12210+ uint16_t pid;
12211+ uint16_t state;
12212+};
d33d7b00 12213+
4bf69007
AM
12214+struct _vxm_event {
12215+ uint32_t jif;
12216+ union {
12217+ uint32_t seq;
12218+ uint32_t sec;
12219+ };
12220+ union {
12221+ uint32_t tokens;
12222+ uint32_t nsec;
12223+ struct _vxm_task tsk;
12224+ };
12225+};
61b0c03f 12226+
4bf69007
AM
12227+struct _vx_mon_entry {
12228+ uint16_t type;
12229+ uint16_t xid;
12230+ union {
12231+ struct _vxm_event ev;
12232+ struct _vxm_sched sd;
12233+ struct _vxm_update_1 u1;
12234+ struct _vxm_update_2 u2;
12235+ struct _vxm_rqinfo_1 q1;
12236+ struct _vxm_rqinfo_2 q2;
12237+ };
12238+};
d33d7b00 12239+
4bf69007 12240+#endif /* _UAPI_VS_MONITOR_H */
cef7ea10
AM
12241diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/network.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/network.h
12242--- linux-4.9.82/include/uapi/vserver/network.h 1970-01-01 00:00:00.000000000 +0000
12243+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/network.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
12244@@ -0,0 +1,76 @@
12245+#ifndef _UAPI_VS_NETWORK_H
12246+#define _UAPI_VS_NETWORK_H
d33d7b00 12247+
4bf69007 12248+#include <linux/types.h>
d33d7b00 12249+
d33d7b00 12250+
4bf69007 12251+#define MAX_N_CONTEXT 65535 /* Arbitrary limit */
d33d7b00 12252+
d33d7b00 12253+
4bf69007 12254+/* network flags */
d33d7b00 12255+
4bf69007 12256+#define NXF_INFO_PRIVATE 0x00000008
d33d7b00 12257+
4bf69007
AM
12258+#define NXF_SINGLE_IP 0x00000100
12259+#define NXF_LBACK_REMAP 0x00000200
12260+#define NXF_LBACK_ALLOW 0x00000400
d33d7b00 12261+
4bf69007
AM
12262+#define NXF_HIDE_NETIF 0x02000000
12263+#define NXF_HIDE_LBACK 0x04000000
265d6dcc 12264+
4bf69007
AM
12265+#define NXF_STATE_SETUP (1ULL << 32)
12266+#define NXF_STATE_ADMIN (1ULL << 34)
d33d7b00 12267+
4bf69007
AM
12268+#define NXF_SC_HELPER (1ULL << 36)
12269+#define NXF_PERSISTENT (1ULL << 38)
d33d7b00 12270+
4bf69007 12271+#define NXF_ONE_TIME (0x0005ULL << 32)
d33d7b00 12272+
d33d7b00 12273+
4bf69007 12274+#define NXF_INIT_SET (__nxf_init_set())
d33d7b00 12275+
4bf69007
AM
12276+static inline uint64_t __nxf_init_set(void) {
12277+ return NXF_STATE_ADMIN
12278+#ifdef CONFIG_VSERVER_AUTO_LBACK
12279+ | NXF_LBACK_REMAP
12280+ | NXF_HIDE_LBACK
12281+#endif
12282+#ifdef CONFIG_VSERVER_AUTO_SINGLE
12283+ | NXF_SINGLE_IP
12284+#endif
12285+ | NXF_HIDE_NETIF;
12286+}
d33d7b00 12287+
d33d7b00 12288+
4bf69007 12289+/* network caps */
d33d7b00 12290+
4bf69007 12291+#define NXC_TUN_CREATE 0x00000001
d33d7b00 12292+
4bf69007 12293+#define NXC_RAW_ICMP 0x00000100
d33d7b00 12294+
4bf69007 12295+#define NXC_MULTICAST 0x00001000
d33d7b00 12296+
adc1caaa 12297+
4bf69007 12298+/* address types */
adc1caaa 12299+
4bf69007
AM
12300+#define NXA_TYPE_IPV4 0x0001
12301+#define NXA_TYPE_IPV6 0x0002
adc1caaa 12302+
4bf69007
AM
12303+#define NXA_TYPE_NONE 0x0000
12304+#define NXA_TYPE_ANY 0x00FF
adc1caaa 12305+
4bf69007
AM
12306+#define NXA_TYPE_ADDR 0x0010
12307+#define NXA_TYPE_MASK 0x0020
12308+#define NXA_TYPE_RANGE 0x0040
adc1caaa 12309+
4bf69007 12310+#define NXA_MASK_ALL (NXA_TYPE_ADDR | NXA_TYPE_MASK | NXA_TYPE_RANGE)
adc1caaa 12311+
4bf69007
AM
12312+#define NXA_MOD_BCAST 0x0100
12313+#define NXA_MOD_LBACK 0x0200
adc1caaa 12314+
4bf69007 12315+#define NXA_LOOPBACK 0x1000
2380c486 12316+
4bf69007
AM
12317+#define NXA_MASK_BIND (NXA_MASK_ALL | NXA_MOD_BCAST | NXA_MOD_LBACK)
12318+#define NXA_MASK_SHOW (NXA_MASK_ALL | NXA_LOOPBACK)
2380c486 12319+
4bf69007 12320+#endif /* _UAPI_VS_NETWORK_H */
cef7ea10
AM
12321diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/network_cmd.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/network_cmd.h
12322--- linux-4.9.82/include/uapi/vserver/network_cmd.h 1970-01-01 00:00:00.000000000 +0000
12323+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/network_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
12324@@ -0,0 +1,123 @@
12325+#ifndef _UAPI_VS_NETWORK_CMD_H
12326+#define _UAPI_VS_NETWORK_CMD_H
2380c486 12327+
2380c486 12328+
4bf69007 12329+/* vinfo commands */
2380c486 12330+
4bf69007 12331+#define VCMD_task_nid VC_CMD(VINFO, 2, 0)
2380c486 12332+
2380c486 12333+
4bf69007 12334+#define VCMD_nx_info VC_CMD(VINFO, 6, 0)
2380c486 12335+
4bf69007
AM
12336+struct vcmd_nx_info_v0 {
12337+ uint32_t nid;
12338+ /* more to come */
12339+};
2380c486 12340+
2380c486 12341+
4bf69007
AM
12342+#include <linux/in.h>
12343+#include <linux/in6.h>
2380c486 12344+
4bf69007
AM
12345+#define VCMD_net_create_v0 VC_CMD(VNET, 1, 0)
12346+#define VCMD_net_create VC_CMD(VNET, 1, 1)
2380c486 12347+
4bf69007
AM
12348+struct vcmd_net_create {
12349+ uint64_t flagword;
12350+};
2380c486 12351+
4bf69007 12352+#define VCMD_net_migrate VC_CMD(NETMIG, 1, 0)
2380c486 12353+
4bf69007
AM
12354+#define VCMD_net_add VC_CMD(NETALT, 1, 0)
12355+#define VCMD_net_remove VC_CMD(NETALT, 2, 0)
2380c486 12356+
4bf69007
AM
12357+struct vcmd_net_addr_v0 {
12358+ uint16_t type;
12359+ uint16_t count;
12360+ struct in_addr ip[4];
12361+ struct in_addr mask[4];
12362+};
2380c486 12363+
4bf69007
AM
12364+#define VCMD_net_add_ipv4_v1 VC_CMD(NETALT, 1, 1)
12365+#define VCMD_net_rem_ipv4_v1 VC_CMD(NETALT, 2, 1)
2380c486 12366+
4bf69007
AM
12367+struct vcmd_net_addr_ipv4_v1 {
12368+ uint16_t type;
12369+ uint16_t flags;
12370+ struct in_addr ip;
12371+ struct in_addr mask;
12372+};
2380c486 12373+
4bf69007
AM
12374+#define VCMD_net_add_ipv4 VC_CMD(NETALT, 1, 2)
12375+#define VCMD_net_rem_ipv4 VC_CMD(NETALT, 2, 2)
2380c486 12376+
4bf69007
AM
12377+struct vcmd_net_addr_ipv4_v2 {
12378+ uint16_t type;
12379+ uint16_t flags;
12380+ struct in_addr ip;
12381+ struct in_addr ip2;
12382+ struct in_addr mask;
12383+};
2380c486 12384+
4bf69007
AM
12385+#define VCMD_net_add_ipv6 VC_CMD(NETALT, 3, 1)
12386+#define VCMD_net_remove_ipv6 VC_CMD(NETALT, 4, 1)
2380c486 12387+
4bf69007
AM
12388+struct vcmd_net_addr_ipv6_v1 {
12389+ uint16_t type;
12390+ uint16_t flags;
12391+ uint32_t prefix;
12392+ struct in6_addr ip;
12393+ struct in6_addr mask;
12394+};
2380c486 12395+
4bf69007
AM
12396+#define VCMD_add_match_ipv4 VC_CMD(NETALT, 5, 0)
12397+#define VCMD_get_match_ipv4 VC_CMD(NETALT, 6, 0)
2380c486 12398+
4bf69007
AM
12399+struct vcmd_match_ipv4_v0 {
12400+ uint16_t type;
12401+ uint16_t flags;
12402+ uint16_t parent;
12403+ uint16_t prefix;
12404+ struct in_addr ip;
12405+ struct in_addr ip2;
12406+ struct in_addr mask;
12407+};
2380c486 12408+
4bf69007
AM
12409+#define VCMD_add_match_ipv6 VC_CMD(NETALT, 7, 0)
12410+#define VCMD_get_match_ipv6 VC_CMD(NETALT, 8, 0)
2380c486 12411+
4bf69007
AM
12412+struct vcmd_match_ipv6_v0 {
12413+ uint16_t type;
12414+ uint16_t flags;
12415+ uint16_t parent;
12416+ uint16_t prefix;
12417+ struct in6_addr ip;
12418+ struct in6_addr ip2;
12419+ struct in6_addr mask;
12420+};
2380c486 12421+
2380c486 12422+
2380c486 12423+
2380c486 12424+
4bf69007 12425+/* flag commands */
2380c486 12426+
4bf69007
AM
12427+#define VCMD_get_nflags VC_CMD(FLAGS, 5, 0)
12428+#define VCMD_set_nflags VC_CMD(FLAGS, 6, 0)
2380c486 12429+
4bf69007
AM
12430+struct vcmd_net_flags_v0 {
12431+ uint64_t flagword;
12432+ uint64_t mask;
12433+};
2380c486 12434+
2380c486 12435+
ab30d09f 12436+
4bf69007 12437+/* network caps commands */
ab30d09f 12438+
4bf69007
AM
12439+#define VCMD_get_ncaps VC_CMD(FLAGS, 7, 0)
12440+#define VCMD_set_ncaps VC_CMD(FLAGS, 8, 0)
ec22aa5c 12441+
4bf69007
AM
12442+struct vcmd_net_caps_v0 {
12443+ uint64_t ncaps;
12444+ uint64_t cmask;
12445+};
3bac966d 12446+
4bf69007 12447+#endif /* _UAPI_VS_NETWORK_CMD_H */
cef7ea10
AM
12448diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/sched_cmd.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/sched_cmd.h
12449--- linux-4.9.82/include/uapi/vserver/sched_cmd.h 1970-01-01 00:00:00.000000000 +0000
12450+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/sched_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
12451@@ -0,0 +1,13 @@
12452+#ifndef _UAPI_VS_SCHED_CMD_H
12453+#define _UAPI_VS_SCHED_CMD_H
d337f35e 12454+
d337f35e 12455+
4bf69007
AM
12456+struct vcmd_prio_bias {
12457+ int32_t cpu_id;
12458+ int32_t prio_bias;
12459+};
2380c486 12460+
4bf69007
AM
12461+#define VCMD_set_prio_bias VC_CMD(SCHED, 4, 0)
12462+#define VCMD_get_prio_bias VC_CMD(SCHED, 5, 0)
d337f35e 12463+
4bf69007 12464+#endif /* _UAPI_VS_SCHED_CMD_H */
cef7ea10
AM
12465diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/signal_cmd.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/signal_cmd.h
12466--- linux-4.9.82/include/uapi/vserver/signal_cmd.h 1970-01-01 00:00:00.000000000 +0000
12467+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/signal_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
12468@@ -0,0 +1,31 @@
12469+#ifndef _UAPI_VS_SIGNAL_CMD_H
12470+#define _UAPI_VS_SIGNAL_CMD_H
d337f35e 12471+
d337f35e 12472+
4bf69007 12473+/* signalling vserver commands */
d337f35e 12474+
4bf69007
AM
12475+#define VCMD_ctx_kill VC_CMD(PROCTRL, 1, 0)
12476+#define VCMD_wait_exit VC_CMD(EVENT, 99, 0)
d337f35e 12477+
4bf69007
AM
12478+struct vcmd_ctx_kill_v0 {
12479+ int32_t pid;
12480+ int32_t sig;
12481+};
d337f35e 12482+
4bf69007
AM
12483+struct vcmd_wait_exit_v0 {
12484+ int32_t reboot_cmd;
12485+ int32_t exit_code;
12486+};
d337f35e 12487+
d337f35e 12488+
4bf69007 12489+/* process alteration commands */
ab30d09f 12490+
4bf69007
AM
12491+#define VCMD_get_pflags VC_CMD(PROCALT, 5, 0)
12492+#define VCMD_set_pflags VC_CMD(PROCALT, 6, 0)
d337f35e 12493+
4bf69007
AM
12494+struct vcmd_pflags_v0 {
12495+ uint32_t flagword;
12496+ uint32_t mask;
12497+};
3bac966d 12498+
4bf69007 12499+#endif /* _UAPI_VS_SIGNAL_CMD_H */
cef7ea10
AM
12500diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/space_cmd.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/space_cmd.h
12501--- linux-4.9.82/include/uapi/vserver/space_cmd.h 1970-01-01 00:00:00.000000000 +0000
12502+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/space_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
12503@@ -0,0 +1,28 @@
12504+#ifndef _UAPI_VS_SPACE_CMD_H
12505+#define _UAPI_VS_SPACE_CMD_H
d337f35e 12506+
d337f35e 12507+
4bf69007
AM
12508+#define VCMD_enter_space_v0 VC_CMD(PROCALT, 1, 0)
12509+#define VCMD_enter_space_v1 VC_CMD(PROCALT, 1, 1)
12510+#define VCMD_enter_space VC_CMD(PROCALT, 1, 2)
2380c486 12511+
4bf69007
AM
12512+#define VCMD_set_space_v0 VC_CMD(PROCALT, 3, 0)
12513+#define VCMD_set_space_v1 VC_CMD(PROCALT, 3, 1)
12514+#define VCMD_set_space VC_CMD(PROCALT, 3, 2)
d337f35e 12515+
4bf69007 12516+#define VCMD_get_space_mask_v0 VC_CMD(PROCALT, 4, 0)
d337f35e 12517+
4bf69007
AM
12518+#define VCMD_get_space_mask VC_CMD(VSPACE, 0, 1)
12519+#define VCMD_get_space_default VC_CMD(VSPACE, 1, 0)
d337f35e 12520+
d337f35e 12521+
4bf69007
AM
12522+struct vcmd_space_mask_v1 {
12523+ uint64_t mask;
12524+};
d337f35e 12525+
4bf69007
AM
12526+struct vcmd_space_mask_v2 {
12527+ uint64_t mask;
12528+ uint32_t index;
12529+};
d337f35e 12530+
4bf69007 12531+#endif /* _UAPI_VS_SPACE_CMD_H */
cef7ea10
AM
12532diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/switch.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/switch.h
12533--- linux-4.9.82/include/uapi/vserver/switch.h 1970-01-01 00:00:00.000000000 +0000
12534+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/switch.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
12535@@ -0,0 +1,90 @@
12536+#ifndef _UAPI_VS_SWITCH_H
12537+#define _UAPI_VS_SWITCH_H
d337f35e 12538+
4bf69007 12539+#include <linux/types.h>
d337f35e 12540+
d337f35e 12541+
4bf69007
AM
12542+#define VC_CATEGORY(c) (((c) >> 24) & 0x3F)
12543+#define VC_COMMAND(c) (((c) >> 16) & 0xFF)
12544+#define VC_VERSION(c) ((c) & 0xFFF)
d337f35e 12545+
4bf69007
AM
12546+#define VC_CMD(c, i, v) ((((VC_CAT_ ## c) & 0x3F) << 24) \
12547+ | (((i) & 0xFF) << 16) | ((v) & 0xFFF))
d337f35e 12548+
4bf69007 12549+/*
d337f35e 12550+
4bf69007 12551+ Syscall Matrix V2.8
d337f35e 12552+
4bf69007
AM
12553+ |VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|
12554+ |STATS |DESTROY|ALTER |CHANGE |LIMIT |TEST | | | |
12555+ |INFO |SETUP | |MOVE | | | | | |
12556+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12557+ SYSTEM |VERSION|VSETUP |VHOST | | | | |DEVICE | |
12558+ HOST | 00| 01| 02| 03| 04| 05| | 06| 07|
12559+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12560+ CPU | |VPROC |PROCALT|PROCMIG|PROCTRL| | |SCHED. | |
12561+ PROCESS| 08| 09| 10| 11| 12| 13| | 14| 15|
12562+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12563+ MEMORY | | | | |MEMCTRL| | |SWAP | |
12564+ | 16| 17| 18| 19| 20| 21| | 22| 23|
12565+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12566+ NETWORK| |VNET |NETALT |NETMIG |NETCTL | | |SERIAL | |
12567+ | 24| 25| 26| 27| 28| 29| | 30| 31|
12568+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12569+ DISK | | | |TAGMIG |DLIMIT | | |INODE | |
12570+ VFS | 32| 33| 34| 35| 36| 37| | 38| 39|
12571+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12572+ OTHER |VSTAT | | | | | | |VINFO | |
12573+ | 40| 41| 42| 43| 44| 45| | 46| 47|
12574+ =======+=======+=======+=======+=======+=======+=======+ +=======+=======+
12575+ SPECIAL|EVENT | | | |FLAGS | | |VSPACE | |
12576+ | 48| 49| 50| 51| 52| 53| | 54| 55|
12577+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12578+ SPECIAL|DEBUG | | | |RLIMIT |SYSCALL| | |COMPAT |
12579+ | 56| 57| 58| 59| 60|TEST 61| | 62| 63|
12580+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
d337f35e 12581+
4bf69007 12582+*/
d337f35e 12583+
4bf69007 12584+#define VC_CAT_VERSION 0
d337f35e 12585+
4bf69007
AM
12586+#define VC_CAT_VSETUP 1
12587+#define VC_CAT_VHOST 2
d337f35e 12588+
4bf69007 12589+#define VC_CAT_DEVICE 6
d337f35e 12590+
4bf69007
AM
12591+#define VC_CAT_VPROC 9
12592+#define VC_CAT_PROCALT 10
12593+#define VC_CAT_PROCMIG 11
12594+#define VC_CAT_PROCTRL 12
d337f35e 12595+
4bf69007
AM
12596+#define VC_CAT_SCHED 14
12597+#define VC_CAT_MEMCTRL 20
d337f35e 12598+
4bf69007
AM
12599+#define VC_CAT_VNET 25
12600+#define VC_CAT_NETALT 26
12601+#define VC_CAT_NETMIG 27
12602+#define VC_CAT_NETCTRL 28
d337f35e 12603+
4bf69007
AM
12604+#define VC_CAT_TAGMIG 35
12605+#define VC_CAT_DLIMIT 36
12606+#define VC_CAT_INODE 38
d337f35e 12607+
4bf69007
AM
12608+#define VC_CAT_VSTAT 40
12609+#define VC_CAT_VINFO 46
12610+#define VC_CAT_EVENT 48
d337f35e 12611+
4bf69007
AM
12612+#define VC_CAT_FLAGS 52
12613+#define VC_CAT_VSPACE 54
12614+#define VC_CAT_DEBUG 56
12615+#define VC_CAT_RLIMIT 60
d337f35e 12616+
4bf69007
AM
12617+#define VC_CAT_SYSTEST 61
12618+#define VC_CAT_COMPAT 63
d337f35e 12619+
4bf69007 12620+/* query version */
d337f35e 12621+
4bf69007
AM
12622+#define VCMD_get_version VC_CMD(VERSION, 0, 0)
12623+#define VCMD_get_vci VC_CMD(VERSION, 1, 0)
2380c486 12624+
4bf69007 12625+#endif /* _UAPI_VS_SWITCH_H */
cef7ea10
AM
12626diff -NurpP --minimal linux-4.9.82/include/uapi/vserver/tag_cmd.h linux-4.9.82-vs2.3.9.7/include/uapi/vserver/tag_cmd.h
12627--- linux-4.9.82/include/uapi/vserver/tag_cmd.h 1970-01-01 00:00:00.000000000 +0000
12628+++ linux-4.9.82-vs2.3.9.7/include/uapi/vserver/tag_cmd.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
12629@@ -0,0 +1,14 @@
12630+#ifndef _UAPI_VS_TAG_CMD_H
12631+#define _UAPI_VS_TAG_CMD_H
d337f35e 12632+
d337f35e 12633+
4bf69007 12634+/* vinfo commands */
d337f35e 12635+
4bf69007 12636+#define VCMD_task_tag VC_CMD(VINFO, 3, 0)
d337f35e
JR
12637+
12638+
4bf69007 12639+/* context commands */
d337f35e 12640+
4bf69007 12641+#define VCMD_tag_migrate VC_CMD(TAGMIG, 1, 0)
2380c486 12642+
4bf69007 12643+#endif /* _UAPI_VS_TAG_CMD_H */
cef7ea10
AM
12644diff -NurpP --minimal linux-4.9.82/init/Kconfig linux-4.9.82-vs2.3.9.7/init/Kconfig
12645--- linux-4.9.82/init/Kconfig 2018-02-22 21:18:55.000000000 +0000
12646+++ linux-4.9.82-vs2.3.9.7/init/Kconfig 2018-02-10 15:15:43.000000000 +0000
cc23e853 12647@@ -958,6 +958,7 @@ config NUMA_BALANCING_DEFAULT_ENABLED
4bf69007 12648 menuconfig CGROUPS
cc23e853 12649 bool "Control Group support"
265de2f7 12650 select KERNFS
4bf69007
AM
12651+ default y
12652 help
12653 This option adds support for grouping sets of processes together, for
12654 use with process control subsystems such as Cpusets, CFS, memory
cef7ea10
AM
12655diff -NurpP --minimal linux-4.9.82/init/main.c linux-4.9.82-vs2.3.9.7/init/main.c
12656--- linux-4.9.82/init/main.c 2018-02-22 21:18:56.000000000 +0000
12657+++ linux-4.9.82-vs2.3.9.7/init/main.c 2018-01-10 02:50:49.000000000 +0000
cc23e853
AM
12658@@ -81,6 +81,7 @@
12659 #include <linux/proc_ns.h>
12660 #include <linux/io.h>
12661 #include <linux/kaiser.h>
4bf69007
AM
12662+#include <linux/vserver/percpu.h>
12663
12664 #include <asm/io.h>
12665 #include <asm/bugs.h>
cef7ea10
AM
12666diff -NurpP --minimal linux-4.9.82/ipc/mqueue.c linux-4.9.82-vs2.3.9.7/ipc/mqueue.c
12667--- linux-4.9.82/ipc/mqueue.c 2018-02-22 21:18:56.000000000 +0000
12668+++ linux-4.9.82-vs2.3.9.7/ipc/mqueue.c 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
12669@@ -35,6 +35,8 @@
12670 #include <linux/ipc_namespace.h>
12671 #include <linux/user_namespace.h>
12672 #include <linux/slab.h>
12673+#include <linux/vs_context.h>
12674+#include <linux/vs_limit.h>
12675
12676 #include <net/sock.h>
12677 #include "util.h"
cc23e853 12678@@ -75,6 +77,7 @@ struct mqueue_inode_info {
bb20add7 12679 struct pid *notify_owner;
4bf69007
AM
12680 struct user_namespace *notify_user_ns;
12681 struct user_struct *user; /* user who created, for accounting */
12682+ struct vx_info *vxi;
12683 struct sock *notify_sock;
12684 struct sk_buff *notify_cookie;
12685
cc23e853 12686@@ -230,6 +233,7 @@ static struct inode *mqueue_get_inode(st
4bf69007
AM
12687 if (S_ISREG(mode)) {
12688 struct mqueue_inode_info *info;
12689 unsigned long mq_bytes, mq_treesize;
12690+ struct vx_info *vxi = current_vx_info();
12691
12692 inode->i_fop = &mqueue_file_operations;
12693 inode->i_size = FILENT_SIZE;
cc23e853 12694@@ -243,6 +247,7 @@ static struct inode *mqueue_get_inode(st
4bf69007
AM
12695 info->notify_user_ns = NULL;
12696 info->qsize = 0;
12697 info->user = NULL; /* set when all is ok */
12698+ info->vxi = NULL;
12699 info->msg_tree = RB_ROOT;
12700 info->node_cache = NULL;
12701 memset(&info->attr, 0, sizeof(info->attr));
cc23e853 12702@@ -276,17 +281,20 @@ static struct inode *mqueue_get_inode(st
4bf69007
AM
12703
12704 spin_lock(&mq_lock);
12705 if (u->mq_bytes + mq_bytes < u->mq_bytes ||
12706- u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE)) {
12707+ u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE) ||
12708+ !vx_ipcmsg_avail(vxi, mq_bytes)) {
12709 spin_unlock(&mq_lock);
12710 /* mqueue_evict_inode() releases info->messages */
12711 ret = -EMFILE;
12712 goto out_inode;
12713 }
12714 u->mq_bytes += mq_bytes;
12715+ vx_ipcmsg_add(vxi, u, mq_bytes);
12716 spin_unlock(&mq_lock);
12717
12718 /* all is ok */
12719 info->user = get_uid(u);
12720+ info->vxi = get_vx_info(vxi);
12721 } else if (S_ISDIR(mode)) {
12722 inc_nlink(inode);
12723 /* Some things misbehave if size == 0 on a directory */
cc23e853 12724@@ -396,8 +404,11 @@ static void mqueue_evict_inode(struct in
4bf69007
AM
12725
12726 user = info->user;
12727 if (user) {
12728+ struct vx_info *vxi = info->vxi;
d337f35e 12729+
4bf69007
AM
12730 spin_lock(&mq_lock);
12731 user->mq_bytes -= mq_bytes;
12732+ vx_ipcmsg_sub(vxi, user, mq_bytes);
12733 /*
12734 * get_ns_from_inode() ensures that the
12735 * (ipc_ns = sb->s_fs_info) is either a valid ipc_ns
cc23e853 12736@@ -407,6 +418,7 @@ static void mqueue_evict_inode(struct in
4bf69007
AM
12737 if (ipc_ns)
12738 ipc_ns->mq_queues_count--;
12739 spin_unlock(&mq_lock);
12740+ put_vx_info(vxi);
12741 free_uid(user);
12742 }
12743 if (ipc_ns)
cef7ea10
AM
12744diff -NurpP --minimal linux-4.9.82/ipc/msg.c linux-4.9.82-vs2.3.9.7/ipc/msg.c
12745--- linux-4.9.82/ipc/msg.c 2018-02-22 21:18:56.000000000 +0000
12746+++ linux-4.9.82-vs2.3.9.7/ipc/msg.c 2018-02-10 15:15:43.000000000 +0000
4bf69007
AM
12747@@ -37,6 +37,7 @@
12748 #include <linux/rwsem.h>
12749 #include <linux/nsproxy.h>
12750 #include <linux/ipc_namespace.h>
12751+#include <linux/vs_base.h>
12752
12753 #include <asm/current.h>
bb20add7 12754 #include <linux/uaccess.h>
cc23e853 12755@@ -124,6 +125,7 @@ static int newque(struct ipc_namespace *
4bf69007
AM
12756
12757 msq->q_perm.mode = msgflg & S_IRWXUGO;
12758 msq->q_perm.key = key;
12759+ msq->q_perm.xid = vx_current_xid();
12760
12761 msq->q_perm.security = NULL;
12762 retval = security_msg_queue_alloc(msq);
cef7ea10
AM
12763diff -NurpP --minimal linux-4.9.82/ipc/namespace.c linux-4.9.82-vs2.3.9.7/ipc/namespace.c
12764--- linux-4.9.82/ipc/namespace.c 2016-12-11 19:17:54.000000000 +0000
12765+++ linux-4.9.82-vs2.3.9.7/ipc/namespace.c 2018-01-13 03:52:55.000000000 +0000
cc23e853
AM
12766@@ -13,6 +13,7 @@
12767 #include <linux/mount.h>
12768 #include <linux/user_namespace.h>
12769 #include <linux/proc_ns.h>
12770+#include <linux/vserver/global.h>
12771
12772 #include "util.h"
12773
12774@@ -59,6 +60,7 @@ static struct ipc_namespace *create_ipc_
12775 sem_init_ns(ns);
12776 msg_init_ns(ns);
12777 shm_init_ns(ns);
12778+ atomic_inc(&vs_global_ipc_ns);
12779
12780 return ns;
12781
12782@@ -121,6 +123,7 @@ static void free_ipc_ns(struct ipc_names
12783 dec_ipc_namespaces(ns->ucounts);
12784 put_user_ns(ns->user_ns);
12785 ns_free_inum(&ns->ns);
12786+ atomic_dec(&vs_global_ipc_ns);
12787 kfree(ns);
12788 }
12789
cef7ea10
AM
12790diff -NurpP --minimal linux-4.9.82/ipc/sem.c linux-4.9.82-vs2.3.9.7/ipc/sem.c
12791--- linux-4.9.82/ipc/sem.c 2016-12-11 19:17:54.000000000 +0000
12792+++ linux-4.9.82-vs2.3.9.7/ipc/sem.c 2018-01-10 02:50:49.000000000 +0000
bb20add7 12793@@ -85,6 +85,8 @@
4bf69007
AM
12794 #include <linux/rwsem.h>
12795 #include <linux/nsproxy.h>
12796 #include <linux/ipc_namespace.h>
12797+#include <linux/vs_base.h>
12798+#include <linux/vs_limit.h>
12799
bb20add7 12800 #include <linux/uaccess.h>
4bf69007 12801 #include "util.h"
cc23e853 12802@@ -537,6 +539,7 @@ static int newary(struct ipc_namespace *
4bf69007
AM
12803
12804 sma->sem_perm.mode = (semflg & S_IRWXUGO);
12805 sma->sem_perm.key = key;
12806+ sma->sem_perm.xid = vx_current_xid();
12807
12808 sma->sem_perm.security = NULL;
12809 retval = security_sem_alloc(sma);
cc23e853 12810@@ -567,6 +570,9 @@ static int newary(struct ipc_namespace *
4bf69007
AM
12811 return id;
12812 }
12813 ns->used_sems += nsems;
12814+ /* FIXME: obsoleted? */
12815+ vx_semary_inc(sma);
12816+ vx_nsems_add(sma, nsems);
12817
bb20add7
AM
12818 sem_unlock(sma, -1);
12819 rcu_read_unlock();
cc23e853 12820@@ -1155,6 +1161,9 @@ static void freeary(struct ipc_namespace
4bf69007
AM
12821
12822 wake_up_sem_queue_do(&tasks);
12823 ns->used_sems -= sma->sem_nsems;
12824+ /* FIXME: obsoleted? */
12825+ vx_nsems_sub(sma, sma->sem_nsems);
12826+ vx_semary_dec(sma);
926e38e0 12827 ipc_rcu_putref(sma, sem_rcu_free);
4bf69007 12828 }
926e38e0 12829
cef7ea10
AM
12830diff -NurpP --minimal linux-4.9.82/ipc/shm.c linux-4.9.82-vs2.3.9.7/ipc/shm.c
12831--- linux-4.9.82/ipc/shm.c 2018-02-22 21:18:56.000000000 +0000
12832+++ linux-4.9.82-vs2.3.9.7/ipc/shm.c 2018-01-10 02:50:49.000000000 +0000
c2e5f7c8 12833@@ -42,6 +42,8 @@
4bf69007
AM
12834 #include <linux/nsproxy.h>
12835 #include <linux/mount.h>
12836 #include <linux/ipc_namespace.h>
12837+#include <linux/vs_context.h>
12838+#include <linux/vs_limit.h>
12839
bb20add7 12840 #include <linux/uaccess.h>
4bf69007 12841
cc23e853 12842@@ -228,10 +230,14 @@ static void shm_open(struct vm_area_stru
4bf69007
AM
12843 static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
12844 {
c2e5f7c8 12845 struct file *shm_file;
4bf69007
AM
12846+ struct vx_info *vxi = lookup_vx_info(shp->shm_perm.xid);
12847+ int numpages = (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
c2e5f7c8
JR
12848
12849 shm_file = shp->shm_file;
12850 shp->shm_file = NULL;
12851- ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
4bf69007
AM
12852+ vx_ipcshm_sub(vxi, shp, numpages);
12853+ ns->shm_tot -= numpages;
d337f35e 12854+
4bf69007
AM
12855 shm_rmid(ns, shp);
12856 shm_unlock(shp);
c2e5f7c8 12857 if (!is_file_hugepages(shm_file))
cc23e853
AM
12858@@ -240,6 +246,7 @@ static void shm_destroy(struct ipc_names
12859 user_shm_unlock(i_size_read(file_inode(shm_file)),
12860 shp->mlock_user);
c2e5f7c8 12861 fput(shm_file);
4bf69007 12862+ put_vx_info(vxi);
926e38e0 12863 ipc_rcu_putref(shp, shm_rcu_free);
4bf69007
AM
12864 }
12865
cc23e853 12866@@ -539,11 +546,15 @@ static int newseg(struct ipc_namespace *
bb20add7 12867 ns->shm_tot + numpages > ns->shm_ctlall)
4bf69007
AM
12868 return -ENOSPC;
12869
12870+ if (!vx_ipcshm_avail(current_vx_info(), numpages))
12871+ return -ENOSPC;
d337f35e 12872+
4bf69007
AM
12873 shp = ipc_rcu_alloc(sizeof(*shp));
12874 if (!shp)
12875 return -ENOMEM;
12876
12877 shp->shm_perm.key = key;
12878+ shp->shm_perm.xid = vx_current_xid();
12879 shp->shm_perm.mode = (shmflg & S_IRWXUGO);
12880 shp->mlock_user = NULL;
12881
cc23e853 12882@@ -614,6 +625,7 @@ static int newseg(struct ipc_namespace *
926e38e0
JR
12883
12884 ipc_unlock_object(&shp->shm_perm);
12885 rcu_read_unlock();
4bf69007
AM
12886+ vx_ipcshm_add(current_vx_info(), key, numpages);
12887 return error;
12888
12889 no_id:
cef7ea10
AM
12890diff -NurpP --minimal linux-4.9.82/kernel/Makefile linux-4.9.82-vs2.3.9.7/kernel/Makefile
12891--- linux-4.9.82/kernel/Makefile 2018-02-22 21:18:56.000000000 +0000
12892+++ linux-4.9.82-vs2.3.9.7/kernel/Makefile 2018-01-10 02:50:49.000000000 +0000
cc23e853 12893@@ -39,6 +39,7 @@ obj-y += printk/
c2e5f7c8
JR
12894 obj-y += irq/
12895 obj-y += rcu/
cc23e853 12896 obj-y += livepatch/
4bf69007
AM
12897+obj-y += vserver/
12898
b00e13aa
AM
12899 obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o
12900 obj-$(CONFIG_FREEZER) += freezer.o
cef7ea10
AM
12901diff -NurpP --minimal linux-4.9.82/kernel/auditsc.c linux-4.9.82-vs2.3.9.7/kernel/auditsc.c
12902--- linux-4.9.82/kernel/auditsc.c 2016-12-11 19:17:54.000000000 +0000
12903+++ linux-4.9.82-vs2.3.9.7/kernel/auditsc.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 12904@@ -1965,7 +1965,7 @@ static int audit_set_loginuid_perm(kuid_
c2e5f7c8 12905 if (is_audit_feature_set(AUDIT_FEATURE_LOGINUID_IMMUTABLE))
4bf69007 12906 return -EPERM;
c2e5f7c8 12907 /* it is set, you need permission */
4bf69007
AM
12908- if (!capable(CAP_AUDIT_CONTROL))
12909+ if (!vx_capable(CAP_AUDIT_CONTROL, VXC_AUDIT_CONTROL))
12910 return -EPERM;
c2e5f7c8
JR
12911 /* reject if this is not an unset and we don't allow that */
12912 if (is_audit_feature_set(AUDIT_FEATURE_ONLY_UNSET_LOGINUID) && uid_valid(loginuid))
cef7ea10
AM
12913diff -NurpP --minimal linux-4.9.82/kernel/capability.c linux-4.9.82-vs2.3.9.7/kernel/capability.c
12914--- linux-4.9.82/kernel/capability.c 2018-02-22 21:18:56.000000000 +0000
12915+++ linux-4.9.82-vs2.3.9.7/kernel/capability.c 2018-01-10 02:50:49.000000000 +0000
bb20add7 12916@@ -17,6 +17,7 @@
4bf69007
AM
12917 #include <linux/syscalls.h>
12918 #include <linux/pid_namespace.h>
12919 #include <linux/user_namespace.h>
12920+#include <linux/vs_context.h>
12921 #include <asm/uaccess.h>
12922
12923 /*
cc23e853 12924@@ -107,6 +108,7 @@ static int cap_validate_magic(cap_user_h
4bf69007
AM
12925 return 0;
12926 }
12927
2380c486 12928+
4bf69007
AM
12929 /*
12930 * The only thing that can change the capabilities of the current
12931 * process is the current process. As such, we can't be in this code
cc23e853 12932@@ -344,6 +346,8 @@ bool has_ns_capability_noaudit(struct ta
4bf69007
AM
12933 return (ret == 0);
12934 }
12935
12936+#include <linux/vserver/base.h>
d337f35e 12937+
4bf69007
AM
12938 /**
12939 * has_capability_noaudit - Does a task have a capability (unaudited) in the
12940 * initial user ns
cef7ea10
AM
12941diff -NurpP --minimal linux-4.9.82/kernel/compat.c linux-4.9.82-vs2.3.9.7/kernel/compat.c
12942--- linux-4.9.82/kernel/compat.c 2016-12-11 19:17:54.000000000 +0000
12943+++ linux-4.9.82-vs2.3.9.7/kernel/compat.c 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
12944@@ -27,6 +27,7 @@
12945 #include <linux/times.h>
12946 #include <linux/ptrace.h>
12947 #include <linux/gfp.h>
12948+#include <linux/vs_time.h>
12949
12950 #include <asm/uaccess.h>
12951
cc23e853 12952@@ -1059,7 +1060,7 @@ COMPAT_SYSCALL_DEFINE1(stime, compat_tim
4bf69007
AM
12953 if (err)
12954 return err;
12955
12956- do_settimeofday(&tv);
12957+ vx_settimeofday(&tv);
12958 return 0;
12959 }
12960
cef7ea10
AM
12961diff -NurpP --minimal linux-4.9.82/kernel/cred.c linux-4.9.82-vs2.3.9.7/kernel/cred.c
12962--- linux-4.9.82/kernel/cred.c 2016-12-11 19:17:54.000000000 +0000
12963+++ linux-4.9.82-vs2.3.9.7/kernel/cred.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 12964@@ -64,31 +64,6 @@ struct cred init_cred = {
b00e13aa 12965 .group_info = &init_groups,
4bf69007
AM
12966 };
12967
12968-static inline void set_cred_subscribers(struct cred *cred, int n)
12969-{
12970-#ifdef CONFIG_DEBUG_CREDENTIALS
12971- atomic_set(&cred->subscribers, n);
12972-#endif
12973-}
12974-
12975-static inline int read_cred_subscribers(const struct cred *cred)
12976-{
12977-#ifdef CONFIG_DEBUG_CREDENTIALS
12978- return atomic_read(&cred->subscribers);
12979-#else
12980- return 0;
12981-#endif
12982-}
12983-
12984-static inline void alter_cred_subscribers(const struct cred *_cred, int n)
12985-{
12986-#ifdef CONFIG_DEBUG_CREDENTIALS
12987- struct cred *cred = (struct cred *) _cred;
12988-
12989- atomic_add(n, &cred->subscribers);
12990-#endif
12991-}
12992-
12993 /*
b00e13aa 12994 * The RCU callback to actually dispose of a set of credentials
4bf69007 12995 */
cc23e853 12996@@ -240,21 +215,16 @@ error:
4bf69007
AM
12997 *
12998 * Call commit_creds() or abort_creds() to clean up.
12999 */
13000-struct cred *prepare_creds(void)
13001+struct cred *__prepare_creds(const struct cred *old)
13002 {
13003- struct task_struct *task = current;
13004- const struct cred *old;
13005 struct cred *new;
13006
13007- validate_process_creds();
13008-
13009 new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
13010 if (!new)
13011 return NULL;
13012
13013 kdebug("prepare_creds() alloc %p", new);
13014
13015- old = task->cred;
13016 memcpy(new, old, sizeof(struct cred));
13017
13018 atomic_set(&new->usage, 1);
cc23e853 13019@@ -283,6 +253,13 @@ error:
4bf69007
AM
13020 abort_creds(new);
13021 return NULL;
13022 }
d337f35e 13023+
4bf69007 13024+struct cred *prepare_creds(void)
2380c486 13025+{
4bf69007 13026+ validate_process_creds();
d337f35e 13027+
4bf69007 13028+ return __prepare_creds(current->cred);
2380c486 13029+}
4bf69007
AM
13030 EXPORT_SYMBOL(prepare_creds);
13031
13032 /*
cef7ea10
AM
13033diff -NurpP --minimal linux-4.9.82/kernel/exit.c linux-4.9.82-vs2.3.9.7/kernel/exit.c
13034--- linux-4.9.82/kernel/exit.c 2016-12-11 19:17:54.000000000 +0000
13035+++ linux-4.9.82-vs2.3.9.7/kernel/exit.c 2018-02-06 17:14:57.000000000 +0000
4bf69007
AM
13036@@ -48,6 +48,10 @@
13037 #include <linux/fs_struct.h>
13038 #include <linux/init_task.h>
13039 #include <linux/perf_event.h>
13040+#include <linux/vs_limit.h>
13041+#include <linux/vs_context.h>
13042+#include <linux/vs_network.h>
13043+#include <linux/vs_pid.h>
13044 #include <trace/events/sched.h>
13045 #include <linux/hw_breakpoint.h>
13046 #include <linux/oom.h>
cc23e853 13047@@ -531,14 +535,24 @@ static struct task_struct *find_child_re
4bf69007
AM
13048 {
13049 struct pid_namespace *pid_ns = task_active_pid_ns(father);
cc23e853 13050 struct task_struct *reaper = pid_ns->child_reaper;
4bf69007 13051+ struct vx_info *vxi = task_get_vx_info(father);
d337f35e 13052+
4bf69007
AM
13053+ if (vxi) {
13054+ BUG_ON(!vxi->vx_reaper);
13055+ if (vxi->vx_reaper != init_pid_ns.child_reaper &&
cc23e853 13056+ vxi->vx_reaper != father) {
4bf69007 13057+ reaper = vxi->vx_reaper;
cc23e853
AM
13058+ goto out_put;
13059+ }
13060+ }
4bf69007 13061
cc23e853
AM
13062 if (likely(reaper != father))
13063- return reaper;
13064+ goto out_put;
13065
13066 reaper = find_alive_thread(father);
13067 if (reaper) {
13068 pid_ns->child_reaper = reaper;
13069- return reaper;
13070+ goto out_put;
4bf69007
AM
13071 }
13072
cc23e853
AM
13073 write_unlock_irq(&tasklist_lock);
13074@@ -549,7 +563,10 @@ static struct task_struct *find_child_re
13075 zap_pid_ns_processes(pid_ns);
13076 write_lock_irq(&tasklist_lock);
13077
13078- return father;
13079+ reaper = father;
4bf69007
AM
13080+out_put:
13081+ put_vx_info(vxi);
13082+ return reaper;
13083 }
13084
13085 /*
cc23e853
AM
13086@@ -637,9 +654,13 @@ static void forget_original_parent(struc
13087 return;
bb20add7 13088
cc23e853
AM
13089 reaper = find_new_reaper(father, reaper);
13090- list_for_each_entry(p, &father->children, sibling) {
13091+ for (p = list_first_entry(&father->children, struct task_struct, sibling);
13092+ &p->sibling != &father->children; ) {
13093+ struct task_struct *next, *this_reaper = reaper;
13094+ if (p == reaper)
13095+ this_reaper = task_active_pid_ns(reaper)->child_reaper;
13096 for_each_thread(p, t) {
4bf69007 13097- t->real_parent = reaper;
cc23e853
AM
13098+ t->real_parent = this_reaper;
13099 BUG_ON((!t->ptrace) != (t->parent == father));
13100 if (likely(!t->ptrace))
13101 t->parent = t->real_parent;
13102@@ -651,10 +672,13 @@ static void forget_original_parent(struc
13103 * If this is a threaded reparent there is no need to
13104 * notify anyone anything has happened.
13105 */
13106- if (!same_thread_group(reaper, father))
13107+ if (!same_thread_group(this_reaper, father))
13108 reparent_leader(father, p, dead);
13109+ next = list_next_entry(p, sibling);
13110+ list_add(&p->sibling, &this_reaper->children);
13111+ p = next;
13112 }
13113- list_splice_tail_init(&father->children, &reaper->children);
13114+ INIT_LIST_HEAD(&father->children);
13115 }
13116
13117 /*
13118@@ -844,6 +868,9 @@ void __noreturn do_exit(long code)
4bf69007 13119 */
c2e5f7c8 13120 flush_ptrace_hw_breakpoint(tsk);
4bf69007
AM
13121
13122+ /* needs to stay before exit_notify() */
13123+ exit_vx_info_early(tsk, code);
d337f35e 13124+
cc23e853 13125 TASKS_RCU(preempt_disable());
bb20add7 13126 TASKS_RCU(tasks_rcu_i = __srcu_read_lock(&tasks_rcu_exit_srcu));
cc23e853 13127 TASKS_RCU(preempt_enable());
5ba7a31c 13128@@ -876,6 +903,10 @@ void __noreturn do_exit(long code)
4bf69007 13129
5ba7a31c
AM
13130 validate_creds_for_do_exit(tsk);
13131
13132+ /* needs to stay after exit_notify() and before preempt_disable() */
4bf69007
AM
13133+ exit_vx_info(tsk, code);
13134+ exit_nx_info(tsk);
d337f35e 13135+
5ba7a31c
AM
13136 check_stack_usage();
13137 preempt_disable();
13138 if (tsk->nr_dirtied)
cef7ea10
AM
13139diff -NurpP --minimal linux-4.9.82/kernel/fork.c linux-4.9.82-vs2.3.9.7/kernel/fork.c
13140--- linux-4.9.82/kernel/fork.c 2018-02-22 21:18:56.000000000 +0000
13141+++ linux-4.9.82-vs2.3.9.7/kernel/fork.c 2018-01-10 09:23:14.000000000 +0000
cc23e853 13142@@ -77,6 +77,9 @@
265de2f7 13143 #include <linux/compiler.h>
cc23e853
AM
13144 #include <linux/sysctl.h>
13145 #include <linux/kcov.h>
4bf69007
AM
13146+#include <linux/vs_context.h>
13147+#include <linux/vs_network.h>
13148+#include <linux/vs_limit.h>
13149
13150 #include <asm/pgtable.h>
13151 #include <asm/pgalloc.h>
cc23e853
AM
13152@@ -353,6 +356,8 @@ void free_task(struct task_struct *tsk)
13153 WARN_ON_ONCE(atomic_read(&tsk->stack_refcount) != 0);
13154 #endif
4bf69007
AM
13155 rt_mutex_debug_task_free(tsk);
13156+ clr_vx_info(&tsk->vx_info);
13157+ clr_nx_info(&tsk->nx_info);
13158 ftrace_graph_exit_task(tsk);
13159 put_seccomp_filter(tsk);
13160 arch_release_task_struct(tsk);
cc23e853 13161@@ -1475,6 +1480,8 @@ static __latent_entropy struct task_stru
8d50a2ea 13162 {
4bf69007
AM
13163 int retval;
13164 struct task_struct *p;
4bf69007
AM
13165+ struct vx_info *vxi;
13166+ struct nx_info *nxi;
13167
13168 if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
13169 return ERR_PTR(-EINVAL);
cc23e853 13170@@ -1535,7 +1542,12 @@ static __latent_entropy struct task_stru
4bf69007
AM
13171 DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
13172 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
13173 #endif
13174+ init_vx_info(&p->vx_info, current_vx_info());
13175+ init_nx_info(&p->nx_info, current_nx_info());
13176+
13177 retval = -EAGAIN;
13178+ if (!vx_nproc_avail(1))
13179+ goto bad_fork_free;
13180 if (atomic_read(&p->real_cred->user->processes) >=
13181 task_rlimit(p, RLIMIT_NPROC)) {
c2e5f7c8 13182 if (p->real_cred->user != INIT_USER &&
cc23e853 13183@@ -1832,6 +1844,18 @@ static __latent_entropy struct task_stru
4bf69007
AM
13184 total_forks++;
13185 spin_unlock(&current->sighand->siglock);
bb20add7 13186 syscall_tracepoint_update(p);
4bf69007
AM
13187+
13188+ /* p is copy of current */
13189+ vxi = p->vx_info;
13190+ if (vxi) {
13191+ claim_vx_info(vxi, p);
13192+ atomic_inc(&vxi->cvirt.nr_threads);
13193+ atomic_inc(&vxi->cvirt.total_forks);
13194+ vx_nproc_inc(p);
2380c486 13195+ }
4bf69007
AM
13196+ nxi = p->nx_info;
13197+ if (nxi)
13198+ claim_nx_info(nxi, p);
13199 write_unlock_irq(&tasklist_lock);
bb20add7 13200
4bf69007 13201 proc_fork_connector(p);
cef7ea10
AM
13202diff -NurpP --minimal linux-4.9.82/kernel/kthread.c linux-4.9.82-vs2.3.9.7/kernel/kthread.c
13203--- linux-4.9.82/kernel/kthread.c 2018-02-22 21:18:56.000000000 +0000
13204+++ linux-4.9.82-vs2.3.9.7/kernel/kthread.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 13205@@ -19,6 +19,7 @@
4bf69007 13206 #include <linux/ptrace.h>
09be7631 13207 #include <linux/uaccess.h>
cc23e853 13208 #include <linux/cgroup.h>
4bf69007
AM
13209+#include <linux/vs_pid.h>
13210 #include <trace/events/sched.h>
13211
13212 static DEFINE_SPINLOCK(kthread_create_lock);
cef7ea10
AM
13213diff -NurpP --minimal linux-4.9.82/kernel/nsproxy.c linux-4.9.82-vs2.3.9.7/kernel/nsproxy.c
13214--- linux-4.9.82/kernel/nsproxy.c 2016-12-11 19:17:54.000000000 +0000
13215+++ linux-4.9.82-vs2.3.9.7/kernel/nsproxy.c 2018-01-14 06:25:23.000000000 +0000
cc23e853 13216@@ -20,12 +20,15 @@
4bf69007
AM
13217 #include <linux/mnt_namespace.h>
13218 #include <linux/utsname.h>
13219 #include <linux/pid_namespace.h>
13220+#include <linux/vserver/global.h>
13221+#include <linux/vserver/debug.h>
13222 #include <net/net_namespace.h>
13223 #include <linux/ipc_namespace.h>
09be7631 13224 #include <linux/proc_ns.h>
4bf69007
AM
13225 #include <linux/file.h>
13226 #include <linux/syscalls.h>
cc23e853 13227 #include <linux/cgroup.h>
4bf69007
AM
13228+#include "../fs/mount.h"
13229
13230 static struct kmem_cache *nsproxy_cachep;
13231
cc23e853 13232@@ -50,8 +53,11 @@ static inline struct nsproxy *create_nsp
4bf69007
AM
13233 struct nsproxy *nsproxy;
13234
13235 nsproxy = kmem_cache_alloc(nsproxy_cachep, GFP_KERNEL);
13236- if (nsproxy)
13237+ if (nsproxy) {
13238 atomic_set(&nsproxy->count, 1);
13239+ atomic_inc(&vs_global_nsproxy);
13240+ }
13241+ vxdprintk(VXD_CBIT(space, 2), "create_nsproxy = %p[1]", nsproxy);
13242 return nsproxy;
13243 }
13244
cc23e853 13245@@ -60,9 +66,12 @@ static inline struct nsproxy *create_nsp
4bf69007
AM
13246 * Return the newly created nsproxy. Do not attach this to the task,
13247 * leave it to the caller to do proper locking and attach it to task.
13248 */
13249-static struct nsproxy *create_new_namespaces(unsigned long flags,
b00e13aa
AM
13250- struct task_struct *tsk, struct user_namespace *user_ns,
13251- struct fs_struct *new_fs)
13252+static struct nsproxy *unshare_namespaces(
13253+ unsigned long flags,
13254+ struct nsproxy *orig,
13255+ struct fs_struct *new_fs,
13256+ struct user_namespace *new_user,
13257+ struct pid_namespace *new_pid)
4bf69007
AM
13258 {
13259 struct nsproxy *new_nsp;
13260 int err;
cc23e853 13261@@ -71,39 +80,37 @@ static struct nsproxy *create_new_namesp
4bf69007
AM
13262 if (!new_nsp)
13263 return ERR_PTR(-ENOMEM);
13264
b00e13aa
AM
13265- new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, user_ns, new_fs);
13266+ new_nsp->mnt_ns = copy_mnt_ns(flags, orig->mnt_ns, new_user, new_fs);
4bf69007
AM
13267 if (IS_ERR(new_nsp->mnt_ns)) {
13268 err = PTR_ERR(new_nsp->mnt_ns);
13269 goto out_ns;
13270 }
13271
b00e13aa
AM
13272- new_nsp->uts_ns = copy_utsname(flags, user_ns, tsk->nsproxy->uts_ns);
13273+ new_nsp->uts_ns = copy_utsname(flags, new_user, orig->uts_ns);
4bf69007
AM
13274 if (IS_ERR(new_nsp->uts_ns)) {
13275 err = PTR_ERR(new_nsp->uts_ns);
13276 goto out_uts;
13277 }
13278
b00e13aa
AM
13279- new_nsp->ipc_ns = copy_ipcs(flags, user_ns, tsk->nsproxy->ipc_ns);
13280+ new_nsp->ipc_ns = copy_ipcs(flags, new_user, orig->ipc_ns);
4bf69007
AM
13281 if (IS_ERR(new_nsp->ipc_ns)) {
13282 err = PTR_ERR(new_nsp->ipc_ns);
13283 goto out_ipc;
13284 }
13285
c2e5f7c8
JR
13286- new_nsp->pid_ns_for_children =
13287- copy_pid_ns(flags, user_ns, tsk->nsproxy->pid_ns_for_children);
13288+ new_nsp->pid_ns_for_children = copy_pid_ns(flags, new_user, new_pid);
13289 if (IS_ERR(new_nsp->pid_ns_for_children)) {
13290 err = PTR_ERR(new_nsp->pid_ns_for_children);
4bf69007
AM
13291 goto out_pid;
13292 }
13293
cc23e853
AM
13294- new_nsp->cgroup_ns = copy_cgroup_ns(flags, user_ns,
13295- tsk->nsproxy->cgroup_ns);
13296+ new_nsp->cgroup_ns = copy_cgroup_ns(flags, new_user, orig->cgroup_ns);
13297 if (IS_ERR(new_nsp->cgroup_ns)) {
13298 err = PTR_ERR(new_nsp->cgroup_ns);
13299 goto out_cgroup;
13300 }
13301
b00e13aa
AM
13302- new_nsp->net_ns = copy_net_ns(flags, user_ns, tsk->nsproxy->net_ns);
13303+ new_nsp->net_ns = copy_net_ns(flags, new_user, orig->net_ns);
4bf69007
AM
13304 if (IS_ERR(new_nsp->net_ns)) {
13305 err = PTR_ERR(new_nsp->net_ns);
13306 goto out_net;
cc23e853 13307@@ -130,6 +137,43 @@ out_ns:
4bf69007
AM
13308 return ERR_PTR(err);
13309 }
13310
13311+static struct nsproxy *create_new_namespaces(unsigned long flags,
b00e13aa
AM
13312+ struct task_struct *tsk, struct user_namespace *user_ns,
13313+ struct fs_struct *new_fs)
13314+
4bf69007
AM
13315+{
13316+ return unshare_namespaces(flags, tsk->nsproxy,
b00e13aa 13317+ new_fs, user_ns, task_active_pid_ns(tsk));
2380c486 13318+}
d337f35e 13319+
4bf69007
AM
13320+/*
13321+ * copies the nsproxy, setting refcount to 1, and grabbing a
13322+ * reference to all contained namespaces.
13323+ */
13324+struct nsproxy *copy_nsproxy(struct nsproxy *orig)
2380c486 13325+{
4bf69007 13326+ struct nsproxy *ns = create_nsproxy();
d337f35e 13327+
4bf69007
AM
13328+ if (ns) {
13329+ memcpy(ns, orig, sizeof(struct nsproxy));
13330+ atomic_set(&ns->count, 1);
d337f35e 13331+
4bf69007
AM
13332+ if (ns->mnt_ns)
13333+ get_mnt_ns(ns->mnt_ns);
13334+ if (ns->uts_ns)
13335+ get_uts_ns(ns->uts_ns);
13336+ if (ns->ipc_ns)
13337+ get_ipc_ns(ns->ipc_ns);
c2e5f7c8
JR
13338+ if (ns->pid_ns_for_children)
13339+ get_pid_ns(ns->pid_ns_for_children);
4bf69007
AM
13340+ if (ns->net_ns)
13341+ get_net(ns->net_ns);
cc23e853
AM
13342+ if (ns->cgroup_ns)
13343+ get_cgroup_ns(ns->cgroup_ns);
4bf69007
AM
13344+ }
13345+ return ns;
13346+}
d337f35e 13347+
4bf69007
AM
13348 /*
13349 * called from clone. This now handles copy for nsproxy and all
13350 * namespaces therein.
cc23e853 13351@@ -138,7 +182,10 @@ int copy_namespaces(unsigned long flags,
4bf69007
AM
13352 {
13353 struct nsproxy *old_ns = tsk->nsproxy;
b00e13aa 13354 struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns);
4bf69007
AM
13355- struct nsproxy *new_ns;
13356+ struct nsproxy *new_ns = NULL;
c2e5f7c8 13357+
4bf69007
AM
13358+ vxdprintk(VXD_CBIT(space, 7), "copy_namespaces(0x%08lx,%p[%p])",
13359+ flags, tsk, old_ns);
4bf69007 13360
c2e5f7c8 13361 if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
cc23e853
AM
13362 CLONE_NEWPID | CLONE_NEWNET |
13363@@ -147,7 +194,7 @@ int copy_namespaces(unsigned long flags,
4bf69007 13364 return 0;
4bf69007 13365 }
4bf69007 13366
c2e5f7c8
JR
13367- if (!ns_capable(user_ns, CAP_SYS_ADMIN))
13368+ if (!vx_ns_can_unshare(user_ns, CAP_SYS_ADMIN, flags))
13369 return -EPERM;
13370
13371 /*
cc23e853 13372@@ -166,6 +213,9 @@ int copy_namespaces(unsigned long flags,
c2e5f7c8
JR
13373 return PTR_ERR(new_ns);
13374
13375 tsk->nsproxy = new_ns;
4bf69007 13376+ vxdprintk(VXD_CBIT(space, 3),
c2e5f7c8
JR
13377+ "copy_namespaces(0x%08lx,%p[%p]) = [%p]",
13378+ flags, tsk, old_ns, new_ns);
13379 return 0;
4bf69007
AM
13380 }
13381
cc23e853 13382@@ -179,8 +229,10 @@ void free_nsproxy(struct nsproxy *ns)
4bf69007 13383 put_ipc_ns(ns->ipc_ns);
c2e5f7c8
JR
13384 if (ns->pid_ns_for_children)
13385 put_pid_ns(ns->pid_ns_for_children);
4bf69007
AM
13386+ if (ns->net_ns)
13387+ put_net(ns->net_ns);
cc23e853
AM
13388 put_cgroup_ns(ns->cgroup_ns);
13389- put_net(ns->net_ns);
4bf69007
AM
13390+ atomic_dec(&vs_global_nsproxy);
13391 kmem_cache_free(nsproxy_cachep, ns);
13392 }
13393
cc23e853 13394@@ -194,12 +246,16 @@ int unshare_nsproxy_namespaces(unsigned
b00e13aa 13395 struct user_namespace *user_ns;
4bf69007
AM
13396 int err = 0;
13397
13398+ vxdprintk(VXD_CBIT(space, 4),
13399+ "unshare_nsproxy_namespaces(0x%08lx,[%p])",
13400+ unshare_flags, current->nsproxy);
d337f35e 13401+
4bf69007 13402 if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
cc23e853 13403 CLONE_NEWNET | CLONE_NEWPID | CLONE_NEWCGROUP)))
4bf69007
AM
13404 return 0;
13405
b00e13aa
AM
13406 user_ns = new_cred ? new_cred->user_ns : current_user_ns();
13407- if (!ns_capable(user_ns, CAP_SYS_ADMIN))
13408+ if (!vx_ns_can_unshare(user_ns, CAP_SYS_ADMIN, unshare_flags))
4bf69007
AM
13409 return -EPERM;
13410
b00e13aa 13411 *new_nsp = create_new_namespaces(unshare_flags, current, user_ns,
cef7ea10
AM
13412diff -NurpP --minimal linux-4.9.82/kernel/pid.c linux-4.9.82-vs2.3.9.7/kernel/pid.c
13413--- linux-4.9.82/kernel/pid.c 2018-02-22 21:18:56.000000000 +0000
13414+++ linux-4.9.82-vs2.3.9.7/kernel/pid.c 2018-01-10 02:50:49.000000000 +0000
09be7631 13415@@ -38,6 +38,7 @@
4bf69007 13416 #include <linux/syscalls.h>
09be7631 13417 #include <linux/proc_ns.h>
b00e13aa 13418 #include <linux/proc_fs.h>
4bf69007
AM
13419+#include <linux/vs_pid.h>
13420
13421 #define pid_hashfn(nr, ns) \
13422 hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
cc23e853 13423@@ -379,7 +380,7 @@ EXPORT_SYMBOL_GPL(find_pid_ns);
4bf69007
AM
13424
13425 struct pid *find_vpid(int nr)
13426 {
b00e13aa
AM
13427- return find_pid_ns(nr, task_active_pid_ns(current));
13428+ return find_pid_ns(vx_rmap_pid(nr), task_active_pid_ns(current));
4bf69007
AM
13429 }
13430 EXPORT_SYMBOL_GPL(find_vpid);
13431
cc23e853 13432@@ -435,6 +436,9 @@ void transfer_pid(struct task_struct *ol
4bf69007
AM
13433 struct task_struct *pid_task(struct pid *pid, enum pid_type type)
13434 {
13435 struct task_struct *result = NULL;
d337f35e 13436+
cc23e853 13437+ if (type == __PIDTYPE_REALPID)
4bf69007
AM
13438+ type = PIDTYPE_PID;
13439 if (pid) {
13440 struct hlist_node *first;
13441 first = rcu_dereference_check(hlist_first_rcu(&pid->tasks[type]),
cc23e853
AM
13442@@ -453,7 +457,7 @@ struct task_struct *find_task_by_pid_ns(
13443 {
13444 RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
13445 "find_task_by_pid_ns() needs rcu_read_lock() protection");
4bf69007
AM
13446- return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
13447+ return pid_task(find_pid_ns(vx_rmap_pid(nr), ns), PIDTYPE_PID);
13448 }
13449
13450 struct task_struct *find_task_by_vpid(pid_t vnr)
cc23e853 13451@@ -497,7 +501,7 @@ struct pid *find_get_pid(pid_t nr)
4bf69007
AM
13452 }
13453 EXPORT_SYMBOL_GPL(find_get_pid);
13454
13455-pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
13456+pid_t pid_unmapped_nr_ns(struct pid *pid, struct pid_namespace *ns)
13457 {
13458 struct upid *upid;
13459 pid_t nr = 0;
cc23e853 13460@@ -511,6 +515,11 @@ pid_t pid_nr_ns(struct pid *pid, struct
4bf69007
AM
13461 }
13462 EXPORT_SYMBOL_GPL(pid_nr_ns);
13463
13464+pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
2380c486 13465+{
4bf69007
AM
13466+ return vx_map_pid(pid_unmapped_nr_ns(pid, ns));
13467+}
d337f35e 13468+
4bf69007
AM
13469 pid_t pid_vnr(struct pid *pid)
13470 {
b00e13aa 13471 return pid_nr_ns(pid, task_active_pid_ns(current));
cef7ea10
AM
13472diff -NurpP --minimal linux-4.9.82/kernel/pid_namespace.c linux-4.9.82-vs2.3.9.7/kernel/pid_namespace.c
13473--- linux-4.9.82/kernel/pid_namespace.c 2018-02-22 21:18:56.000000000 +0000
13474+++ linux-4.9.82-vs2.3.9.7/kernel/pid_namespace.c 2018-01-10 02:50:49.000000000 +0000
b00e13aa 13475@@ -18,6 +18,7 @@
09be7631 13476 #include <linux/proc_ns.h>
4bf69007
AM
13477 #include <linux/reboot.h>
13478 #include <linux/export.h>
13479+#include <linux/vserver/global.h>
13480
09be7631
JR
13481 struct pid_cache {
13482 int nr_ids;
cc23e853
AM
13483@@ -124,6 +125,7 @@ static struct pid_namespace *create_pid_
13484 ns->ns.ops = &pidns_operations;
4bf69007
AM
13485
13486 kref_init(&ns->kref);
13487+ atomic_inc(&vs_global_pid_ns);
13488 ns->level = level;
13489 ns->parent = get_pid_ns(parent_pid_ns);
b00e13aa 13490 ns->user_ns = get_user_ns(user_ns);
cc23e853 13491@@ -142,6 +144,7 @@ static struct pid_namespace *create_pid_
c2e5f7c8
JR
13492 out_free_map:
13493 kfree(ns->pidmap[0].page);
13494 out_free:
4bf69007
AM
13495+ atomic_dec(&vs_global_pid_ns);
13496 kmem_cache_free(pid_ns_cachep, ns);
cc23e853
AM
13497 out_dec:
13498 dec_pid_namespaces(ucounts);
cef7ea10
AM
13499diff -NurpP --minimal linux-4.9.82/kernel/printk/printk.c linux-4.9.82-vs2.3.9.7/kernel/printk/printk.c
13500--- linux-4.9.82/kernel/printk/printk.c 2018-02-22 21:18:56.000000000 +0000
13501+++ linux-4.9.82-vs2.3.9.7/kernel/printk/printk.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 13502@@ -45,6 +45,7 @@
09be7631 13503 #include <linux/utsname.h>
bb20add7 13504 #include <linux/ctype.h>
cc23e853 13505 #include <linux/uio.h>
4bf69007
AM
13506+#include <linux/vs_cvirt.h>
13507
13508 #include <asm/uaccess.h>
cc23e853
AM
13509 #include <asm/sections.h>
13510@@ -612,7 +613,7 @@ int check_syslog_permissions(int type, i
13511 goto ok;
4bf69007
AM
13512
13513 if (syslog_action_restricted(type)) {
13514- if (capable(CAP_SYSLOG))
13515+ if (vx_capable(CAP_SYSLOG, VXC_SYSLOG))
cc23e853 13516 goto ok;
092a4f51
JR
13517 /*
13518 * For historical reasons, accept CAP_SYS_ADMIN too, with
cc23e853 13519@@ -1432,12 +1433,9 @@ int do_syslog(int type, char __user *buf
4bf69007 13520 if (error)
cc23e853 13521 goto out;
4bf69007
AM
13522
13523- switch (type) {
13524- case SYSLOG_ACTION_CLOSE: /* Close log */
13525- break;
13526- case SYSLOG_ACTION_OPEN: /* Open log */
13527- break;
13528- case SYSLOG_ACTION_READ: /* Read from log */
13529+ if ((type == SYSLOG_ACTION_READ) ||
13530+ (type == SYSLOG_ACTION_READ_ALL) ||
13531+ (type == SYSLOG_ACTION_READ_CLEAR)) {
13532 error = -EINVAL;
13533 if (!buf || len < 0)
13534 goto out;
cc23e853 13535@@ -1448,6 +1446,16 @@ int do_syslog(int type, char __user *buf
4bf69007
AM
13536 error = -EFAULT;
13537 goto out;
13538 }
13539+ }
13540+ if (!vx_check(0, VS_ADMIN|VS_WATCH))
13541+ return vx_do_syslog(type, buf, len);
d337f35e 13542+
4bf69007
AM
13543+ switch (type) {
13544+ case SYSLOG_ACTION_CLOSE: /* Close log */
13545+ break;
13546+ case SYSLOG_ACTION_OPEN: /* Open log */
13547+ break;
13548+ case SYSLOG_ACTION_READ: /* Read from log */
13549 error = wait_event_interruptible(log_wait,
13550 syslog_seq != log_next_seq);
13551 if (error)
cc23e853 13552@@ -1460,16 +1468,6 @@ int do_syslog(int type, char __user *buf
4bf69007
AM
13553 /* FALL THRU */
13554 /* Read last kernel messages */
13555 case SYSLOG_ACTION_READ_ALL:
13556- error = -EINVAL;
13557- if (!buf || len < 0)
13558- goto out;
13559- error = 0;
13560- if (!len)
13561- goto out;
13562- if (!access_ok(VERIFY_WRITE, buf, len)) {
13563- error = -EFAULT;
13564- goto out;
13565- }
13566 error = syslog_print_all(buf, len, clear);
13567 break;
13568 /* Clear ring buffer */
cef7ea10
AM
13569diff -NurpP --minimal linux-4.9.82/kernel/ptrace.c linux-4.9.82-vs2.3.9.7/kernel/ptrace.c
13570--- linux-4.9.82/kernel/ptrace.c 2018-02-22 21:18:56.000000000 +0000
13571+++ linux-4.9.82-vs2.3.9.7/kernel/ptrace.c 2018-01-10 02:50:49.000000000 +0000
09be7631 13572@@ -23,6 +23,7 @@
4bf69007
AM
13573 #include <linux/syscalls.h>
13574 #include <linux/uaccess.h>
13575 #include <linux/regset.h>
13576+#include <linux/vs_context.h>
13577 #include <linux/hw_breakpoint.h>
13578 #include <linux/cn_proc.h>
09be7631 13579 #include <linux/compat.h>
cc23e853
AM
13580@@ -325,6 +326,11 @@ ok:
13581 !ptrace_has_cap(mm->user_ns, mode)))
13582 return -EPERM;
b00e13aa 13583
4bf69007
AM
13584+ if (!vx_check(task->xid, VS_ADMIN_P|VS_WATCH_P|VS_IDENT))
13585+ return -EPERM;
13586+ if (!vx_check(task->xid, VS_IDENT) &&
13587+ !task_vx_flags(task, VXF_STATE_ADMIN, 0))
13588+ return -EACCES;
4bf69007
AM
13589 return security_ptrace_access_check(task, mode);
13590 }
b00e13aa 13591
cef7ea10
AM
13592diff -NurpP --minimal linux-4.9.82/kernel/reboot.c linux-4.9.82-vs2.3.9.7/kernel/reboot.c
13593--- linux-4.9.82/kernel/reboot.c 2016-12-11 19:17:54.000000000 +0000
13594+++ linux-4.9.82-vs2.3.9.7/kernel/reboot.c 2018-01-10 02:50:49.000000000 +0000
c2e5f7c8
JR
13595@@ -16,6 +16,7 @@
13596 #include <linux/syscalls.h>
13597 #include <linux/syscore_ops.h>
13598 #include <linux/uaccess.h>
13599+#include <linux/vs_pid.h>
13600
13601 /*
13602 * this indicates whether you can reboot with ctrl-alt-del: the default is yes
bb20add7 13603@@ -269,6 +270,8 @@ EXPORT_SYMBOL_GPL(kernel_power_off);
c2e5f7c8
JR
13604
13605 static DEFINE_MUTEX(reboot_mutex);
13606
13607+long vs_reboot(unsigned int, void __user *);
13608+
13609 /*
13610 * Reboot system call: for obvious reasons only root may call it,
13611 * and even root needs to set up some magic numbers in the registers
bb20add7 13612@@ -311,6 +314,9 @@ SYSCALL_DEFINE4(reboot, int, magic1, int
c2e5f7c8
JR
13613 if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
13614 cmd = LINUX_REBOOT_CMD_HALT;
13615
13616+ if (!vx_check(0, VS_ADMIN|VS_WATCH))
13617+ return vs_reboot(cmd, arg);
13618+
13619 mutex_lock(&reboot_mutex);
13620 switch (cmd) {
13621 case LINUX_REBOOT_CMD_RESTART:
cef7ea10
AM
13622diff -NurpP --minimal linux-4.9.82/kernel/sched/core.c linux-4.9.82-vs2.3.9.7/kernel/sched/core.c
13623--- linux-4.9.82/kernel/sched/core.c 2018-02-22 21:18:56.000000000 +0000
13624+++ linux-4.9.82-vs2.3.9.7/kernel/sched/core.c 2018-02-22 21:31:40.000000000 +0000
cc23e853 13625@@ -75,6 +75,8 @@
265de2f7 13626 #include <linux/compiler.h>
cc23e853
AM
13627 #include <linux/frame.h>
13628 #include <linux/prefetch.h>
4bf69007
AM
13629+#include <linux/vs_sched.h>
13630+#include <linux/vs_cvirt.h>
13631
13632 #include <asm/switch_to.h>
13633 #include <asm/tlb.h>
cc23e853
AM
13634@@ -3429,6 +3431,7 @@ void __noreturn do_task_dead(void)
13635 __set_current_state(TASK_DEAD);
13636 current->flags |= PF_NOFREEZE; /* tell freezer to ignore us */
13637 __schedule(false);
13638+ printk("bad task: %p [%lx]\n", current, current->state);
13639 BUG();
13640 /* Avoid "noreturn function does return". */
13641 for (;;)
13642@@ -3822,7 +3825,7 @@ SYSCALL_DEFINE1(nice, int, increment)
4bf69007 13643
bb20add7 13644 nice = clamp_val(nice, MIN_NICE, MAX_NICE);
4bf69007
AM
13645 if (increment < 0 && !can_nice(current, nice))
13646- return -EPERM;
13647+ return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
13648
13649 retval = security_task_setnice(current, nice);
13650 if (retval)
cef7ea10
AM
13651diff -NurpP --minimal linux-4.9.82/kernel/sched/cputime.c linux-4.9.82-vs2.3.9.7/kernel/sched/cputime.c
13652--- linux-4.9.82/kernel/sched/cputime.c 2016-12-11 19:17:54.000000000 +0000
13653+++ linux-4.9.82-vs2.3.9.7/kernel/sched/cputime.c 2018-01-10 02:50:49.000000000 +0000
b00e13aa 13654@@ -4,6 +4,7 @@
4bf69007
AM
13655 #include <linux/kernel_stat.h>
13656 #include <linux/static_key.h>
b00e13aa 13657 #include <linux/context_tracking.h>
4bf69007
AM
13658+#include <linux/vs_sched.h>
13659 #include "sched.h"
cc23e853
AM
13660 #ifdef CONFIG_PARAVIRT
13661 #include <asm/paravirt.h>
13662@@ -133,14 +134,17 @@ static inline void task_group_account_fi
4bf69007
AM
13663 void account_user_time(struct task_struct *p, cputime_t cputime,
13664 cputime_t cputime_scaled)
13665 {
13666+ struct vx_info *vxi = p->vx_info; /* p is _always_ current */
ca5d134c 13667+ int nice = (task_nice(p) > 0);
4bf69007
AM
13668 int index;
13669
13670 /* Add user time to process. */
13671 p->utime += cputime;
13672 p->utimescaled += cputime_scaled;
13673+ vx_account_user(vxi, cputime, nice);
13674 account_group_user_time(p, cputime);
13675
ca5d134c 13676- index = (task_nice(p) > 0) ? CPUTIME_NICE : CPUTIME_USER;
4bf69007
AM
13677+ index = (nice) ? CPUTIME_NICE : CPUTIME_USER;
13678
13679 /* Add user time to cpustat. */
13680 task_group_account_field(p, index, (__force u64) cputime);
cc23e853 13681@@ -187,9 +191,12 @@ static inline
ca5d134c
JR
13682 void __account_system_time(struct task_struct *p, cputime_t cputime,
13683 cputime_t cputime_scaled, int index)
13684 {
13685+ struct vx_info *vxi = p->vx_info; /* p is _always_ current */
13686+
13687 /* Add system time to process. */
13688 p->stime += cputime;
13689 p->stimescaled += cputime_scaled;
13690+ vx_account_system(vxi, cputime, 0 /* do we have idle time? */);
13691 account_group_system_time(p, cputime);
13692
13693 /* Add system time to cpustat. */
cef7ea10
AM
13694diff -NurpP --minimal linux-4.9.82/kernel/sched/fair.c linux-4.9.82-vs2.3.9.7/kernel/sched/fair.c
13695--- linux-4.9.82/kernel/sched/fair.c 2018-02-22 21:18:57.000000000 +0000
13696+++ linux-4.9.82-vs2.3.9.7/kernel/sched/fair.c 2018-01-10 02:50:49.000000000 +0000
bb20add7 13697@@ -30,6 +30,7 @@
b00e13aa
AM
13698 #include <linux/mempolicy.h>
13699 #include <linux/migrate.h>
13700 #include <linux/task_work.h>
4bf69007
AM
13701+#include <linux/vs_cvirt.h>
13702
13703 #include <trace/events/sched.h>
13704
cc23e853 13705@@ -3410,6 +3411,8 @@ enqueue_entity(struct cfs_rq *cfs_rq, st
4bf69007
AM
13706 __enqueue_entity(cfs_rq, se);
13707 se->on_rq = 1;
13708
13709+ if (entity_is_task(se))
13710+ vx_activate_task(task_of(se));
13711 if (cfs_rq->nr_running == 1) {
13712 list_add_leaf_cfs_rq(cfs_rq);
13713 check_enqueue_throttle(cfs_rq);
cc23e853 13714@@ -3479,6 +3482,8 @@ dequeue_entity(struct cfs_rq *cfs_rq, st
4bf69007
AM
13715 if (se != cfs_rq->curr)
13716 __dequeue_entity(cfs_rq, se);
13717 se->on_rq = 0;
13718+ if (entity_is_task(se))
13719+ vx_deactivate_task(task_of(se));
4bf69007
AM
13720 account_entity_dequeue(cfs_rq, se);
13721
b00e13aa 13722 /*
cef7ea10
AM
13723diff -NurpP --minimal linux-4.9.82/kernel/sched/loadavg.c linux-4.9.82-vs2.3.9.7/kernel/sched/loadavg.c
13724--- linux-4.9.82/kernel/sched/loadavg.c 2018-02-22 21:18:57.000000000 +0000
13725+++ linux-4.9.82-vs2.3.9.7/kernel/sched/loadavg.c 2018-01-29 08:40:41.000000000 +0000
5ba7a31c
AM
13726@@ -73,9 +73,16 @@ EXPORT_SYMBOL(avenrun); /* should be rem
13727 */
13728 void get_avenrun(unsigned long *loads, unsigned long offset, int shift)
13729 {
13730- loads[0] = (avenrun[0] + offset) << shift;
13731- loads[1] = (avenrun[1] + offset) << shift;
13732- loads[2] = (avenrun[2] + offset) << shift;
13733+ if (vx_flags(VXF_VIRT_LOAD, 0)) {
13734+ struct vx_info *vxi = current_vx_info();
13735+ loads[0] = (vxi->cvirt.load[0] + offset) << shift;
13736+ loads[1] = (vxi->cvirt.load[1] + offset) << shift;
13737+ loads[2] = (vxi->cvirt.load[2] + offset) << shift;
13738+ } else {
13739+ loads[0] = (avenrun[0] + offset) << shift;
13740+ loads[1] = (avenrun[1] + offset) << shift;
13741+ loads[2] = (avenrun[2] + offset) << shift;
13742+ }
13743 }
13744
13745 long calc_load_fold_active(struct rq *this_rq, long adjust)
cef7ea10
AM
13746diff -NurpP --minimal linux-4.9.82/kernel/signal.c linux-4.9.82-vs2.3.9.7/kernel/signal.c
13747--- linux-4.9.82/kernel/signal.c 2018-02-22 21:18:57.000000000 +0000
13748+++ linux-4.9.82-vs2.3.9.7/kernel/signal.c 2018-01-13 21:30:31.000000000 +0000
bb20add7 13749@@ -34,6 +34,8 @@
b00e13aa 13750 #include <linux/compat.h>
09be7631 13751 #include <linux/cn_proc.h>
265de2f7 13752 #include <linux/compiler.h>
4bf69007
AM
13753+#include <linux/vs_context.h>
13754+#include <linux/vs_pid.h>
265de2f7 13755
4bf69007
AM
13756 #define CREATE_TRACE_POINTS
13757 #include <trace/events/signal.h>
cc23e853 13758@@ -726,9 +728,18 @@ static int check_kill_permission(int sig
4bf69007
AM
13759 struct pid *sid;
13760 int error;
13761
13762+ vxdprintk(VXD_CBIT(misc, 7),
13763+ "check_kill_permission(%d,%p,%p[#%u,%u])",
13764+ sig, info, t, vx_task_xid(t), t->pid);
d337f35e 13765+
4bf69007
AM
13766 if (!valid_signal(sig))
13767 return -EINVAL;
13768
13769+/* FIXME: needed? if so, why?
13770+ if ((info != SEND_SIG_NOINFO) &&
13771+ (is_si_special(info) || !si_fromuser(info)))
13772+ goto skip; */
d337f35e 13773+
4bf69007
AM
13774 if (!si_fromuser(info))
13775 return 0;
13776
cc23e853 13777@@ -752,6 +763,20 @@ static int check_kill_permission(int sig
4bf69007
AM
13778 }
13779 }
13780
13781+ error = -EPERM;
13782+ if (t->pid == 1 && current->xid)
13783+ return error;
d337f35e 13784+
4bf69007
AM
13785+ error = -ESRCH;
13786+ /* FIXME: we shouldn't return ESRCH ever, to avoid
13787+ loops, maybe ENOENT or EACCES? */
13788+ if (!vx_check(vx_task_xid(t), VS_WATCH_P | VS_IDENT)) {
13789+ vxdprintk(current->xid || VXD_CBIT(misc, 7),
13790+ "signal %d[%p] xid mismatch %p[#%u,%u] xid=#%u",
13791+ sig, info, t, vx_task_xid(t), t->pid, current->xid);
13792+ return error;
2380c486 13793+ }
4bf69007
AM
13794+/* skip: */
13795 return security_task_kill(t, info, sig, 0);
13796 }
13797
cc23e853
AM
13798@@ -1303,8 +1328,14 @@ int kill_pid_info(int sig, struct siginf
13799 for (;;) {
13800 rcu_read_lock();
13801 p = pid_task(pid, PIDTYPE_PID);
13802- if (p)
13803- error = group_send_sig_info(sig, info, p);
13804+ if (p) {
13805+ if (vx_check(vx_task_xid(p), VS_IDENT))
13806+ error = group_send_sig_info(sig, info, p);
13807+ else {
13808+ rcu_read_unlock();
13809+ return -ESRCH;
13810+ }
13811+ }
13812 rcu_read_unlock();
13813 if (likely(!p || error != -ESRCH))
13814 return error;
13815@@ -1349,7 +1380,7 @@ int kill_pid_info_as_cred(int sig, struc
4bf69007
AM
13816
13817 rcu_read_lock();
13818 p = pid_task(pid, PIDTYPE_PID);
13819- if (!p) {
13820+ if (!p || !vx_check(vx_task_xid(p), VS_IDENT)) {
13821 ret = -ESRCH;
13822 goto out_unlock;
13823 }
cc23e853 13824@@ -1401,8 +1432,10 @@ static int kill_something_info(int sig,
4bf69007
AM
13825 struct task_struct * p;
13826
13827 for_each_process(p) {
13828- if (task_pid_vnr(p) > 1 &&
13829- !same_thread_group(p, current)) {
13830+ if (vx_check(vx_task_xid(p), VS_ADMIN|VS_IDENT) &&
13831+ task_pid_vnr(p) > 1 &&
13832+ !same_thread_group(p, current) &&
13833+ !vx_current_initpid(p->pid)) {
13834 int err = group_send_sig_info(sig, info, p);
13835 ++count;
13836 if (err != -EPERM)
cc23e853 13837@@ -2255,6 +2288,11 @@ relock:
4bf69007
AM
13838 !sig_kernel_only(signr))
13839 continue;
13840
13841+ /* virtual init is protected against user signals */
bb20add7 13842+ if ((ksig->info.si_code == SI_USER) &&
4bf69007
AM
13843+ vx_current_initpid(current->pid))
13844+ continue;
d337f35e 13845+
4bf69007
AM
13846 if (sig_kernel_stop(signr)) {
13847 /*
13848 * The default action is to stop all threads in
cef7ea10
AM
13849diff -NurpP --minimal linux-4.9.82/kernel/softirq.c linux-4.9.82-vs2.3.9.7/kernel/softirq.c
13850--- linux-4.9.82/kernel/softirq.c 2016-12-11 19:17:54.000000000 +0000
13851+++ linux-4.9.82-vs2.3.9.7/kernel/softirq.c 2018-01-10 02:50:49.000000000 +0000
bb20add7 13852@@ -26,6 +26,7 @@
4bf69007
AM
13853 #include <linux/smpboot.h>
13854 #include <linux/tick.h>
265de2f7 13855 #include <linux/irq.h>
4bf69007
AM
13856+#include <linux/vs_context.h>
13857
13858 #define CREATE_TRACE_POINTS
13859 #include <trace/events/irq.h>
cef7ea10
AM
13860diff -NurpP --minimal linux-4.9.82/kernel/sys.c linux-4.9.82-vs2.3.9.7/kernel/sys.c
13861--- linux-4.9.82/kernel/sys.c 2016-12-11 19:17:54.000000000 +0000
13862+++ linux-4.9.82-vs2.3.9.7/kernel/sys.c 2018-01-10 02:50:49.000000000 +0000
c2e5f7c8 13863@@ -54,6 +54,7 @@
09be7631 13864 #include <linux/cred.h>
4bf69007
AM
13865
13866 #include <linux/kmsg_dump.h>
b00e13aa 13867+#include <linux/vs_pid.h>
4bf69007 13868 /* Move somewhere else to avoid recompiling? */
b00e13aa
AM
13869 #include <generated/utsrelease.h>
13870
cc23e853 13871@@ -157,7 +158,10 @@ static int set_one_prio(struct task_stru
4bf69007
AM
13872 goto out;
13873 }
13874 if (niceval < task_nice(p) && !can_nice(p, niceval)) {
13875- error = -EACCES;
13876+ if (vx_flags(VXF_IGNEG_NICE, 0))
13877+ error = 0;
13878+ else
13879+ error = -EACCES;
13880 goto out;
13881 }
13882 no_nice = security_task_setnice(p, niceval);
cc23e853 13883@@ -208,6 +212,8 @@ SYSCALL_DEFINE3(setpriority, int, which,
bb20add7
AM
13884 else
13885 pgrp = task_pgrp(current);
13886 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
13887+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
13888+ continue;
13889 error = set_one_prio(p, niceval, error);
13890 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
13891 break;
cc23e853 13892@@ -274,6 +280,8 @@ SYSCALL_DEFINE2(getpriority, int, which,
bb20add7
AM
13893 else
13894 pgrp = task_pgrp(current);
13895 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
13896+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
13897+ continue;
13898 niceval = nice_to_rlimit(task_nice(p));
13899 if (niceval > retval)
13900 retval = niceval;
cc23e853 13901@@ -290,6 +298,8 @@ SYSCALL_DEFINE2(getpriority, int, which,
bb20add7
AM
13902 goto out_unlock; /* No processes for this user */
13903 }
13904 do_each_thread(g, p) {
13905+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
13906+ continue;
cc23e853 13907 if (uid_eq(task_uid(p), uid) && task_pid_vnr(p)) {
bb20add7 13908 niceval = nice_to_rlimit(task_nice(p));
4bf69007 13909 if (niceval > retval)
cc23e853 13910@@ -1217,7 +1227,8 @@ SYSCALL_DEFINE2(sethostname, char __user
4bf69007
AM
13911 int errno;
13912 char tmp[__NEW_UTS_LEN];
13913
13914- if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
13915+ if (!vx_ns_capable(current->nsproxy->uts_ns->user_ns,
13916+ CAP_SYS_ADMIN, VXC_SET_UTSNAME))
13917 return -EPERM;
13918
13919 if (len < 0 || len > __NEW_UTS_LEN)
cc23e853 13920@@ -1268,7 +1279,8 @@ SYSCALL_DEFINE2(setdomainname, char __us
4bf69007
AM
13921 int errno;
13922 char tmp[__NEW_UTS_LEN];
13923
13924- if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
13925+ if (!vx_ns_capable(current->nsproxy->uts_ns->user_ns,
13926+ CAP_SYS_ADMIN, VXC_SET_UTSNAME))
13927 return -EPERM;
13928 if (len < 0 || len > __NEW_UTS_LEN)
13929 return -EINVAL;
cc23e853 13930@@ -1386,7 +1398,7 @@ int do_prlimit(struct task_struct *tsk,
4bf69007
AM
13931 /* Keep the capable check against init_user_ns until
13932 cgroups can contain all limits */
13933 if (new_rlim->rlim_max > rlim->rlim_max &&
13934- !capable(CAP_SYS_RESOURCE))
13935+ !vx_capable(CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
13936 retval = -EPERM;
13937 if (!retval)
13938 retval = security_task_setrlimit(tsk->group_leader,
cc23e853 13939@@ -1439,7 +1451,8 @@ static int check_prlimit_permission(stru
4bf69007
AM
13940 gid_eq(cred->gid, tcred->sgid) &&
13941 gid_eq(cred->gid, tcred->gid))
13942 return 0;
13943- if (ns_capable(tcred->user_ns, CAP_SYS_RESOURCE))
13944+ if (vx_ns_capable(tcred->user_ns,
13945+ CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
13946 return 0;
13947
13948 return -EPERM;
cef7ea10
AM
13949diff -NurpP --minimal linux-4.9.82/kernel/sysctl.c linux-4.9.82-vs2.3.9.7/kernel/sysctl.c
13950--- linux-4.9.82/kernel/sysctl.c 2018-02-22 21:18:57.000000000 +0000
13951+++ linux-4.9.82-vs2.3.9.7/kernel/sysctl.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 13952@@ -87,6 +87,7 @@
4bf69007
AM
13953 #if defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_LOCK_STAT)
13954 #include <linux/lockdep.h>
13955 #endif
13956+extern char vshelper_path[];
13957 #ifdef CONFIG_CHR_DEV_SG
13958 #include <scsi/sg.h>
13959 #endif
cc23e853 13960@@ -282,6 +283,13 @@ static int max_extfrag_threshold = 1000;
bb20add7
AM
13961
13962 static struct ctl_table kern_table[] = {
13963 {
4bf69007
AM
13964+ .procname = "vshelper",
13965+ .data = &vshelper_path,
13966+ .maxlen = 256,
13967+ .mode = 0644,
bb20add7 13968+ .proc_handler = proc_dostring,
4bf69007 13969+ },
bb20add7
AM
13970+ {
13971 .procname = "sched_child_runs_first",
13972 .data = &sysctl_sched_child_runs_first,
13973 .maxlen = sizeof(unsigned int),
cc23e853
AM
13974@@ -1426,7 +1434,6 @@ static struct ctl_table vm_table[] = {
13975 .extra1 = &zero,
13976 .extra2 = &one,
bb20add7
AM
13977 },
13978-
13979 #endif /* CONFIG_COMPACTION */
4bf69007 13980 {
bb20add7 13981 .procname = "min_free_kbytes",
cef7ea10
AM
13982diff -NurpP --minimal linux-4.9.82/kernel/sysctl_binary.c linux-4.9.82-vs2.3.9.7/kernel/sysctl_binary.c
13983--- linux-4.9.82/kernel/sysctl_binary.c 2016-12-11 19:17:54.000000000 +0000
13984+++ linux-4.9.82-vs2.3.9.7/kernel/sysctl_binary.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 13985@@ -74,6 +74,7 @@ static const struct bin_table bin_kern_t
4bf69007
AM
13986
13987 { CTL_INT, KERN_PANIC, "panic" },
13988 { CTL_INT, KERN_REALROOTDEV, "real-root-dev" },
13989+ { CTL_STR, KERN_VSHELPER, "vshelper" },
13990
13991 { CTL_STR, KERN_SPARC_REBOOT, "reboot-cmd" },
13992 { CTL_INT, KERN_CTLALTDEL, "ctrl-alt-del" },
cef7ea10
AM
13993diff -NurpP --minimal linux-4.9.82/kernel/time/posix-timers.c linux-4.9.82-vs2.3.9.7/kernel/time/posix-timers.c
13994--- linux-4.9.82/kernel/time/posix-timers.c 2018-02-22 21:18:57.000000000 +0000
13995+++ linux-4.9.82-vs2.3.9.7/kernel/time/posix-timers.c 2018-02-22 21:31:40.000000000 +0000
bb20add7
AM
13996@@ -48,6 +48,7 @@
13997 #include <linux/workqueue.h>
13998 #include <linux/export.h>
13999 #include <linux/hashtable.h>
14000+#include <linux/vs_context.h>
4bf69007 14001
bb20add7 14002 #include "timekeeping.h"
4bf69007 14003
cc23e853 14004@@ -407,6 +408,7 @@ int posix_timer_event(struct k_itimer *t
bb20add7
AM
14005 {
14006 struct task_struct *task;
14007 int shared, ret = -1;
14008+
14009 /*
14010 * FIXME: if ->sigq is queued we can race with
14011 * dequeue_signal()->do_schedule_next_timer().
cc23e853 14012@@ -423,10 +425,18 @@ int posix_timer_event(struct k_itimer *t
bb20add7
AM
14013 rcu_read_lock();
14014 task = pid_task(timr->it_pid, PIDTYPE_PID);
14015 if (task) {
14016+ struct vx_info_save vxis;
14017+ struct vx_info *vxi;
14018+
14019+ vxi = get_vx_info(task->vx_info);
14020+ enter_vx_info(vxi, &vxis);
14021 shared = !(timr->it_sigev_notify & SIGEV_THREAD_ID);
14022 ret = send_sigqueue(timr->sigq, task, shared);
14023+ leave_vx_info(&vxis);
14024+ put_vx_info(vxi);
14025 }
14026 rcu_read_unlock();
14027+
14028 /* If we failed to send the signal the timer stops. */
14029 return ret > 0;
4bf69007 14030 }
cef7ea10
AM
14031diff -NurpP --minimal linux-4.9.82/kernel/time/time.c linux-4.9.82-vs2.3.9.7/kernel/time/time.c
14032--- linux-4.9.82/kernel/time/time.c 2016-12-11 19:17:54.000000000 +0000
14033+++ linux-4.9.82-vs2.3.9.7/kernel/time/time.c 2018-01-10 09:31:11.000000000 +0000
4bf69007
AM
14034@@ -37,6 +37,7 @@
14035 #include <linux/fs.h>
14036 #include <linux/math64.h>
14037 #include <linux/ptrace.h>
14038+#include <linux/vs_time.h>
14039
14040 #include <asm/uaccess.h>
14041 #include <asm/unistd.h>
bb20add7 14042@@ -93,7 +94,7 @@ SYSCALL_DEFINE1(stime, time_t __user *,
4bf69007
AM
14043 if (err)
14044 return err;
14045
14046- do_settimeofday(&tv);
14047+ vx_settimeofday(&tv);
14048 return 0;
14049 }
14050
cc23e853 14051@@ -186,7 +187,7 @@ int do_sys_settimeofday64(const struct t
4bf69007
AM
14052 }
14053 }
14054 if (tv)
cc23e853
AM
14055- return do_settimeofday64(tv);
14056+ return vx_settimeofday64(tv);
4bf69007
AM
14057 return 0;
14058 }
14059
cef7ea10
AM
14060diff -NurpP --minimal linux-4.9.82/kernel/time/timekeeping.c linux-4.9.82-vs2.3.9.7/kernel/time/timekeeping.c
14061--- linux-4.9.82/kernel/time/timekeeping.c 2018-02-22 21:18:57.000000000 +0000
14062+++ linux-4.9.82-vs2.3.9.7/kernel/time/timekeeping.c 2018-01-10 02:50:49.000000000 +0000
bb20add7
AM
14063@@ -23,6 +23,7 @@
14064 #include <linux/stop_machine.h>
14065 #include <linux/pvclock_gtod.h>
14066 #include <linux/compiler.h>
14067+#include <linux/vs_time.h>
14068
14069 #include "tick-internal.h"
14070 #include "ntp_internal.h"
cef7ea10
AM
14071diff -NurpP --minimal linux-4.9.82/kernel/time/timer.c linux-4.9.82-vs2.3.9.7/kernel/time/timer.c
14072--- linux-4.9.82/kernel/time/timer.c 2018-02-22 21:18:57.000000000 +0000
14073+++ linux-4.9.82-vs2.3.9.7/kernel/time/timer.c 2018-01-25 00:21:32.000000000 +0000
09be7631 14074@@ -42,6 +42,10 @@
b00e13aa 14075 #include <linux/sched/sysctl.h>
4bf69007 14076 #include <linux/slab.h>
09be7631 14077 #include <linux/compat.h>
4bf69007
AM
14078+#include <linux/vs_base.h>
14079+#include <linux/vs_cvirt.h>
14080+#include <linux/vs_pid.h>
14081+#include <linux/vserver/sched.h>
14082
14083 #include <asm/uaccess.h>
14084 #include <asm/unistd.h>
cef7ea10
AM
14085diff -NurpP --minimal linux-4.9.82/kernel/user_namespace.c linux-4.9.82-vs2.3.9.7/kernel/user_namespace.c
14086--- linux-4.9.82/kernel/user_namespace.c 2016-12-11 19:17:54.000000000 +0000
14087+++ linux-4.9.82-vs2.3.9.7/kernel/user_namespace.c 2018-01-10 02:50:49.000000000 +0000
b00e13aa 14088@@ -22,6 +22,7 @@
4bf69007
AM
14089 #include <linux/ctype.h>
14090 #include <linux/projid.h>
b00e13aa 14091 #include <linux/fs_struct.h>
4bf69007
AM
14092+#include <linux/vserver/global.h>
14093
14094 static struct kmem_cache *user_ns_cachep __read_mostly;
bb20add7 14095 static DEFINE_MUTEX(userns_state_mutex);
cc23e853 14096@@ -115,6 +116,7 @@ int create_user_ns(struct cred *new)
4bf69007 14097
b00e13aa
AM
14098 atomic_set(&ns->count, 1);
14099 /* Leave the new->user_ns reference with the new user namespace. */
4bf69007
AM
14100+ atomic_inc(&vs_global_user_ns);
14101 ns->parent = parent_ns;
09be7631 14102 ns->level = parent_ns->level + 1;
4bf69007 14103 ns->owner = owner;
cc23e853
AM
14104@@ -185,6 +187,7 @@ static void free_user_ns(struct work_str
14105 key_put(ns->persistent_keyring_register);
14106 #endif
14107 ns_free_inum(&ns->ns);
14108+ atomic_dec(&vs_global_user_ns);
14109 kmem_cache_free(user_ns_cachep, ns);
14110 dec_user_namespaces(ucounts);
14111 ns = parent;
14112@@ -404,6 +407,18 @@ gid_t from_kgid_munged(struct user_names
bb20add7
AM
14113 }
14114 EXPORT_SYMBOL(from_kgid_munged);
14115
14116+ktag_t make_ktag(struct user_namespace *from, vtag_t tag)
14117+{
14118+ return KTAGT_INIT(tag);
14119+}
14120+EXPORT_SYMBOL(make_ktag);
14121+
14122+vtag_t from_ktag(struct user_namespace *to, ktag_t tag)
14123+{
14124+ return __ktag_val(tag);
14125+}
14126+EXPORT_SYMBOL(from_ktag);
14127+
14128 /**
14129 * make_kprojid - Map a user-namespace projid pair into a kprojid.
14130 * @ns: User namespace that the projid is in
cef7ea10
AM
14131diff -NurpP --minimal linux-4.9.82/kernel/utsname.c linux-4.9.82-vs2.3.9.7/kernel/utsname.c
14132--- linux-4.9.82/kernel/utsname.c 2016-12-11 19:17:54.000000000 +0000
14133+++ linux-4.9.82-vs2.3.9.7/kernel/utsname.c 2018-01-10 09:05:33.000000000 +0000
cc23e853 14134@@ -16,6 +16,7 @@
4bf69007
AM
14135 #include <linux/slab.h>
14136 #include <linux/user_namespace.h>
09be7631 14137 #include <linux/proc_ns.h>
4bf69007
AM
14138+#include <linux/vserver/global.h>
14139
cc23e853 14140 static struct ucounts *inc_uts_namespaces(struct user_namespace *ns)
4bf69007 14141 {
cc23e853 14142@@ -32,8 +33,10 @@ static struct uts_namespace *create_uts_
4bf69007
AM
14143 struct uts_namespace *uts_ns;
14144
14145 uts_ns = kmalloc(sizeof(struct uts_namespace), GFP_KERNEL);
14146- if (uts_ns)
14147+ if (uts_ns) {
c2e5f7c8 14148 kref_init(&uts_ns->kref);
4bf69007
AM
14149+ atomic_inc(&vs_global_uts_ns);
14150+ }
14151 return uts_ns;
14152 }
14153
cc23e853
AM
14154@@ -111,6 +114,7 @@ void free_uts_ns(struct kref *kref)
14155 dec_uts_namespaces(ns->ucounts);
4bf69007 14156 put_user_ns(ns->user_ns);
cc23e853 14157 ns_free_inum(&ns->ns);
4bf69007
AM
14158+ atomic_dec(&vs_global_uts_ns);
14159 kfree(ns);
14160 }
14161
cef7ea10
AM
14162diff -NurpP --minimal linux-4.9.82/kernel/vserver/Kconfig linux-4.9.82-vs2.3.9.7/kernel/vserver/Kconfig
14163--- linux-4.9.82/kernel/vserver/Kconfig 1970-01-01 00:00:00.000000000 +0000
14164+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/Kconfig 2018-01-10 02:50:49.000000000 +0000
c2e5f7c8 14165@@ -0,0 +1,230 @@
4bf69007
AM
14166+#
14167+# Linux VServer configuration
14168+#
d337f35e 14169+
4bf69007 14170+menu "Linux VServer"
d337f35e 14171+
4bf69007
AM
14172+config VSERVER_AUTO_LBACK
14173+ bool "Automatically Assign Loopback IP"
14174+ default y
14175+ help
14176+ Automatically assign a guest specific loopback
14177+ IP and add it to the kernel network stack on
14178+ startup.
d337f35e 14179+
4bf69007
AM
14180+config VSERVER_AUTO_SINGLE
14181+ bool "Automatic Single IP Special Casing"
c2e5f7c8 14182+ default n
4bf69007
AM
14183+ help
14184+ This allows network contexts with a single IP to
14185+ automatically remap 0.0.0.0 bindings to that IP,
14186+ avoiding further network checks and improving
14187+ performance.
d337f35e 14188+
4bf69007
AM
14189+ (note: such guests do not allow to change the ip
14190+ on the fly and do not show loopback addresses)
2380c486 14191+
4bf69007
AM
14192+config VSERVER_COWBL
14193+ bool "Enable COW Immutable Link Breaking"
14194+ default y
14195+ help
14196+ This enables the COW (Copy-On-Write) link break code.
14197+ It allows you to treat unified files like normal files
14198+ when writing to them (which will implicitely break the
14199+ link and create a copy of the unified file)
d337f35e 14200+
4bf69007 14201+config VSERVER_VTIME
c2e5f7c8 14202+ bool "Enable Virtualized Guest Time (EXPERIMENTAL)"
4bf69007
AM
14203+ default n
14204+ help
14205+ This enables per guest time offsets to allow for
14206+ adjusting the system clock individually per guest.
14207+ this adds some overhead to the time functions and
14208+ therefore should not be enabled without good reason.
d337f35e 14209+
4bf69007 14210+config VSERVER_DEVICE
c2e5f7c8 14211+ bool "Enable Guest Device Mapping (EXPERIMENTAL)"
4bf69007
AM
14212+ default n
14213+ help
14214+ This enables generic device remapping.
d337f35e 14215+
4bf69007
AM
14216+config VSERVER_PROC_SECURE
14217+ bool "Enable Proc Security"
14218+ depends on PROC_FS
14219+ default y
14220+ help
14221+ This configures ProcFS security to initially hide
14222+ non-process entries for all contexts except the main and
14223+ spectator context (i.e. for all guests), which is a secure
14224+ default.
d337f35e 14225+
4bf69007 14226+ (note: on 1.2x the entries were visible by default)
d337f35e 14227+
4bf69007
AM
14228+choice
14229+ prompt "Persistent Inode Tagging"
14230+ default TAGGING_ID24
14231+ help
14232+ This adds persistent context information to filesystems
14233+ mounted with the tagxid option. Tagging is a requirement
14234+ for per-context disk limits and per-context quota.
d337f35e 14235+
d337f35e 14236+
4bf69007
AM
14237+config TAGGING_NONE
14238+ bool "Disabled"
14239+ help
14240+ do not store per-context information in inodes.
d337f35e 14241+
4bf69007
AM
14242+config TAGGING_UID16
14243+ bool "UID16/GID32"
14244+ help
14245+ reduces UID to 16 bit, but leaves GID at 32 bit.
d337f35e 14246+
4bf69007
AM
14247+config TAGGING_GID16
14248+ bool "UID32/GID16"
14249+ help
14250+ reduces GID to 16 bit, but leaves UID at 32 bit.
d337f35e 14251+
4bf69007
AM
14252+config TAGGING_ID24
14253+ bool "UID24/GID24"
14254+ help
14255+ uses the upper 8bit from UID and GID for XID tagging
14256+ which leaves 24bit for UID/GID each, which should be
14257+ more than sufficient for normal use.
d337f35e 14258+
4bf69007
AM
14259+config TAGGING_INTERN
14260+ bool "UID32/GID32"
14261+ help
14262+ this uses otherwise reserved inode fields in the on
14263+ disk representation, which limits the use to a few
14264+ filesystems (currently ext2 and ext3)
d337f35e 14265+
4bf69007 14266+endchoice
d337f35e 14267+
4bf69007
AM
14268+config TAG_NFSD
14269+ bool "Tag NFSD User Auth and Files"
14270+ default n
14271+ help
14272+ Enable this if you do want the in-kernel NFS
14273+ Server to use the tagging specified above.
14274+ (will require patched clients too)
2380c486 14275+
4bf69007
AM
14276+config VSERVER_PRIVACY
14277+ bool "Honor Privacy Aspects of Guests"
14278+ default n
14279+ help
14280+ When enabled, most context checks will disallow
14281+ access to structures assigned to a specific context,
14282+ like ptys or loop devices.
2380c486 14283+
4bf69007
AM
14284+config VSERVER_CONTEXTS
14285+ int "Maximum number of Contexts (1-65533)" if EMBEDDED
14286+ range 1 65533
14287+ default "768" if 64BIT
14288+ default "256"
14289+ help
14290+ This setting will optimize certain data structures
14291+ and memory allocations according to the expected
14292+ maximum.
2380c486 14293+
4bf69007 14294+ note: this is not a strict upper limit.
2380c486 14295+
4bf69007
AM
14296+config VSERVER_WARN
14297+ bool "VServer Warnings"
14298+ default y
14299+ help
14300+ This enables various runtime warnings, which will
14301+ notify about potential manipulation attempts or
14302+ resource shortage. It is generally considered to
14303+ be a good idea to have that enabled.
2380c486 14304+
4bf69007
AM
14305+config VSERVER_WARN_DEVPTS
14306+ bool "VServer DevPTS Warnings"
14307+ depends on VSERVER_WARN
14308+ default y
14309+ help
14310+ This enables DevPTS related warnings, issued when a
14311+ process inside a context tries to lookup or access
14312+ a dynamic pts from the host or a different context.
d337f35e 14313+
4bf69007
AM
14314+config VSERVER_DEBUG
14315+ bool "VServer Debugging Code"
14316+ default n
14317+ help
14318+ Set this to yes if you want to be able to activate
14319+ debugging output at runtime. It adds a very small
14320+ overhead to all vserver related functions and
14321+ increases the kernel size by about 20k.
d337f35e 14322+
4bf69007
AM
14323+config VSERVER_HISTORY
14324+ bool "VServer History Tracing"
14325+ depends on VSERVER_DEBUG
14326+ default n
14327+ help
14328+ Set this to yes if you want to record the history of
14329+ linux-vserver activities, so they can be replayed in
14330+ the event of a kernel panic or oops.
d337f35e 14331+
4bf69007
AM
14332+config VSERVER_HISTORY_SIZE
14333+ int "Per-CPU History Size (32-65536)"
14334+ depends on VSERVER_HISTORY
14335+ range 32 65536
14336+ default 64
14337+ help
14338+ This allows you to specify the number of entries in
14339+ the per-CPU history buffer.
d337f35e 14340+
4bf69007
AM
14341+config VSERVER_EXTRA_MNT_CHECK
14342+ bool "Extra Checks for Reachability"
14343+ default n
14344+ help
14345+ Set this to yes if you want to do extra checks for
14346+ vfsmount reachability in the proc filesystem code.
14347+ This shouldn't be required on any setup utilizing
14348+ mnt namespaces.
d337f35e 14349+
4bf69007
AM
14350+choice
14351+ prompt "Quotes used in debug and warn messages"
14352+ default QUOTES_ISO8859
d337f35e 14353+
4bf69007
AM
14354+config QUOTES_ISO8859
14355+ bool "Extended ASCII (ISO 8859) angle quotes"
14356+ help
14357+ This uses the extended ASCII characters \xbb
14358+ and \xab for quoting file and process names.
d337f35e 14359+
4bf69007
AM
14360+config QUOTES_UTF8
14361+ bool "UTF-8 angle quotes"
14362+ help
14363+ This uses the the UTF-8 sequences for angle
14364+ quotes to quote file and process names.
d337f35e 14365+
4bf69007
AM
14366+config QUOTES_ASCII
14367+ bool "ASCII single quotes"
14368+ help
14369+ This uses the ASCII single quote character
14370+ (\x27) to quote file and process names.
d337f35e 14371+
4bf69007 14372+endchoice
d337f35e 14373+
4bf69007 14374+endmenu
d337f35e 14375+
d337f35e 14376+
4bf69007
AM
14377+config VSERVER
14378+ bool
14379+ default y
14380+ select NAMESPACES
14381+ select UTS_NS
14382+ select IPC_NS
14383+# select USER_NS
14384+ select SYSVIPC
d337f35e 14385+
4bf69007
AM
14386+config VSERVER_SECURITY
14387+ bool
14388+ depends on SECURITY
14389+ default y
14390+ select SECURITY_CAPABILITIES
d337f35e 14391+
4bf69007
AM
14392+config VSERVER_DISABLED
14393+ bool
14394+ default n
d337f35e 14395+
cef7ea10
AM
14396diff -NurpP --minimal linux-4.9.82/kernel/vserver/Makefile linux-4.9.82-vs2.3.9.7/kernel/vserver/Makefile
14397--- linux-4.9.82/kernel/vserver/Makefile 1970-01-01 00:00:00.000000000 +0000
14398+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/Makefile 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
14399@@ -0,0 +1,18 @@
14400+#
14401+# Makefile for the Linux vserver routines.
14402+#
d337f35e 14403+
d337f35e 14404+
4bf69007 14405+obj-y += vserver.o
2380c486 14406+
4bf69007
AM
14407+vserver-y := switch.o context.o space.o sched.o network.o inode.o \
14408+ limit.o cvirt.o cacct.o signal.o helper.o init.o \
14409+ dlimit.o tag.o
d337f35e 14410+
4bf69007
AM
14411+vserver-$(CONFIG_INET) += inet.o
14412+vserver-$(CONFIG_PROC_FS) += proc.o
14413+vserver-$(CONFIG_VSERVER_DEBUG) += sysctl.o debug.o
14414+vserver-$(CONFIG_VSERVER_HISTORY) += history.o
14415+vserver-$(CONFIG_VSERVER_MONITOR) += monitor.o
14416+vserver-$(CONFIG_VSERVER_DEVICE) += device.o
d337f35e 14417+
cef7ea10
AM
14418diff -NurpP --minimal linux-4.9.82/kernel/vserver/cacct.c linux-4.9.82-vs2.3.9.7/kernel/vserver/cacct.c
14419--- linux-4.9.82/kernel/vserver/cacct.c 1970-01-01 00:00:00.000000000 +0000
14420+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/cacct.c 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
14421@@ -0,0 +1,42 @@
14422+/*
14423+ * linux/kernel/vserver/cacct.c
14424+ *
14425+ * Virtual Server: Context Accounting
14426+ *
cc23e853 14427+ * Copyright (C) 2006-2007 Herbert P?tzl
4bf69007
AM
14428+ *
14429+ * V0.01 added accounting stats
14430+ *
14431+ */
d337f35e 14432+
4bf69007
AM
14433+#include <linux/types.h>
14434+#include <linux/vs_context.h>
14435+#include <linux/vserver/cacct_cmd.h>
14436+#include <linux/vserver/cacct_int.h>
d337f35e 14437+
4bf69007
AM
14438+#include <asm/errno.h>
14439+#include <asm/uaccess.h>
14440+
14441+
14442+int vc_sock_stat(struct vx_info *vxi, void __user *data)
d337f35e 14443+{
4bf69007
AM
14444+ struct vcmd_sock_stat_v0 vc_data;
14445+ int j, field;
d337f35e 14446+
2380c486
JR
14447+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
14448+ return -EFAULT;
14449+
4bf69007
AM
14450+ field = vc_data.field;
14451+ if ((field < 0) || (field >= VXA_SOCK_SIZE))
14452+ return -EINVAL;
7e46296a 14453+
4bf69007
AM
14454+ for (j = 0; j < 3; j++) {
14455+ vc_data.count[j] = vx_sock_count(&vxi->cacct, field, j);
14456+ vc_data.total[j] = vx_sock_total(&vxi->cacct, field, j);
14457+ }
7e46296a
AM
14458+
14459+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
14460+ return -EFAULT;
14461+ return 0;
14462+}
14463+
cef7ea10
AM
14464diff -NurpP --minimal linux-4.9.82/kernel/vserver/cacct_init.h linux-4.9.82-vs2.3.9.7/kernel/vserver/cacct_init.h
14465--- linux-4.9.82/kernel/vserver/cacct_init.h 1970-01-01 00:00:00.000000000 +0000
14466+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/cacct_init.h 2018-01-10 02:50:49.000000000 +0000
4bf69007 14467@@ -0,0 +1,25 @@
7e46296a
AM
14468+
14469+
4bf69007 14470+static inline void vx_info_init_cacct(struct _vx_cacct *cacct)
265d6dcc 14471+{
4bf69007 14472+ int i, j;
265d6dcc 14473+
265d6dcc 14474+
4bf69007
AM
14475+ for (i = 0; i < VXA_SOCK_SIZE; i++) {
14476+ for (j = 0; j < 3; j++) {
14477+ atomic_long_set(&cacct->sock[i][j].count, 0);
14478+ atomic_long_set(&cacct->sock[i][j].total, 0);
14479+ }
14480+ }
14481+ for (i = 0; i < 8; i++)
14482+ atomic_set(&cacct->slab[i], 0);
14483+ for (i = 0; i < 5; i++)
14484+ for (j = 0; j < 4; j++)
14485+ atomic_set(&cacct->page[i][j], 0);
265d6dcc
JR
14486+}
14487+
4bf69007 14488+static inline void vx_info_exit_cacct(struct _vx_cacct *cacct)
265d6dcc 14489+{
4bf69007 14490+ return;
265d6dcc
JR
14491+}
14492+
cef7ea10
AM
14493diff -NurpP --minimal linux-4.9.82/kernel/vserver/cacct_proc.h linux-4.9.82-vs2.3.9.7/kernel/vserver/cacct_proc.h
14494--- linux-4.9.82/kernel/vserver/cacct_proc.h 1970-01-01 00:00:00.000000000 +0000
14495+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/cacct_proc.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
14496@@ -0,0 +1,53 @@
14497+#ifndef _VX_CACCT_PROC_H
14498+#define _VX_CACCT_PROC_H
265d6dcc 14499+
4bf69007 14500+#include <linux/vserver/cacct_int.h>
d337f35e 14501+
d337f35e 14502+
4bf69007
AM
14503+#define VX_SOCKA_TOP \
14504+ "Type\t recv #/bytes\t\t send #/bytes\t\t fail #/bytes\n"
d337f35e 14505+
4bf69007 14506+static inline int vx_info_proc_cacct(struct _vx_cacct *cacct, char *buffer)
d337f35e 14507+{
4bf69007
AM
14508+ int i, j, length = 0;
14509+ static char *type[VXA_SOCK_SIZE] = {
14510+ "UNSPEC", "UNIX", "INET", "INET6", "PACKET", "OTHER"
14511+ };
d337f35e 14512+
4bf69007
AM
14513+ length += sprintf(buffer + length, VX_SOCKA_TOP);
14514+ for (i = 0; i < VXA_SOCK_SIZE; i++) {
14515+ length += sprintf(buffer + length, "%s:", type[i]);
14516+ for (j = 0; j < 3; j++) {
14517+ length += sprintf(buffer + length,
14518+ "\t%10lu/%-10lu",
14519+ vx_sock_count(cacct, i, j),
14520+ vx_sock_total(cacct, i, j));
14521+ }
14522+ buffer[length++] = '\n';
14523+ }
d337f35e 14524+
4bf69007
AM
14525+ length += sprintf(buffer + length, "\n");
14526+ length += sprintf(buffer + length,
14527+ "slab:\t %8u %8u %8u %8u\n",
14528+ atomic_read(&cacct->slab[1]),
14529+ atomic_read(&cacct->slab[4]),
14530+ atomic_read(&cacct->slab[0]),
14531+ atomic_read(&cacct->slab[2]));
d337f35e 14532+
4bf69007
AM
14533+ length += sprintf(buffer + length, "\n");
14534+ for (i = 0; i < 5; i++) {
14535+ length += sprintf(buffer + length,
14536+ "page[%d]: %8u %8u %8u %8u\t %8u %8u %8u %8u\n", i,
14537+ atomic_read(&cacct->page[i][0]),
14538+ atomic_read(&cacct->page[i][1]),
14539+ atomic_read(&cacct->page[i][2]),
14540+ atomic_read(&cacct->page[i][3]),
14541+ atomic_read(&cacct->page[i][4]),
14542+ atomic_read(&cacct->page[i][5]),
14543+ atomic_read(&cacct->page[i][6]),
14544+ atomic_read(&cacct->page[i][7]));
14545+ }
14546+ return length;
14547+}
d337f35e 14548+
4bf69007 14549+#endif /* _VX_CACCT_PROC_H */
cef7ea10
AM
14550diff -NurpP --minimal linux-4.9.82/kernel/vserver/context.c linux-4.9.82-vs2.3.9.7/kernel/vserver/context.c
14551--- linux-4.9.82/kernel/vserver/context.c 1970-01-01 00:00:00.000000000 +0000
14552+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/context.c 2018-01-10 02:50:49.000000000 +0000
4bf69007 14553@@ -0,0 +1,1119 @@
2380c486 14554+/*
4bf69007 14555+ * linux/kernel/vserver/context.c
2380c486 14556+ *
4bf69007 14557+ * Virtual Server: Context Support
2380c486 14558+ *
cc23e853 14559+ * Copyright (C) 2003-2011 Herbert P?tzl
2380c486 14560+ *
4bf69007
AM
14561+ * V0.01 context helper
14562+ * V0.02 vx_ctx_kill syscall command
14563+ * V0.03 replaced context_info calls
14564+ * V0.04 redesign of struct (de)alloc
14565+ * V0.05 rlimit basic implementation
14566+ * V0.06 task_xid and info commands
14567+ * V0.07 context flags and caps
14568+ * V0.08 switch to RCU based hash
14569+ * V0.09 revert to non RCU for now
14570+ * V0.10 and back to working RCU hash
14571+ * V0.11 and back to locking again
14572+ * V0.12 referenced context store
14573+ * V0.13 separate per cpu data
14574+ * V0.14 changed vcmds to vxi arg
14575+ * V0.15 added context stat
14576+ * V0.16 have __create claim() the vxi
14577+ * V0.17 removed older and legacy stuff
14578+ * V0.18 added user credentials
14579+ * V0.19 added warn mask
2380c486
JR
14580+ *
14581+ */
d337f35e 14582+
4bf69007 14583+#include <linux/slab.h>
2380c486 14584+#include <linux/types.h>
4bf69007
AM
14585+#include <linux/security.h>
14586+#include <linux/pid_namespace.h>
14587+#include <linux/capability.h>
1e8b8f9b 14588+
4bf69007
AM
14589+#include <linux/vserver/context.h>
14590+#include <linux/vserver/network.h>
14591+#include <linux/vserver/debug.h>
14592+#include <linux/vserver/limit.h>
14593+#include <linux/vserver/limit_int.h>
14594+#include <linux/vserver/space.h>
14595+#include <linux/init_task.h>
14596+#include <linux/fs_struct.h>
14597+#include <linux/cred.h>
1e8b8f9b 14598+
4bf69007
AM
14599+#include <linux/vs_context.h>
14600+#include <linux/vs_limit.h>
14601+#include <linux/vs_pid.h>
14602+#include <linux/vserver/context_cmd.h>
d337f35e 14603+
4bf69007
AM
14604+#include "cvirt_init.h"
14605+#include "cacct_init.h"
14606+#include "limit_init.h"
14607+#include "sched_init.h"
d337f35e 14608+
d337f35e 14609+
4bf69007
AM
14610+atomic_t vx_global_ctotal = ATOMIC_INIT(0);
14611+atomic_t vx_global_cactive = ATOMIC_INIT(0);
d337f35e 14612+
d337f35e 14613+
4bf69007 14614+/* now inactive context structures */
d337f35e 14615+
4bf69007 14616+static struct hlist_head vx_info_inactive = HLIST_HEAD_INIT;
2380c486 14617+
4bf69007 14618+static DEFINE_SPINLOCK(vx_info_inactive_lock);
d337f35e 14619+
2380c486 14620+
4bf69007 14621+/* __alloc_vx_info()
d337f35e 14622+
4bf69007
AM
14623+ * allocate an initialized vx_info struct
14624+ * doesn't make it visible (hash) */
d337f35e 14625+
61333608 14626+static struct vx_info *__alloc_vx_info(vxid_t xid)
4bf69007
AM
14627+{
14628+ struct vx_info *new = NULL;
14629+ int cpu, index;
d337f35e 14630+
4bf69007 14631+ vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d)*", xid);
d337f35e 14632+
4bf69007
AM
14633+ /* would this benefit from a slab cache? */
14634+ new = kmalloc(sizeof(struct vx_info), GFP_KERNEL);
14635+ if (!new)
14636+ return 0;
2380c486 14637+
4bf69007
AM
14638+ memset(new, 0, sizeof(struct vx_info));
14639+#ifdef CONFIG_SMP
14640+ new->ptr_pc = alloc_percpu(struct _vx_info_pc);
14641+ if (!new->ptr_pc)
14642+ goto error;
14643+#endif
14644+ new->vx_id = xid;
14645+ INIT_HLIST_NODE(&new->vx_hlist);
14646+ atomic_set(&new->vx_usecnt, 0);
14647+ atomic_set(&new->vx_tasks, 0);
14648+ new->vx_parent = NULL;
14649+ new->vx_state = 0;
14650+ init_waitqueue_head(&new->vx_wait);
2380c486 14651+
4bf69007
AM
14652+ /* prepare reaper */
14653+ get_task_struct(init_pid_ns.child_reaper);
14654+ new->vx_reaper = init_pid_ns.child_reaper;
14655+ new->vx_badness_bias = 0;
d337f35e 14656+
4bf69007
AM
14657+ /* rest of init goes here */
14658+ vx_info_init_limit(&new->limit);
14659+ vx_info_init_sched(&new->sched);
14660+ vx_info_init_cvirt(&new->cvirt);
14661+ vx_info_init_cacct(&new->cacct);
d337f35e 14662+
4bf69007
AM
14663+ /* per cpu data structures */
14664+ for_each_possible_cpu(cpu) {
14665+ vx_info_init_sched_pc(
14666+ &vx_per_cpu(new, sched_pc, cpu), cpu);
14667+ vx_info_init_cvirt_pc(
14668+ &vx_per_cpu(new, cvirt_pc, cpu), cpu);
14669+ }
d337f35e 14670+
4bf69007
AM
14671+ new->vx_flags = VXF_INIT_SET;
14672+ new->vx_bcaps = CAP_FULL_SET; // maybe ~CAP_SETPCAP
14673+ new->vx_ccaps = 0;
14674+ new->vx_umask = 0;
14675+ new->vx_wmask = 0;
d337f35e 14676+
4bf69007
AM
14677+ new->reboot_cmd = 0;
14678+ new->exit_code = 0;
d337f35e 14679+
4bf69007
AM
14680+ // preconfig spaces
14681+ for (index = 0; index < VX_SPACES; index++) {
14682+ struct _vx_space *space = &new->space[index];
d337f35e 14683+
4bf69007
AM
14684+ // filesystem
14685+ spin_lock(&init_fs.lock);
14686+ init_fs.users++;
14687+ spin_unlock(&init_fs.lock);
14688+ space->vx_fs = &init_fs;
2380c486 14689+
4bf69007
AM
14690+ /* FIXME: do we want defaults? */
14691+ // space->vx_real_cred = 0;
14692+ // space->vx_cred = 0;
2380c486 14693+ }
4bf69007
AM
14694+
14695+
14696+ vxdprintk(VXD_CBIT(xid, 0),
14697+ "alloc_vx_info(%d) = %p", xid, new);
14698+ vxh_alloc_vx_info(new);
14699+ atomic_inc(&vx_global_ctotal);
14700+ return new;
14701+#ifdef CONFIG_SMP
14702+error:
14703+ kfree(new);
14704+ return 0;
14705+#endif
d337f35e
JR
14706+}
14707+
4bf69007 14708+/* __dealloc_vx_info()
d337f35e 14709+
4bf69007 14710+ * final disposal of vx_info */
d337f35e 14711+
4bf69007 14712+static void __dealloc_vx_info(struct vx_info *vxi)
d337f35e 14713+{
4bf69007
AM
14714+#ifdef CONFIG_VSERVER_WARN
14715+ struct vx_info_save vxis;
14716+ int cpu;
14717+#endif
14718+ vxdprintk(VXD_CBIT(xid, 0),
14719+ "dealloc_vx_info(%p)", vxi);
14720+ vxh_dealloc_vx_info(vxi);
d337f35e 14721+
4bf69007
AM
14722+#ifdef CONFIG_VSERVER_WARN
14723+ enter_vx_info(vxi, &vxis);
14724+ vx_info_exit_limit(&vxi->limit);
14725+ vx_info_exit_sched(&vxi->sched);
14726+ vx_info_exit_cvirt(&vxi->cvirt);
14727+ vx_info_exit_cacct(&vxi->cacct);
d337f35e 14728+
4bf69007
AM
14729+ for_each_possible_cpu(cpu) {
14730+ vx_info_exit_sched_pc(
14731+ &vx_per_cpu(vxi, sched_pc, cpu), cpu);
14732+ vx_info_exit_cvirt_pc(
14733+ &vx_per_cpu(vxi, cvirt_pc, cpu), cpu);
14734+ }
14735+ leave_vx_info(&vxis);
14736+#endif
d337f35e 14737+
4bf69007
AM
14738+ vxi->vx_id = -1;
14739+ vxi->vx_state |= VXS_RELEASED;
d337f35e 14740+
4bf69007
AM
14741+#ifdef CONFIG_SMP
14742+ free_percpu(vxi->ptr_pc);
14743+#endif
14744+ kfree(vxi);
14745+ atomic_dec(&vx_global_ctotal);
d337f35e
JR
14746+}
14747+
4bf69007 14748+static void __shutdown_vx_info(struct vx_info *vxi)
d337f35e 14749+{
4bf69007
AM
14750+ struct nsproxy *nsproxy;
14751+ struct fs_struct *fs;
14752+ struct cred *cred;
14753+ int index, kill;
d337f35e 14754+
4bf69007 14755+ might_sleep();
d337f35e 14756+
4bf69007
AM
14757+ vxi->vx_state |= VXS_SHUTDOWN;
14758+ vs_state_change(vxi, VSC_SHUTDOWN);
d337f35e 14759+
4bf69007
AM
14760+ for (index = 0; index < VX_SPACES; index++) {
14761+ struct _vx_space *space = &vxi->space[index];
d337f35e 14762+
4bf69007
AM
14763+ nsproxy = xchg(&space->vx_nsproxy, NULL);
14764+ if (nsproxy)
14765+ put_nsproxy(nsproxy);
2380c486 14766+
4bf69007
AM
14767+ fs = xchg(&space->vx_fs, NULL);
14768+ spin_lock(&fs->lock);
14769+ kill = !--fs->users;
14770+ spin_unlock(&fs->lock);
14771+ if (kill)
14772+ free_fs_struct(fs);
d337f35e 14773+
4bf69007
AM
14774+ cred = (struct cred *)xchg(&space->vx_cred, NULL);
14775+ if (cred)
14776+ abort_creds(cred);
14777+ }
d337f35e
JR
14778+}
14779+
4bf69007 14780+/* exported stuff */
d337f35e 14781+
4bf69007 14782+void free_vx_info(struct vx_info *vxi)
d337f35e 14783+{
4bf69007
AM
14784+ unsigned long flags;
14785+ unsigned index;
d337f35e 14786+
4bf69007
AM
14787+ /* check for reference counts first */
14788+ BUG_ON(atomic_read(&vxi->vx_usecnt));
14789+ BUG_ON(atomic_read(&vxi->vx_tasks));
2380c486 14790+
4bf69007
AM
14791+ /* context must not be hashed */
14792+ BUG_ON(vx_info_state(vxi, VXS_HASHED));
d337f35e 14793+
4bf69007
AM
14794+ /* context shutdown is mandatory */
14795+ BUG_ON(!vx_info_state(vxi, VXS_SHUTDOWN));
d337f35e 14796+
4bf69007
AM
14797+ /* spaces check */
14798+ for (index = 0; index < VX_SPACES; index++) {
14799+ struct _vx_space *space = &vxi->space[index];
d337f35e 14800+
4bf69007
AM
14801+ BUG_ON(space->vx_nsproxy);
14802+ BUG_ON(space->vx_fs);
14803+ // BUG_ON(space->vx_real_cred);
14804+ // BUG_ON(space->vx_cred);
14805+ }
d337f35e 14806+
4bf69007
AM
14807+ spin_lock_irqsave(&vx_info_inactive_lock, flags);
14808+ hlist_del(&vxi->vx_hlist);
14809+ spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
d337f35e 14810+
4bf69007
AM
14811+ __dealloc_vx_info(vxi);
14812+}
eab5a9a6 14813+
d337f35e 14814+
4bf69007 14815+/* hash table for vx_info hash */
93de0823 14816+
4bf69007 14817+#define VX_HASH_SIZE 13
d337f35e 14818+
4bf69007
AM
14819+static struct hlist_head vx_info_hash[VX_HASH_SIZE] =
14820+ { [0 ... VX_HASH_SIZE-1] = HLIST_HEAD_INIT };
d337f35e 14821+
4bf69007 14822+static DEFINE_SPINLOCK(vx_info_hash_lock);
d337f35e 14823+
93de0823 14824+
61333608 14825+static inline unsigned int __hashval(vxid_t xid)
4bf69007
AM
14826+{
14827+ return (xid % VX_HASH_SIZE);
d337f35e
JR
14828+}
14829+
14830+
d337f35e 14831+
4bf69007 14832+/* __hash_vx_info()
d337f35e 14833+
4bf69007
AM
14834+ * add the vxi to the global hash table
14835+ * requires the hash_lock to be held */
d337f35e 14836+
4bf69007 14837+static inline void __hash_vx_info(struct vx_info *vxi)
d337f35e 14838+{
4bf69007 14839+ struct hlist_head *head;
d337f35e 14840+
4bf69007
AM
14841+ vxd_assert_lock(&vx_info_hash_lock);
14842+ vxdprintk(VXD_CBIT(xid, 4),
14843+ "__hash_vx_info: %p[#%d]", vxi, vxi->vx_id);
14844+ vxh_hash_vx_info(vxi);
d337f35e 14845+
4bf69007
AM
14846+ /* context must not be hashed */
14847+ BUG_ON(vx_info_state(vxi, VXS_HASHED));
d337f35e 14848+
4bf69007
AM
14849+ vxi->vx_state |= VXS_HASHED;
14850+ head = &vx_info_hash[__hashval(vxi->vx_id)];
14851+ hlist_add_head(&vxi->vx_hlist, head);
14852+ atomic_inc(&vx_global_cactive);
2380c486 14853+}
d337f35e 14854+
4bf69007 14855+/* __unhash_vx_info()
d337f35e 14856+
4bf69007
AM
14857+ * remove the vxi from the global hash table
14858+ * requires the hash_lock to be held */
d337f35e 14859+
4bf69007 14860+static inline void __unhash_vx_info(struct vx_info *vxi)
d337f35e 14861+{
4bf69007
AM
14862+ unsigned long flags;
14863+
14864+ vxd_assert_lock(&vx_info_hash_lock);
14865+ vxdprintk(VXD_CBIT(xid, 4),
14866+ "__unhash_vx_info: %p[#%d.%d.%d]", vxi, vxi->vx_id,
14867+ atomic_read(&vxi->vx_usecnt), atomic_read(&vxi->vx_tasks));
14868+ vxh_unhash_vx_info(vxi);
14869+
14870+ /* context must be hashed */
14871+ BUG_ON(!vx_info_state(vxi, VXS_HASHED));
14872+ /* but without tasks */
14873+ BUG_ON(atomic_read(&vxi->vx_tasks));
14874+
14875+ vxi->vx_state &= ~VXS_HASHED;
14876+ hlist_del_init(&vxi->vx_hlist);
14877+ spin_lock_irqsave(&vx_info_inactive_lock, flags);
14878+ hlist_add_head(&vxi->vx_hlist, &vx_info_inactive);
14879+ spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
14880+ atomic_dec(&vx_global_cactive);
2380c486 14881+}
d337f35e 14882+
d337f35e 14883+
4bf69007 14884+/* __lookup_vx_info()
d337f35e 14885+
4bf69007
AM
14886+ * requires the hash_lock to be held
14887+ * doesn't increment the vx_refcnt */
2380c486 14888+
61333608 14889+static inline struct vx_info *__lookup_vx_info(vxid_t xid)
d337f35e 14890+{
4bf69007
AM
14891+ struct hlist_head *head = &vx_info_hash[__hashval(xid)];
14892+ struct hlist_node *pos;
14893+ struct vx_info *vxi;
d337f35e 14894+
4bf69007
AM
14895+ vxd_assert_lock(&vx_info_hash_lock);
14896+ hlist_for_each(pos, head) {
14897+ vxi = hlist_entry(pos, struct vx_info, vx_hlist);
d337f35e 14898+
4bf69007
AM
14899+ if (vxi->vx_id == xid)
14900+ goto found;
14901+ }
14902+ vxi = NULL;
14903+found:
14904+ vxdprintk(VXD_CBIT(xid, 0),
14905+ "__lookup_vx_info(#%u): %p[#%u]",
14906+ xid, vxi, vxi ? vxi->vx_id : 0);
14907+ vxh_lookup_vx_info(vxi, xid);
14908+ return vxi;
14909+}
d337f35e 14910+
d337f35e 14911+
4bf69007 14912+/* __create_vx_info()
d337f35e 14913+
4bf69007
AM
14914+ * create the requested context
14915+ * get(), claim() and hash it */
2380c486 14916+
4bf69007
AM
14917+static struct vx_info *__create_vx_info(int id)
14918+{
14919+ struct vx_info *new, *vxi = NULL;
2380c486 14920+
4bf69007 14921+ vxdprintk(VXD_CBIT(xid, 1), "create_vx_info(%d)*", id);
d337f35e 14922+
4bf69007
AM
14923+ if (!(new = __alloc_vx_info(id)))
14924+ return ERR_PTR(-ENOMEM);
d337f35e 14925+
4bf69007
AM
14926+ /* required to make dynamic xids unique */
14927+ spin_lock(&vx_info_hash_lock);
d337f35e 14928+
4bf69007
AM
14929+ /* static context requested */
14930+ if ((vxi = __lookup_vx_info(id))) {
14931+ vxdprintk(VXD_CBIT(xid, 0),
14932+ "create_vx_info(%d) = %p (already there)", id, vxi);
14933+ if (vx_info_flags(vxi, VXF_STATE_SETUP, 0))
14934+ vxi = ERR_PTR(-EBUSY);
14935+ else
14936+ vxi = ERR_PTR(-EEXIST);
14937+ goto out_unlock;
14938+ }
14939+ /* new context */
14940+ vxdprintk(VXD_CBIT(xid, 0),
14941+ "create_vx_info(%d) = %p (new)", id, new);
14942+ claim_vx_info(new, NULL);
14943+ __hash_vx_info(get_vx_info(new));
14944+ vxi = new, new = NULL;
d337f35e 14945+
4bf69007
AM
14946+out_unlock:
14947+ spin_unlock(&vx_info_hash_lock);
14948+ vxh_create_vx_info(IS_ERR(vxi) ? NULL : vxi, id);
14949+ if (new)
14950+ __dealloc_vx_info(new);
14951+ return vxi;
14952+}
d337f35e 14953+
d337f35e 14954+
4bf69007 14955+/* exported stuff */
d337f35e 14956+
d337f35e 14957+
4bf69007 14958+void unhash_vx_info(struct vx_info *vxi)
d337f35e 14959+{
4bf69007
AM
14960+ spin_lock(&vx_info_hash_lock);
14961+ __unhash_vx_info(vxi);
14962+ spin_unlock(&vx_info_hash_lock);
14963+ __shutdown_vx_info(vxi);
14964+ __wakeup_vx_info(vxi);
2380c486 14965+}
d337f35e 14966+
2380c486 14967+
4bf69007 14968+/* lookup_vx_info()
2380c486 14969+
4bf69007
AM
14970+ * search for a vx_info and get() it
14971+ * negative id means current */
2380c486 14972+
4bf69007 14973+struct vx_info *lookup_vx_info(int id)
2380c486 14974+{
4bf69007
AM
14975+ struct vx_info *vxi = NULL;
14976+
14977+ if (id < 0) {
14978+ vxi = get_vx_info(current_vx_info());
14979+ } else if (id > 1) {
14980+ spin_lock(&vx_info_hash_lock);
14981+ vxi = get_vx_info(__lookup_vx_info(id));
14982+ spin_unlock(&vx_info_hash_lock);
2380c486 14983+ }
4bf69007 14984+ return vxi;
d337f35e
JR
14985+}
14986+
4bf69007 14987+/* xid_is_hashed()
d337f35e 14988+
4bf69007 14989+ * verify that xid is still hashed */
d337f35e 14990+
61333608 14991+int xid_is_hashed(vxid_t xid)
4bf69007
AM
14992+{
14993+ int hashed;
d337f35e 14994+
4bf69007
AM
14995+ spin_lock(&vx_info_hash_lock);
14996+ hashed = (__lookup_vx_info(xid) != NULL);
14997+ spin_unlock(&vx_info_hash_lock);
14998+ return hashed;
14999+}
d337f35e 15000+
4bf69007 15001+#ifdef CONFIG_PROC_FS
d337f35e 15002+
4bf69007 15003+/* get_xid_list()
d337f35e 15004+
4bf69007
AM
15005+ * get a subset of hashed xids for proc
15006+ * assumes size is at least one */
d337f35e 15007+
4bf69007
AM
15008+int get_xid_list(int index, unsigned int *xids, int size)
15009+{
15010+ int hindex, nr_xids = 0;
d337f35e 15011+
4bf69007
AM
15012+ /* only show current and children */
15013+ if (!vx_check(0, VS_ADMIN | VS_WATCH)) {
15014+ if (index > 0)
15015+ return 0;
15016+ xids[nr_xids] = vx_current_xid();
15017+ return 1;
15018+ }
d337f35e 15019+
4bf69007
AM
15020+ for (hindex = 0; hindex < VX_HASH_SIZE; hindex++) {
15021+ struct hlist_head *head = &vx_info_hash[hindex];
15022+ struct hlist_node *pos;
d337f35e 15023+
4bf69007
AM
15024+ spin_lock(&vx_info_hash_lock);
15025+ hlist_for_each(pos, head) {
15026+ struct vx_info *vxi;
d337f35e 15027+
4bf69007
AM
15028+ if (--index > 0)
15029+ continue;
d337f35e 15030+
4bf69007
AM
15031+ vxi = hlist_entry(pos, struct vx_info, vx_hlist);
15032+ xids[nr_xids] = vxi->vx_id;
15033+ if (++nr_xids >= size) {
15034+ spin_unlock(&vx_info_hash_lock);
15035+ goto out;
15036+ }
15037+ }
15038+ /* keep the lock time short */
15039+ spin_unlock(&vx_info_hash_lock);
15040+ }
15041+out:
15042+ return nr_xids;
15043+}
15044+#endif
d337f35e 15045+
4bf69007 15046+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 15047+
4bf69007 15048+void dump_vx_info_inactive(int level)
d337f35e 15049+{
4bf69007 15050+ struct hlist_node *entry, *next;
d337f35e 15051+
4bf69007
AM
15052+ hlist_for_each_safe(entry, next, &vx_info_inactive) {
15053+ struct vx_info *vxi =
15054+ list_entry(entry, struct vx_info, vx_hlist);
d337f35e 15055+
4bf69007
AM
15056+ dump_vx_info(vxi, level);
15057+ }
d337f35e
JR
15058+}
15059+
4bf69007 15060+#endif
d337f35e 15061+
4bf69007
AM
15062+#if 0
15063+int vx_migrate_user(struct task_struct *p, struct vx_info *vxi)
d337f35e 15064+{
4bf69007 15065+ struct user_struct *new_user, *old_user;
d337f35e 15066+
4bf69007
AM
15067+ if (!p || !vxi)
15068+ BUG();
d337f35e 15069+
4bf69007
AM
15070+ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
15071+ return -EACCES;
d337f35e 15072+
4bf69007
AM
15073+ new_user = alloc_uid(vxi->vx_id, p->uid);
15074+ if (!new_user)
15075+ return -ENOMEM;
d337f35e 15076+
4bf69007
AM
15077+ old_user = p->user;
15078+ if (new_user != old_user) {
15079+ atomic_inc(&new_user->processes);
15080+ atomic_dec(&old_user->processes);
15081+ p->user = new_user;
d337f35e 15082+ }
4bf69007
AM
15083+ free_uid(old_user);
15084+ return 0;
d337f35e 15085+}
4bf69007 15086+#endif
d337f35e 15087+
4bf69007
AM
15088+#if 0
15089+void vx_mask_cap_bset(struct vx_info *vxi, struct task_struct *p)
d337f35e 15090+{
4bf69007
AM
15091+ // p->cap_effective &= vxi->vx_cap_bset;
15092+ p->cap_effective =
15093+ cap_intersect(p->cap_effective, vxi->cap_bset);
15094+ // p->cap_inheritable &= vxi->vx_cap_bset;
15095+ p->cap_inheritable =
15096+ cap_intersect(p->cap_inheritable, vxi->cap_bset);
15097+ // p->cap_permitted &= vxi->vx_cap_bset;
15098+ p->cap_permitted =
15099+ cap_intersect(p->cap_permitted, vxi->cap_bset);
15100+}
15101+#endif
d337f35e
JR
15102+
15103+
4bf69007
AM
15104+#include <linux/file.h>
15105+#include <linux/fdtable.h>
d337f35e 15106+
4bf69007
AM
15107+static int vx_openfd_task(struct task_struct *tsk)
15108+{
15109+ struct files_struct *files = tsk->files;
15110+ struct fdtable *fdt;
15111+ const unsigned long *bptr;
15112+ int count, total;
d337f35e 15113+
4bf69007
AM
15114+ /* no rcu_read_lock() because of spin_lock() */
15115+ spin_lock(&files->file_lock);
15116+ fdt = files_fdtable(files);
15117+ bptr = fdt->open_fds;
15118+ count = fdt->max_fds / (sizeof(unsigned long) * 8);
15119+ for (total = 0; count > 0; count--) {
15120+ if (*bptr)
15121+ total += hweight_long(*bptr);
15122+ bptr++;
15123+ }
15124+ spin_unlock(&files->file_lock);
15125+ return total;
d337f35e
JR
15126+}
15127+
d337f35e 15128+
4bf69007
AM
15129+/* for *space compatibility */
15130+
15131+asmlinkage long sys_unshare(unsigned long);
15132+
15133+/*
15134+ * migrate task to new context
15135+ * gets vxi, puts old_vxi on change
15136+ * optionally unshares namespaces (hack)
2380c486 15137+ */
4bf69007
AM
15138+
15139+int vx_migrate_task(struct task_struct *p, struct vx_info *vxi, int unshare)
2380c486 15140+{
4bf69007
AM
15141+ struct vx_info *old_vxi;
15142+ int ret = 0;
d337f35e 15143+
4bf69007
AM
15144+ if (!p || !vxi)
15145+ BUG();
d337f35e 15146+
4bf69007
AM
15147+ vxdprintk(VXD_CBIT(xid, 5),
15148+ "vx_migrate_task(%p,%p[#%d.%d])", p, vxi,
15149+ vxi->vx_id, atomic_read(&vxi->vx_usecnt));
d337f35e 15150+
4bf69007
AM
15151+ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0) &&
15152+ !vx_info_flags(vxi, VXF_STATE_SETUP, 0))
15153+ return -EACCES;
2380c486 15154+
4bf69007
AM
15155+ if (vx_info_state(vxi, VXS_SHUTDOWN))
15156+ return -EFAULT;
d337f35e 15157+
4bf69007
AM
15158+ old_vxi = task_get_vx_info(p);
15159+ if (old_vxi == vxi)
15160+ goto out;
d337f35e 15161+
4bf69007
AM
15162+// if (!(ret = vx_migrate_user(p, vxi))) {
15163+ {
15164+ int openfd;
d337f35e 15165+
4bf69007
AM
15166+ task_lock(p);
15167+ openfd = vx_openfd_task(p);
15168+
15169+ if (old_vxi) {
15170+ atomic_dec(&old_vxi->cvirt.nr_threads);
15171+ atomic_dec(&old_vxi->cvirt.nr_running);
15172+ __rlim_dec(&old_vxi->limit, RLIMIT_NPROC);
15173+ /* FIXME: what about the struct files here? */
15174+ __rlim_sub(&old_vxi->limit, VLIMIT_OPENFD, openfd);
15175+ /* account for the executable */
15176+ __rlim_dec(&old_vxi->limit, VLIMIT_DENTRY);
2380c486 15177+ }
4bf69007
AM
15178+ atomic_inc(&vxi->cvirt.nr_threads);
15179+ atomic_inc(&vxi->cvirt.nr_running);
15180+ __rlim_inc(&vxi->limit, RLIMIT_NPROC);
15181+ /* FIXME: what about the struct files here? */
15182+ __rlim_add(&vxi->limit, VLIMIT_OPENFD, openfd);
15183+ /* account for the executable */
15184+ __rlim_inc(&vxi->limit, VLIMIT_DENTRY);
2380c486 15185+
4bf69007
AM
15186+ if (old_vxi) {
15187+ release_vx_info(old_vxi, p);
15188+ clr_vx_info(&p->vx_info);
15189+ }
15190+ claim_vx_info(vxi, p);
15191+ set_vx_info(&p->vx_info, vxi);
15192+ p->xid = vxi->vx_id;
d337f35e 15193+
4bf69007
AM
15194+ vxdprintk(VXD_CBIT(xid, 5),
15195+ "moved task %p into vxi:%p[#%d]",
15196+ p, vxi, vxi->vx_id);
d337f35e 15197+
4bf69007
AM
15198+ // vx_mask_cap_bset(vxi, p);
15199+ task_unlock(p);
d337f35e 15200+
4bf69007
AM
15201+ /* hack for *spaces to provide compatibility */
15202+ if (unshare) {
15203+ struct nsproxy *old_nsp, *new_nsp;
d337f35e 15204+
4bf69007
AM
15205+ ret = unshare_nsproxy_namespaces(
15206+ CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER,
b00e13aa 15207+ &new_nsp, NULL, NULL);
4bf69007
AM
15208+ if (ret)
15209+ goto out;
d337f35e 15210+
4bf69007
AM
15211+ old_nsp = xchg(&p->nsproxy, new_nsp);
15212+ vx_set_space(vxi,
15213+ CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER, 0);
15214+ put_nsproxy(old_nsp);
15215+ }
15216+ }
15217+out:
15218+ put_vx_info(old_vxi);
2380c486
JR
15219+ return ret;
15220+}
d337f35e 15221+
4bf69007 15222+int vx_set_reaper(struct vx_info *vxi, struct task_struct *p)
d337f35e 15223+{
4bf69007
AM
15224+ struct task_struct *old_reaper;
15225+ struct vx_info *reaper_vxi;
d337f35e 15226+
4bf69007
AM
15227+ if (!vxi)
15228+ return -EINVAL;
d337f35e 15229+
4bf69007
AM
15230+ vxdprintk(VXD_CBIT(xid, 6),
15231+ "vx_set_reaper(%p[#%d],%p[#%d,%d])",
15232+ vxi, vxi->vx_id, p, p->xid, p->pid);
d337f35e 15233+
4bf69007
AM
15234+ old_reaper = vxi->vx_reaper;
15235+ if (old_reaper == p)
15236+ return 0;
d337f35e 15237+
4bf69007
AM
15238+ reaper_vxi = task_get_vx_info(p);
15239+ if (reaper_vxi && reaper_vxi != vxi) {
15240+ vxwprintk(1,
15241+ "Unsuitable reaper [" VS_Q("%s") ",%u:#%u] "
15242+ "for [xid #%u]",
15243+ p->comm, p->pid, p->xid, vx_current_xid());
2380c486
JR
15244+ goto out;
15245+ }
4bf69007
AM
15246+
15247+ /* set new child reaper */
15248+ get_task_struct(p);
15249+ vxi->vx_reaper = p;
15250+ put_task_struct(old_reaper);
2380c486 15251+out:
4bf69007
AM
15252+ put_vx_info(reaper_vxi);
15253+ return 0;
2380c486 15254+}
d337f35e 15255+
4bf69007 15256+int vx_set_init(struct vx_info *vxi, struct task_struct *p)
d337f35e 15257+{
4bf69007
AM
15258+ if (!vxi)
15259+ return -EINVAL;
d337f35e 15260+
4bf69007
AM
15261+ vxdprintk(VXD_CBIT(xid, 6),
15262+ "vx_set_init(%p[#%d],%p[#%d,%d,%d])",
15263+ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
d337f35e 15264+
4bf69007
AM
15265+ vxi->vx_flags &= ~VXF_STATE_INIT;
15266+ // vxi->vx_initpid = p->tgid;
15267+ vxi->vx_initpid = p->pid;
2380c486 15268+ return 0;
d337f35e
JR
15269+}
15270+
4bf69007 15271+void vx_exit_init(struct vx_info *vxi, struct task_struct *p, int code)
d337f35e 15272+{
4bf69007
AM
15273+ vxdprintk(VXD_CBIT(xid, 6),
15274+ "vx_exit_init(%p[#%d],%p[#%d,%d,%d])",
15275+ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
2380c486 15276+
4bf69007
AM
15277+ vxi->exit_code = code;
15278+ vxi->vx_initpid = 0;
d337f35e
JR
15279+}
15280+
2380c486 15281+
4bf69007 15282+void vx_set_persistent(struct vx_info *vxi)
d337f35e 15283+{
4bf69007
AM
15284+ vxdprintk(VXD_CBIT(xid, 6),
15285+ "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id);
2380c486 15286+
4bf69007
AM
15287+ get_vx_info(vxi);
15288+ claim_vx_info(vxi, NULL);
d337f35e
JR
15289+}
15290+
4bf69007 15291+void vx_clear_persistent(struct vx_info *vxi)
2380c486 15292+{
4bf69007
AM
15293+ vxdprintk(VXD_CBIT(xid, 6),
15294+ "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id);
d337f35e 15295+
4bf69007
AM
15296+ release_vx_info(vxi, NULL);
15297+ put_vx_info(vxi);
2380c486 15298+}
d337f35e 15299+
4bf69007 15300+void vx_update_persistent(struct vx_info *vxi)
d337f35e 15301+{
4bf69007
AM
15302+ if (vx_info_flags(vxi, VXF_PERSISTENT, 0))
15303+ vx_set_persistent(vxi);
2380c486 15304+ else
4bf69007 15305+ vx_clear_persistent(vxi);
2380c486 15306+}
d337f35e 15307+
d337f35e 15308+
4bf69007
AM
15309+/* task must be current or locked */
15310+
15311+void exit_vx_info(struct task_struct *p, int code)
2380c486 15312+{
4bf69007 15313+ struct vx_info *vxi = p->vx_info;
d337f35e 15314+
4bf69007
AM
15315+ if (vxi) {
15316+ atomic_dec(&vxi->cvirt.nr_threads);
15317+ vx_nproc_dec(p);
d337f35e 15318+
4bf69007
AM
15319+ vxi->exit_code = code;
15320+ release_vx_info(vxi, p);
15321+ }
2380c486 15322+}
d337f35e 15323+
4bf69007 15324+void exit_vx_info_early(struct task_struct *p, int code)
2380c486 15325+{
4bf69007 15326+ struct vx_info *vxi = p->vx_info;
d337f35e 15327+
4bf69007
AM
15328+ if (vxi) {
15329+ if (vxi->vx_initpid == p->pid)
15330+ vx_exit_init(vxi, p, code);
15331+ if (vxi->vx_reaper == p)
15332+ vx_set_reaper(vxi, init_pid_ns.child_reaper);
15333+ }
d337f35e
JR
15334+}
15335+
15336+
4bf69007 15337+/* vserver syscall commands below here */
d337f35e 15338+
4bf69007 15339+/* taks xid and vx_info functions */
d337f35e 15340+
4bf69007 15341+#include <asm/uaccess.h>
d337f35e 15342+
d337f35e 15343+
4bf69007 15344+int vc_task_xid(uint32_t id)
d337f35e 15345+{
61333608 15346+ vxid_t xid;
d337f35e 15347+
4bf69007
AM
15348+ if (id) {
15349+ struct task_struct *tsk;
d337f35e 15350+
4bf69007
AM
15351+ rcu_read_lock();
15352+ tsk = find_task_by_real_pid(id);
15353+ xid = (tsk) ? tsk->xid : -ESRCH;
15354+ rcu_read_unlock();
15355+ } else
15356+ xid = vx_current_xid();
15357+ return xid;
d337f35e
JR
15358+}
15359+
d337f35e 15360+
4bf69007
AM
15361+int vc_vx_info(struct vx_info *vxi, void __user *data)
15362+{
15363+ struct vcmd_vx_info_v0 vc_data;
d337f35e 15364+
4bf69007
AM
15365+ vc_data.xid = vxi->vx_id;
15366+ vc_data.initpid = vxi->vx_initpid;
d337f35e 15367+
4bf69007
AM
15368+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15369+ return -EFAULT;
15370+ return 0;
15371+}
d337f35e 15372+
d337f35e 15373+
4bf69007 15374+int vc_ctx_stat(struct vx_info *vxi, void __user *data)
d337f35e 15375+{
4bf69007 15376+ struct vcmd_ctx_stat_v0 vc_data;
d337f35e 15377+
4bf69007
AM
15378+ vc_data.usecnt = atomic_read(&vxi->vx_usecnt);
15379+ vc_data.tasks = atomic_read(&vxi->vx_tasks);
d337f35e 15380+
4bf69007
AM
15381+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15382+ return -EFAULT;
15383+ return 0;
d337f35e
JR
15384+}
15385+
d337f35e 15386+
4bf69007 15387+/* context functions */
d337f35e 15388+
4bf69007 15389+int vc_ctx_create(uint32_t xid, void __user *data)
d337f35e 15390+{
4bf69007
AM
15391+ struct vcmd_ctx_create vc_data = { .flagword = VXF_INIT_SET };
15392+ struct vx_info *new_vxi;
15393+ int ret;
d337f35e 15394+
4bf69007
AM
15395+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
15396+ return -EFAULT;
d337f35e 15397+
4bf69007
AM
15398+ if ((xid > MAX_S_CONTEXT) || (xid < 2))
15399+ return -EINVAL;
d337f35e 15400+
4bf69007
AM
15401+ new_vxi = __create_vx_info(xid);
15402+ if (IS_ERR(new_vxi))
15403+ return PTR_ERR(new_vxi);
d337f35e 15404+
4bf69007
AM
15405+ /* initial flags */
15406+ new_vxi->vx_flags = vc_data.flagword;
d337f35e 15407+
4bf69007
AM
15408+ ret = -ENOEXEC;
15409+ if (vs_state_change(new_vxi, VSC_STARTUP))
15410+ goto out;
d337f35e 15411+
4bf69007
AM
15412+ ret = vx_migrate_task(current, new_vxi, (!data));
15413+ if (ret)
15414+ goto out;
d337f35e 15415+
4bf69007
AM
15416+ /* return context id on success */
15417+ ret = new_vxi->vx_id;
d337f35e 15418+
4bf69007
AM
15419+ /* get a reference for persistent contexts */
15420+ if ((vc_data.flagword & VXF_PERSISTENT))
15421+ vx_set_persistent(new_vxi);
15422+out:
15423+ release_vx_info(new_vxi, NULL);
15424+ put_vx_info(new_vxi);
15425+ return ret;
15426+}
d337f35e
JR
15427+
15428+
4bf69007 15429+int vc_ctx_migrate(struct vx_info *vxi, void __user *data)
d337f35e 15430+{
4bf69007
AM
15431+ struct vcmd_ctx_migrate vc_data = { .flagword = 0 };
15432+ int ret;
d337f35e 15433+
4bf69007
AM
15434+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
15435+ return -EFAULT;
d337f35e 15436+
4bf69007
AM
15437+ ret = vx_migrate_task(current, vxi, 0);
15438+ if (ret)
15439+ return ret;
15440+ if (vc_data.flagword & VXM_SET_INIT)
15441+ ret = vx_set_init(vxi, current);
15442+ if (ret)
15443+ return ret;
15444+ if (vc_data.flagword & VXM_SET_REAPER)
15445+ ret = vx_set_reaper(vxi, current);
15446+ return ret;
15447+}
d337f35e 15448+
d337f35e 15449+
4bf69007 15450+int vc_get_cflags(struct vx_info *vxi, void __user *data)
d337f35e 15451+{
4bf69007 15452+ struct vcmd_ctx_flags_v0 vc_data;
d337f35e 15453+
4bf69007 15454+ vc_data.flagword = vxi->vx_flags;
d337f35e 15455+
4bf69007
AM
15456+ /* special STATE flag handling */
15457+ vc_data.mask = vs_mask_flags(~0ULL, vxi->vx_flags, VXF_ONE_TIME);
d337f35e 15458+
4bf69007
AM
15459+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15460+ return -EFAULT;
15461+ return 0;
d337f35e
JR
15462+}
15463+
4bf69007
AM
15464+int vc_set_cflags(struct vx_info *vxi, void __user *data)
15465+{
15466+ struct vcmd_ctx_flags_v0 vc_data;
15467+ uint64_t mask, trigger;
d337f35e 15468+
4bf69007
AM
15469+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15470+ return -EFAULT;
d337f35e 15471+
4bf69007
AM
15472+ /* special STATE flag handling */
15473+ mask = vs_mask_mask(vc_data.mask, vxi->vx_flags, VXF_ONE_TIME);
15474+ trigger = (mask & vxi->vx_flags) ^ (mask & vc_data.flagword);
d337f35e 15475+
4bf69007
AM
15476+ if (vxi == current_vx_info()) {
15477+ /* if (trigger & VXF_STATE_SETUP)
15478+ vx_mask_cap_bset(vxi, current); */
15479+ if (trigger & VXF_STATE_INIT) {
15480+ int ret;
d337f35e 15481+
4bf69007
AM
15482+ ret = vx_set_init(vxi, current);
15483+ if (ret)
15484+ return ret;
15485+ ret = vx_set_reaper(vxi, current);
15486+ if (ret)
15487+ return ret;
d337f35e
JR
15488+ }
15489+ }
4bf69007
AM
15490+
15491+ vxi->vx_flags = vs_mask_flags(vxi->vx_flags,
15492+ vc_data.flagword, mask);
15493+ if (trigger & VXF_PERSISTENT)
15494+ vx_update_persistent(vxi);
15495+
15496+ return 0;
d337f35e
JR
15497+}
15498+
15499+
4bf69007 15500+static inline uint64_t caps_from_cap_t(kernel_cap_t c)
d337f35e 15501+{
4bf69007 15502+ uint64_t v = c.cap[0] | ((uint64_t)c.cap[1] << 32);
d337f35e 15503+
4bf69007
AM
15504+ // printk("caps_from_cap_t(%08x:%08x) = %016llx\n", c.cap[1], c.cap[0], v);
15505+ return v;
d337f35e
JR
15506+}
15507+
4bf69007 15508+static inline kernel_cap_t cap_t_from_caps(uint64_t v)
d337f35e 15509+{
4bf69007 15510+ kernel_cap_t c = __cap_empty_set;
d337f35e 15511+
4bf69007
AM
15512+ c.cap[0] = v & 0xFFFFFFFF;
15513+ c.cap[1] = (v >> 32) & 0xFFFFFFFF;
d337f35e 15514+
4bf69007
AM
15515+ // printk("cap_t_from_caps(%016llx) = %08x:%08x\n", v, c.cap[1], c.cap[0]);
15516+ return c;
d337f35e
JR
15517+}
15518+
15519+
4bf69007 15520+static int do_get_caps(struct vx_info *vxi, uint64_t *bcaps, uint64_t *ccaps)
d337f35e 15521+{
4bf69007
AM
15522+ if (bcaps)
15523+ *bcaps = caps_from_cap_t(vxi->vx_bcaps);
15524+ if (ccaps)
15525+ *ccaps = vxi->vx_ccaps;
d337f35e 15526+
4bf69007
AM
15527+ return 0;
15528+}
d337f35e 15529+
4bf69007
AM
15530+int vc_get_ccaps(struct vx_info *vxi, void __user *data)
15531+{
15532+ struct vcmd_ctx_caps_v1 vc_data;
15533+ int ret;
d337f35e 15534+
4bf69007
AM
15535+ ret = do_get_caps(vxi, NULL, &vc_data.ccaps);
15536+ if (ret)
15537+ return ret;
15538+ vc_data.cmask = ~0ULL;
d337f35e 15539+
4bf69007
AM
15540+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15541+ return -EFAULT;
15542+ return 0;
d337f35e
JR
15543+}
15544+
4bf69007
AM
15545+static int do_set_caps(struct vx_info *vxi,
15546+ uint64_t bcaps, uint64_t bmask, uint64_t ccaps, uint64_t cmask)
d337f35e 15547+{
4bf69007 15548+ uint64_t bcold = caps_from_cap_t(vxi->vx_bcaps);
d337f35e 15549+
4bf69007
AM
15550+#if 0
15551+ printk("do_set_caps(%16llx, %16llx, %16llx, %16llx)\n",
15552+ bcaps, bmask, ccaps, cmask);
15553+#endif
15554+ vxi->vx_bcaps = cap_t_from_caps(
15555+ vs_mask_flags(bcold, bcaps, bmask));
15556+ vxi->vx_ccaps = vs_mask_flags(vxi->vx_ccaps, ccaps, cmask);
d337f35e 15557+
4bf69007 15558+ return 0;
d337f35e
JR
15559+}
15560+
4bf69007 15561+int vc_set_ccaps(struct vx_info *vxi, void __user *data)
d337f35e 15562+{
4bf69007 15563+ struct vcmd_ctx_caps_v1 vc_data;
d337f35e 15564+
2380c486 15565+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15566+ return -EFAULT;
15567+
4bf69007 15568+ return do_set_caps(vxi, 0, 0, vc_data.ccaps, vc_data.cmask);
d337f35e
JR
15569+}
15570+
4bf69007 15571+int vc_get_bcaps(struct vx_info *vxi, void __user *data)
d337f35e 15572+{
4bf69007
AM
15573+ struct vcmd_bcaps vc_data;
15574+ int ret;
d337f35e 15575+
4bf69007
AM
15576+ ret = do_get_caps(vxi, &vc_data.bcaps, NULL);
15577+ if (ret)
15578+ return ret;
15579+ vc_data.bmask = ~0ULL;
d337f35e 15580+
4bf69007
AM
15581+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15582+ return -EFAULT;
15583+ return 0;
d337f35e
JR
15584+}
15585+
4bf69007 15586+int vc_set_bcaps(struct vx_info *vxi, void __user *data)
d337f35e 15587+{
4bf69007 15588+ struct vcmd_bcaps vc_data;
d337f35e 15589+
2380c486 15590+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15591+ return -EFAULT;
15592+
4bf69007 15593+ return do_set_caps(vxi, vc_data.bcaps, vc_data.bmask, 0, 0);
d337f35e
JR
15594+}
15595+
d337f35e 15596+
4bf69007 15597+int vc_get_umask(struct vx_info *vxi, void __user *data)
d337f35e 15598+{
4bf69007 15599+ struct vcmd_umask vc_data;
7e46296a 15600+
4bf69007
AM
15601+ vc_data.umask = vxi->vx_umask;
15602+ vc_data.mask = ~0ULL;
d337f35e 15603+
4bf69007
AM
15604+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15605+ return -EFAULT;
15606+ return 0;
15607+}
d337f35e 15608+
4bf69007
AM
15609+int vc_set_umask(struct vx_info *vxi, void __user *data)
15610+{
15611+ struct vcmd_umask vc_data;
d337f35e 15612+
4bf69007
AM
15613+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15614+ return -EFAULT;
7e46296a 15615+
4bf69007
AM
15616+ vxi->vx_umask = vs_mask_flags(vxi->vx_umask,
15617+ vc_data.umask, vc_data.mask);
15618+ return 0;
15619+}
7e46296a 15620+
d337f35e 15621+
4bf69007
AM
15622+int vc_get_wmask(struct vx_info *vxi, void __user *data)
15623+{
15624+ struct vcmd_wmask vc_data;
d337f35e 15625+
4bf69007
AM
15626+ vc_data.wmask = vxi->vx_wmask;
15627+ vc_data.mask = ~0ULL;
d337f35e 15628+
4bf69007
AM
15629+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15630+ return -EFAULT;
15631+ return 0;
d337f35e
JR
15632+}
15633+
4bf69007 15634+int vc_set_wmask(struct vx_info *vxi, void __user *data)
d337f35e 15635+{
4bf69007 15636+ struct vcmd_wmask vc_data;
d337f35e 15637+
2380c486 15638+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15639+ return -EFAULT;
15640+
4bf69007
AM
15641+ vxi->vx_wmask = vs_mask_flags(vxi->vx_wmask,
15642+ vc_data.wmask, vc_data.mask);
15643+ return 0;
d337f35e
JR
15644+}
15645+
d337f35e 15646+
4bf69007 15647+int vc_get_badness(struct vx_info *vxi, void __user *data)
d337f35e 15648+{
4bf69007
AM
15649+ struct vcmd_badness_v0 vc_data;
15650+
15651+ vc_data.bias = vxi->vx_badness_bias;
15652+
15653+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15654+ return -EFAULT;
15655+ return 0;
15656+}
15657+
15658+int vc_set_badness(struct vx_info *vxi, void __user *data)
15659+{
15660+ struct vcmd_badness_v0 vc_data;
d337f35e 15661+
2380c486 15662+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15663+ return -EFAULT;
15664+
4bf69007
AM
15665+ vxi->vx_badness_bias = vc_data.bias;
15666+ return 0;
d337f35e
JR
15667+}
15668+
4bf69007 15669+#include <linux/module.h>
d337f35e 15670+
4bf69007 15671+EXPORT_SYMBOL_GPL(free_vx_info);
d337f35e 15672+
cef7ea10
AM
15673diff -NurpP --minimal linux-4.9.82/kernel/vserver/cvirt.c linux-4.9.82-vs2.3.9.7/kernel/vserver/cvirt.c
15674--- linux-4.9.82/kernel/vserver/cvirt.c 1970-01-01 00:00:00.000000000 +0000
15675+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/cvirt.c 2018-01-16 00:54:54.000000000 +0000
cc23e853 15676@@ -0,0 +1,350 @@
4bf69007
AM
15677+/*
15678+ * linux/kernel/vserver/cvirt.c
15679+ *
15680+ * Virtual Server: Context Virtualization
15681+ *
cc23e853 15682+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
15683+ *
15684+ * V0.01 broken out from limit.c
15685+ * V0.02 added utsname stuff
15686+ * V0.03 changed vcmds to vxi arg
15687+ *
15688+ */
d337f35e 15689+
4bf69007
AM
15690+#include <linux/types.h>
15691+#include <linux/utsname.h>
15692+#include <linux/vs_cvirt.h>
15693+#include <linux/vserver/switch.h>
15694+#include <linux/vserver/cvirt_cmd.h>
d337f35e 15695+
4bf69007 15696+#include <asm/uaccess.h>
d337f35e 15697+
d337f35e 15698+
369dbd59 15699+void vx_vsi_boottime64(struct timespec64 *boottime)
4bf69007
AM
15700+{
15701+ struct vx_info *vxi = current_vx_info();
d337f35e 15702+
369dbd59 15703+ set_normalized_timespec64(boottime,
4bf69007
AM
15704+ boottime->tv_sec + vxi->cvirt.bias_uptime.tv_sec,
15705+ boottime->tv_nsec + vxi->cvirt.bias_uptime.tv_nsec);
15706+ return;
d337f35e
JR
15707+}
15708+
4bf69007 15709+void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle)
d337f35e 15710+{
4bf69007 15711+ struct vx_info *vxi = current_vx_info();
d337f35e 15712+
4bf69007
AM
15713+ set_normalized_timespec(uptime,
15714+ uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec,
15715+ uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec);
15716+ if (!idle)
15717+ return;
15718+ set_normalized_timespec(idle,
15719+ idle->tv_sec - vxi->cvirt.bias_idle.tv_sec,
15720+ idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec);
15721+ return;
d337f35e
JR
15722+}
15723+
4bf69007 15724+uint64_t vx_idle_jiffies(void)
d337f35e 15725+{
4bf69007 15726+ return init_task.utime + init_task.stime;
d337f35e
JR
15727+}
15728+
d337f35e
JR
15729+
15730+
4bf69007
AM
15731+static inline uint32_t __update_loadavg(uint32_t load,
15732+ int wsize, int delta, int n)
d337f35e 15733+{
4bf69007 15734+ unsigned long long calc, prev;
d337f35e 15735+
4bf69007
AM
15736+ /* just set it to n */
15737+ if (unlikely(delta >= wsize))
15738+ return (n << FSHIFT);
d337f35e 15739+
4bf69007
AM
15740+ calc = delta * n;
15741+ calc <<= FSHIFT;
15742+ prev = (wsize - delta);
15743+ prev *= load;
15744+ calc += prev;
15745+ do_div(calc, wsize);
15746+ return calc;
15747+}
d337f35e 15748+
d337f35e 15749+
4bf69007
AM
15750+void vx_update_load(struct vx_info *vxi)
15751+{
15752+ uint32_t now, last, delta;
15753+ unsigned int nr_running, nr_uninterruptible;
15754+ unsigned int total;
15755+ unsigned long flags;
d337f35e 15756+
4bf69007 15757+ spin_lock_irqsave(&vxi->cvirt.load_lock, flags);
d337f35e 15758+
4bf69007
AM
15759+ now = jiffies;
15760+ last = vxi->cvirt.load_last;
15761+ delta = now - last;
d337f35e 15762+
4bf69007
AM
15763+ if (delta < 5*HZ)
15764+ goto out;
d337f35e 15765+
4bf69007
AM
15766+ nr_running = atomic_read(&vxi->cvirt.nr_running);
15767+ nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible);
15768+ total = nr_running + nr_uninterruptible;
d337f35e 15769+
4bf69007
AM
15770+ vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0],
15771+ 60*HZ, delta, total);
15772+ vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1],
15773+ 5*60*HZ, delta, total);
15774+ vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2],
15775+ 15*60*HZ, delta, total);
d337f35e 15776+
4bf69007
AM
15777+ vxi->cvirt.load_last = now;
15778+out:
15779+ atomic_inc(&vxi->cvirt.load_updates);
15780+ spin_unlock_irqrestore(&vxi->cvirt.load_lock, flags);
d337f35e
JR
15781+}
15782+
d337f35e 15783+
d337f35e 15784+/*
4bf69007 15785+ * Commands to do_syslog:
d337f35e 15786+ *
4bf69007
AM
15787+ * 0 -- Close the log. Currently a NOP.
15788+ * 1 -- Open the log. Currently a NOP.
15789+ * 2 -- Read from the log.
15790+ * 3 -- Read all messages remaining in the ring buffer.
15791+ * 4 -- Read and clear all messages remaining in the ring buffer
15792+ * 5 -- Clear ring buffer.
15793+ * 6 -- Disable printk's to console
15794+ * 7 -- Enable printk's to console
15795+ * 8 -- Set level of messages printed to console
15796+ * 9 -- Return number of unread characters in the log buffer
15797+ * 10 -- Return size of the log buffer
d337f35e 15798+ */
4bf69007
AM
15799+int vx_do_syslog(int type, char __user *buf, int len)
15800+{
15801+ int error = 0;
15802+ int do_clear = 0;
15803+ struct vx_info *vxi = current_vx_info();
15804+ struct _vx_syslog *log;
d337f35e 15805+
4bf69007
AM
15806+ if (!vxi)
15807+ return -EINVAL;
15808+ log = &vxi->cvirt.syslog;
15809+
15810+ switch (type) {
15811+ case 0: /* Close log */
15812+ case 1: /* Open log */
15813+ break;
15814+ case 2: /* Read from log */
15815+ error = wait_event_interruptible(log->log_wait,
15816+ (log->log_start - log->log_end));
15817+ if (error)
15818+ break;
15819+ spin_lock_irq(&log->logbuf_lock);
15820+ spin_unlock_irq(&log->logbuf_lock);
15821+ break;
15822+ case 4: /* Read/clear last kernel messages */
15823+ do_clear = 1;
15824+ /* fall through */
15825+ case 3: /* Read last kernel messages */
15826+ return 0;
d337f35e 15827+
4bf69007
AM
15828+ case 5: /* Clear ring buffer */
15829+ return 0;
d337f35e 15830+
4bf69007
AM
15831+ case 6: /* Disable logging to console */
15832+ case 7: /* Enable logging to console */
15833+ case 8: /* Set level of messages printed to console */
15834+ break;
d337f35e 15835+
4bf69007
AM
15836+ case 9: /* Number of chars in the log buffer */
15837+ return 0;
15838+ case 10: /* Size of the log buffer */
15839+ return 0;
15840+ default:
15841+ error = -EINVAL;
15842+ break;
15843+ }
15844+ return error;
1e8b8f9b 15845+}
d337f35e 15846+
4bf69007
AM
15847+
15848+/* virtual host info names */
15849+
15850+static char *vx_vhi_name(struct vx_info *vxi, int id)
d337f35e 15851+{
4bf69007
AM
15852+ struct nsproxy *nsproxy;
15853+ struct uts_namespace *uts;
d337f35e 15854+
4bf69007
AM
15855+ if (id == VHIN_CONTEXT)
15856+ return vxi->vx_name;
15857+
15858+ nsproxy = vxi->space[0].vx_nsproxy;
15859+ if (!nsproxy)
15860+ return NULL;
15861+
15862+ uts = nsproxy->uts_ns;
15863+ if (!uts)
15864+ return NULL;
15865+
15866+ switch (id) {
15867+ case VHIN_SYSNAME:
15868+ return uts->name.sysname;
15869+ case VHIN_NODENAME:
15870+ return uts->name.nodename;
15871+ case VHIN_RELEASE:
15872+ return uts->name.release;
15873+ case VHIN_VERSION:
15874+ return uts->name.version;
15875+ case VHIN_MACHINE:
15876+ return uts->name.machine;
15877+ case VHIN_DOMAINNAME:
15878+ return uts->name.domainname;
15879+ default:
15880+ return NULL;
d337f35e 15881+ }
4bf69007 15882+ return NULL;
d337f35e
JR
15883+}
15884+
4bf69007 15885+int vc_set_vhi_name(struct vx_info *vxi, void __user *data)
d337f35e 15886+{
4bf69007
AM
15887+ struct vcmd_vhi_name_v0 vc_data;
15888+ char *name;
d337f35e 15889+
4bf69007
AM
15890+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15891+ return -EFAULT;
d337f35e 15892+
4bf69007
AM
15893+ name = vx_vhi_name(vxi, vc_data.field);
15894+ if (!name)
15895+ return -EINVAL;
d337f35e 15896+
4bf69007
AM
15897+ memcpy(name, vc_data.name, 65);
15898+ return 0;
15899+}
d337f35e 15900+
4bf69007
AM
15901+int vc_get_vhi_name(struct vx_info *vxi, void __user *data)
15902+{
15903+ struct vcmd_vhi_name_v0 vc_data;
15904+ char *name;
d337f35e 15905+
4bf69007
AM
15906+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15907+ return -EFAULT;
d337f35e 15908+
4bf69007
AM
15909+ name = vx_vhi_name(vxi, vc_data.field);
15910+ if (!name)
15911+ return -EINVAL;
d337f35e 15912+
4bf69007
AM
15913+ memcpy(vc_data.name, name, 65);
15914+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15915+ return -EFAULT;
15916+ return 0;
15917+}
d337f35e 15918+
d337f35e 15919+
4bf69007
AM
15920+int vc_virt_stat(struct vx_info *vxi, void __user *data)
15921+{
15922+ struct vcmd_virt_stat_v0 vc_data;
15923+ struct _vx_cvirt *cvirt = &vxi->cvirt;
cc23e853 15924+ struct timespec64 uptime;
99a884b4 15925+
369dbd59
AM
15926+ ktime_get_ts64(&uptime);
15927+ set_normalized_timespec64(&uptime,
4bf69007
AM
15928+ uptime.tv_sec - cvirt->bias_uptime.tv_sec,
15929+ uptime.tv_nsec - cvirt->bias_uptime.tv_nsec);
d337f35e 15930+
cc23e853
AM
15931+ vc_data.offset = timespec64_to_ns(&cvirt->bias_ts);
15932+ vc_data.uptime = timespec64_to_ns(&uptime);
4bf69007
AM
15933+ vc_data.nr_threads = atomic_read(&cvirt->nr_threads);
15934+ vc_data.nr_running = atomic_read(&cvirt->nr_running);
15935+ vc_data.nr_uninterruptible = atomic_read(&cvirt->nr_uninterruptible);
15936+ vc_data.nr_onhold = atomic_read(&cvirt->nr_onhold);
15937+ vc_data.nr_forks = atomic_read(&cvirt->total_forks);
15938+ vc_data.load[0] = cvirt->load[0];
15939+ vc_data.load[1] = cvirt->load[1];
15940+ vc_data.load[2] = cvirt->load[2];
15941+
15942+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15943+ return -EFAULT;
15944+ return 0;
d337f35e
JR
15945+}
15946+
15947+
4bf69007
AM
15948+#ifdef CONFIG_VSERVER_VTIME
15949+
15950+/* virtualized time base */
15951+
15952+void vx_adjust_timespec(struct timespec *ts)
d337f35e 15953+{
4bf69007 15954+ struct vx_info *vxi;
d337f35e 15955+
4bf69007
AM
15956+ if (!vx_flags(VXF_VIRT_TIME, 0))
15957+ return;
d337f35e 15958+
4bf69007
AM
15959+ vxi = current_vx_info();
15960+ ts->tv_sec += vxi->cvirt.bias_ts.tv_sec;
15961+ ts->tv_nsec += vxi->cvirt.bias_ts.tv_nsec;
d337f35e 15962+
4bf69007
AM
15963+ if (ts->tv_nsec >= NSEC_PER_SEC) {
15964+ ts->tv_sec++;
15965+ ts->tv_nsec -= NSEC_PER_SEC;
15966+ } else if (ts->tv_nsec < 0) {
15967+ ts->tv_sec--;
15968+ ts->tv_nsec += NSEC_PER_SEC;
d337f35e 15969+ }
d337f35e
JR
15970+}
15971+
cc23e853
AM
15972+void vx_adjust_timespec64(struct timespec64 *ts)
15973+{
15974+ struct vx_info *vxi;
15975+
15976+ if (!vx_flags(VXF_VIRT_TIME, 0))
15977+ return;
15978+
15979+ vxi = current_vx_info();
15980+ ts->tv_sec += vxi->cvirt.bias_ts.tv_sec;
15981+ ts->tv_nsec += vxi->cvirt.bias_ts.tv_nsec;
15982+
15983+ if (ts->tv_nsec >= NSEC_PER_SEC) {
15984+ ts->tv_sec++;
15985+ ts->tv_nsec -= NSEC_PER_SEC;
15986+ } else if (ts->tv_nsec < 0) {
15987+ ts->tv_sec--;
15988+ ts->tv_nsec += NSEC_PER_SEC;
15989+ }
15990+}
15991+
4bf69007 15992+int vx_settimeofday(const struct timespec *ts)
99a884b4 15993+{
4bf69007
AM
15994+ struct timespec ats, delta;
15995+ struct vx_info *vxi;
99a884b4 15996+
4bf69007
AM
15997+ if (!vx_flags(VXF_VIRT_TIME, 0))
15998+ return do_settimeofday(ts);
99a884b4 15999+
4bf69007
AM
16000+ getnstimeofday(&ats);
16001+ delta = timespec_sub(*ts, ats);
99a884b4 16002+
4bf69007 16003+ vxi = current_vx_info();
cc23e853
AM
16004+ vxi->cvirt.bias_ts = timespec64_add(vxi->cvirt.bias_ts,
16005+ timespec_to_timespec64(delta));
16006+ return 0;
16007+}
16008+
16009+int vx_settimeofday64(const struct timespec64 *ts)
16010+{
16011+ struct timespec64 ats, delta;
16012+ struct vx_info *vxi;
16013+
16014+ if (!vx_flags(VXF_VIRT_TIME, 0))
16015+ return do_settimeofday64(ts);
16016+
16017+ getnstimeofday64(&ats);
16018+ delta = timespec64_sub(*ts, ats);
16019+
16020+ vxi = current_vx_info();
16021+ vxi->cvirt.bias_ts = timespec64_add(vxi->cvirt.bias_ts, delta);
99a884b4
AM
16022+ return 0;
16023+}
d337f35e 16024+
4bf69007 16025+#endif
d337f35e 16026+
cef7ea10
AM
16027diff -NurpP --minimal linux-4.9.82/kernel/vserver/cvirt_init.h linux-4.9.82-vs2.3.9.7/kernel/vserver/cvirt_init.h
16028--- linux-4.9.82/kernel/vserver/cvirt_init.h 1970-01-01 00:00:00.000000000 +0000
16029+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/cvirt_init.h 2018-01-11 08:38:34.000000000 +0000
4bf69007 16030@@ -0,0 +1,70 @@
d337f35e 16031+
d337f35e 16032+
4bf69007 16033+extern uint64_t vx_idle_jiffies(void);
d337f35e 16034+
4bf69007
AM
16035+static inline void vx_info_init_cvirt(struct _vx_cvirt *cvirt)
16036+{
16037+ uint64_t idle_jiffies = vx_idle_jiffies();
16038+ uint64_t nsuptime;
d337f35e 16039+
cc23e853 16040+ ktime_get_ts64(&cvirt->bias_uptime);
4bf69007
AM
16041+ nsuptime = (unsigned long long)cvirt->bias_uptime.tv_sec
16042+ * NSEC_PER_SEC + cvirt->bias_uptime.tv_nsec;
16043+ cvirt->bias_clock = nsec_to_clock_t(nsuptime);
16044+ cvirt->bias_ts.tv_sec = 0;
16045+ cvirt->bias_ts.tv_nsec = 0;
d337f35e 16046+
cc23e853 16047+ jiffies_to_timespec64(idle_jiffies, &cvirt->bias_idle);
4bf69007
AM
16048+ atomic_set(&cvirt->nr_threads, 0);
16049+ atomic_set(&cvirt->nr_running, 0);
16050+ atomic_set(&cvirt->nr_uninterruptible, 0);
16051+ atomic_set(&cvirt->nr_onhold, 0);
d337f35e 16052+
4bf69007
AM
16053+ spin_lock_init(&cvirt->load_lock);
16054+ cvirt->load_last = jiffies;
16055+ atomic_set(&cvirt->load_updates, 0);
16056+ cvirt->load[0] = 0;
16057+ cvirt->load[1] = 0;
16058+ cvirt->load[2] = 0;
16059+ atomic_set(&cvirt->total_forks, 0);
d337f35e 16060+
4bf69007
AM
16061+ spin_lock_init(&cvirt->syslog.logbuf_lock);
16062+ init_waitqueue_head(&cvirt->syslog.log_wait);
16063+ cvirt->syslog.log_start = 0;
16064+ cvirt->syslog.log_end = 0;
16065+ cvirt->syslog.con_start = 0;
16066+ cvirt->syslog.logged_chars = 0;
16067+}
16068+
16069+static inline
16070+void vx_info_init_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
d337f35e 16071+{
4bf69007
AM
16072+ // cvirt_pc->cpustat = { 0 };
16073+}
d337f35e 16074+
4bf69007
AM
16075+static inline void vx_info_exit_cvirt(struct _vx_cvirt *cvirt)
16076+{
16077+#ifdef CONFIG_VSERVER_WARN
16078+ int value;
16079+#endif
16080+ vxwprintk_xid((value = atomic_read(&cvirt->nr_threads)),
16081+ "!!! cvirt: %p[nr_threads] = %d on exit.",
16082+ cvirt, value);
16083+ vxwprintk_xid((value = atomic_read(&cvirt->nr_running)),
16084+ "!!! cvirt: %p[nr_running] = %d on exit.",
16085+ cvirt, value);
16086+ vxwprintk_xid((value = atomic_read(&cvirt->nr_uninterruptible)),
16087+ "!!! cvirt: %p[nr_uninterruptible] = %d on exit.",
16088+ cvirt, value);
16089+ vxwprintk_xid((value = atomic_read(&cvirt->nr_onhold)),
16090+ "!!! cvirt: %p[nr_onhold] = %d on exit.",
16091+ cvirt, value);
16092+ return;
16093+}
d337f35e 16094+
4bf69007
AM
16095+static inline
16096+void vx_info_exit_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
16097+{
16098+ return;
16099+}
d337f35e 16100+
cef7ea10
AM
16101diff -NurpP --minimal linux-4.9.82/kernel/vserver/cvirt_proc.h linux-4.9.82-vs2.3.9.7/kernel/vserver/cvirt_proc.h
16102--- linux-4.9.82/kernel/vserver/cvirt_proc.h 1970-01-01 00:00:00.000000000 +0000
16103+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/cvirt_proc.h 2018-01-11 08:39:19.000000000 +0000
4bf69007
AM
16104@@ -0,0 +1,123 @@
16105+#ifndef _VX_CVIRT_PROC_H
16106+#define _VX_CVIRT_PROC_H
d337f35e 16107+
4bf69007
AM
16108+#include <linux/nsproxy.h>
16109+#include <linux/mnt_namespace.h>
16110+#include <linux/ipc_namespace.h>
16111+#include <linux/utsname.h>
16112+#include <linux/ipc.h>
d337f35e 16113+
4bf69007 16114+extern int vx_info_mnt_namespace(struct mnt_namespace *, char *);
d337f35e 16115+
4bf69007
AM
16116+static inline
16117+int vx_info_proc_nsproxy(struct nsproxy *nsproxy, char *buffer)
16118+{
16119+ struct mnt_namespace *ns;
16120+ struct uts_namespace *uts;
16121+ struct ipc_namespace *ipc;
16122+ int length = 0;
d337f35e 16123+
4bf69007
AM
16124+ if (!nsproxy)
16125+ goto out;
d337f35e 16126+
4bf69007
AM
16127+ length += sprintf(buffer + length,
16128+ "NSProxy:\t%p [%p,%p,%p]\n",
16129+ nsproxy, nsproxy->mnt_ns,
16130+ nsproxy->uts_ns, nsproxy->ipc_ns);
d337f35e 16131+
4bf69007
AM
16132+ ns = nsproxy->mnt_ns;
16133+ if (!ns)
16134+ goto skip_ns;
d337f35e 16135+
4bf69007 16136+ length += vx_info_mnt_namespace(ns, buffer + length);
d337f35e 16137+
4bf69007 16138+skip_ns:
d337f35e 16139+
4bf69007
AM
16140+ uts = nsproxy->uts_ns;
16141+ if (!uts)
16142+ goto skip_uts;
d337f35e 16143+
4bf69007
AM
16144+ length += sprintf(buffer + length,
16145+ "SysName:\t%.*s\n"
16146+ "NodeName:\t%.*s\n"
16147+ "Release:\t%.*s\n"
16148+ "Version:\t%.*s\n"
16149+ "Machine:\t%.*s\n"
16150+ "DomainName:\t%.*s\n",
16151+ __NEW_UTS_LEN, uts->name.sysname,
16152+ __NEW_UTS_LEN, uts->name.nodename,
16153+ __NEW_UTS_LEN, uts->name.release,
16154+ __NEW_UTS_LEN, uts->name.version,
16155+ __NEW_UTS_LEN, uts->name.machine,
16156+ __NEW_UTS_LEN, uts->name.domainname);
16157+skip_uts:
d337f35e 16158+
4bf69007
AM
16159+ ipc = nsproxy->ipc_ns;
16160+ if (!ipc)
16161+ goto skip_ipc;
d337f35e 16162+
4bf69007
AM
16163+ length += sprintf(buffer + length,
16164+ "SEMS:\t\t%d %d %d %d %d\n"
16165+ "MSG:\t\t%d %d %d\n"
b00e13aa 16166+ "SHM:\t\t%lu %lu %d %ld\n",
4bf69007
AM
16167+ ipc->sem_ctls[0], ipc->sem_ctls[1],
16168+ ipc->sem_ctls[2], ipc->sem_ctls[3],
16169+ ipc->used_sems,
16170+ ipc->msg_ctlmax, ipc->msg_ctlmnb, ipc->msg_ctlmni,
16171+ (unsigned long)ipc->shm_ctlmax,
16172+ (unsigned long)ipc->shm_ctlall,
16173+ ipc->shm_ctlmni, ipc->shm_tot);
16174+skip_ipc:
16175+out:
16176+ return length;
16177+}
d337f35e
JR
16178+
16179+
4bf69007 16180+#include <linux/sched.h>
d337f35e 16181+
4bf69007
AM
16182+#define LOAD_INT(x) ((x) >> FSHIFT)
16183+#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1 - 1)) * 100)
d337f35e 16184+
4bf69007
AM
16185+static inline
16186+int vx_info_proc_cvirt(struct _vx_cvirt *cvirt, char *buffer)
d337f35e 16187+{
4bf69007
AM
16188+ int length = 0;
16189+ int a, b, c;
d337f35e 16190+
4bf69007 16191+ length += sprintf(buffer + length,
cc23e853
AM
16192+ "BiasUptime:\t%llu.%02lu\n",
16193+ (unsigned long long)cvirt->bias_uptime.tv_sec,
4bf69007 16194+ (cvirt->bias_uptime.tv_nsec / (NSEC_PER_SEC / 100)));
d337f35e 16195+
4bf69007
AM
16196+ a = cvirt->load[0] + (FIXED_1 / 200);
16197+ b = cvirt->load[1] + (FIXED_1 / 200);
16198+ c = cvirt->load[2] + (FIXED_1 / 200);
16199+ length += sprintf(buffer + length,
16200+ "nr_threads:\t%d\n"
16201+ "nr_running:\t%d\n"
16202+ "nr_unintr:\t%d\n"
16203+ "nr_onhold:\t%d\n"
16204+ "load_updates:\t%d\n"
16205+ "loadavg:\t%d.%02d %d.%02d %d.%02d\n"
16206+ "total_forks:\t%d\n",
16207+ atomic_read(&cvirt->nr_threads),
16208+ atomic_read(&cvirt->nr_running),
16209+ atomic_read(&cvirt->nr_uninterruptible),
16210+ atomic_read(&cvirt->nr_onhold),
16211+ atomic_read(&cvirt->load_updates),
16212+ LOAD_INT(a), LOAD_FRAC(a),
16213+ LOAD_INT(b), LOAD_FRAC(b),
16214+ LOAD_INT(c), LOAD_FRAC(c),
16215+ atomic_read(&cvirt->total_forks));
16216+ return length;
d337f35e
JR
16217+}
16218+
4bf69007
AM
16219+static inline
16220+int vx_info_proc_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc,
16221+ char *buffer, int cpu)
16222+{
16223+ int length = 0;
16224+ return length;
16225+}
d337f35e 16226+
4bf69007 16227+#endif /* _VX_CVIRT_PROC_H */
cef7ea10
AM
16228diff -NurpP --minimal linux-4.9.82/kernel/vserver/debug.c linux-4.9.82-vs2.3.9.7/kernel/vserver/debug.c
16229--- linux-4.9.82/kernel/vserver/debug.c 1970-01-01 00:00:00.000000000 +0000
16230+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/debug.c 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
16231@@ -0,0 +1,32 @@
16232+/*
16233+ * kernel/vserver/debug.c
16234+ *
cc23e853 16235+ * Copyright (C) 2005-2007 Herbert P?tzl
4bf69007
AM
16236+ *
16237+ * V0.01 vx_info dump support
16238+ *
16239+ */
d337f35e 16240+
4bf69007 16241+#include <linux/module.h>
d337f35e 16242+
4bf69007 16243+#include <linux/vserver/context.h>
d337f35e 16244+
d337f35e 16245+
4bf69007 16246+void dump_vx_info(struct vx_info *vxi, int level)
d337f35e 16247+{
4bf69007
AM
16248+ printk("vx_info %p[#%d, %d.%d, %4x]\n", vxi, vxi->vx_id,
16249+ atomic_read(&vxi->vx_usecnt),
16250+ atomic_read(&vxi->vx_tasks),
16251+ vxi->vx_state);
16252+ if (level > 0) {
16253+ __dump_vx_limit(&vxi->limit);
16254+ __dump_vx_sched(&vxi->sched);
16255+ __dump_vx_cvirt(&vxi->cvirt);
16256+ __dump_vx_cacct(&vxi->cacct);
16257+ }
16258+ printk("---\n");
16259+}
d337f35e 16260+
d337f35e 16261+
4bf69007 16262+EXPORT_SYMBOL_GPL(dump_vx_info);
d337f35e 16263+
cef7ea10
AM
16264diff -NurpP --minimal linux-4.9.82/kernel/vserver/device.c linux-4.9.82-vs2.3.9.7/kernel/vserver/device.c
16265--- linux-4.9.82/kernel/vserver/device.c 1970-01-01 00:00:00.000000000 +0000
16266+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/device.c 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
16267@@ -0,0 +1,443 @@
16268+/*
16269+ * linux/kernel/vserver/device.c
16270+ *
16271+ * Linux-VServer: Device Support
16272+ *
cc23e853 16273+ * Copyright (C) 2006 Herbert P?tzl
4bf69007
AM
16274+ * Copyright (C) 2007 Daniel Hokka Zakrisson
16275+ *
16276+ * V0.01 device mapping basics
16277+ * V0.02 added defaults
16278+ *
16279+ */
d337f35e 16280+
4bf69007
AM
16281+#include <linux/slab.h>
16282+#include <linux/rcupdate.h>
16283+#include <linux/fs.h>
16284+#include <linux/namei.h>
16285+#include <linux/hash.h>
d337f35e 16286+
4bf69007
AM
16287+#include <asm/errno.h>
16288+#include <asm/uaccess.h>
16289+#include <linux/vserver/base.h>
16290+#include <linux/vserver/debug.h>
16291+#include <linux/vserver/context.h>
16292+#include <linux/vserver/device.h>
16293+#include <linux/vserver/device_cmd.h>
d337f35e 16294+
d337f35e 16295+
4bf69007 16296+#define DMAP_HASH_BITS 4
d337f35e 16297+
d337f35e 16298+
4bf69007
AM
16299+struct vs_mapping {
16300+ union {
16301+ struct hlist_node hlist;
16302+ struct list_head list;
16303+ } u;
16304+#define dm_hlist u.hlist
16305+#define dm_list u.list
61333608 16306+ vxid_t xid;
4bf69007
AM
16307+ dev_t device;
16308+ struct vx_dmap_target target;
16309+};
d337f35e 16310+
d337f35e 16311+
4bf69007 16312+static struct hlist_head dmap_main_hash[1 << DMAP_HASH_BITS];
d337f35e 16313+
4bf69007 16314+static DEFINE_SPINLOCK(dmap_main_hash_lock);
d337f35e 16315+
4bf69007
AM
16316+static struct vx_dmap_target dmap_defaults[2] = {
16317+ { .flags = DATTR_OPEN },
16318+ { .flags = DATTR_OPEN },
16319+};
d337f35e
JR
16320+
16321+
4bf69007 16322+struct kmem_cache *dmap_cachep __read_mostly;
d337f35e 16323+
4bf69007
AM
16324+int __init dmap_cache_init(void)
16325+{
16326+ dmap_cachep = kmem_cache_create("dmap_cache",
16327+ sizeof(struct vs_mapping), 0,
16328+ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
d337f35e
JR
16329+ return 0;
16330+}
16331+
4bf69007 16332+__initcall(dmap_cache_init);
d337f35e 16333+
4bf69007
AM
16334+
16335+static inline unsigned int __hashval(dev_t dev, int bits)
d337f35e 16336+{
4bf69007
AM
16337+ return hash_long((unsigned long)dev, bits);
16338+}
d337f35e 16339+
d337f35e 16340+
4bf69007
AM
16341+/* __hash_mapping()
16342+ * add the mapping to the hash table
16343+ */
16344+static inline void __hash_mapping(struct vx_info *vxi, struct vs_mapping *vdm)
16345+{
16346+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16347+ struct hlist_head *head, *hash = dmap_main_hash;
16348+ int device = vdm->device;
d337f35e 16349+
4bf69007
AM
16350+ spin_lock(hash_lock);
16351+ vxdprintk(VXD_CBIT(misc, 8), "__hash_mapping: %p[#%d] %08x:%08x",
16352+ vxi, vxi ? vxi->vx_id : 0, device, vdm->target.target);
d337f35e 16353+
4bf69007
AM
16354+ head = &hash[__hashval(device, DMAP_HASH_BITS)];
16355+ hlist_add_head(&vdm->dm_hlist, head);
16356+ spin_unlock(hash_lock);
16357+}
16358+
16359+
16360+static inline int __mode_to_default(umode_t mode)
16361+{
16362+ switch (mode) {
16363+ case S_IFBLK:
16364+ return 0;
16365+ case S_IFCHR:
16366+ return 1;
16367+ default:
16368+ BUG();
d337f35e 16369+ }
d337f35e
JR
16370+}
16371+
4bf69007
AM
16372+
16373+/* __set_default()
16374+ * set a default
16375+ */
16376+static inline void __set_default(struct vx_info *vxi, umode_t mode,
16377+ struct vx_dmap_target *vdmt)
d337f35e 16378+{
4bf69007
AM
16379+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16380+ spin_lock(hash_lock);
d337f35e 16381+
4bf69007
AM
16382+ if (vxi)
16383+ vxi->dmap.targets[__mode_to_default(mode)] = *vdmt;
16384+ else
16385+ dmap_defaults[__mode_to_default(mode)] = *vdmt;
d337f35e 16386+
d337f35e 16387+
4bf69007 16388+ spin_unlock(hash_lock);
d337f35e 16389+
4bf69007
AM
16390+ vxdprintk(VXD_CBIT(misc, 8), "__set_default: %p[#%u] %08x %04x",
16391+ vxi, vxi ? vxi->vx_id : 0, vdmt->target, vdmt->flags);
d337f35e
JR
16392+}
16393+
d337f35e 16394+
4bf69007
AM
16395+/* __remove_default()
16396+ * remove a default
16397+ */
16398+static inline int __remove_default(struct vx_info *vxi, umode_t mode)
d337f35e 16399+{
4bf69007
AM
16400+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16401+ spin_lock(hash_lock);
d337f35e 16402+
4bf69007
AM
16403+ if (vxi)
16404+ vxi->dmap.targets[__mode_to_default(mode)].flags = 0;
16405+ else /* remove == reset */
16406+ dmap_defaults[__mode_to_default(mode)].flags = DATTR_OPEN | mode;
d337f35e 16407+
4bf69007
AM
16408+ spin_unlock(hash_lock);
16409+ return 0;
d337f35e
JR
16410+}
16411+
d337f35e 16412+
4bf69007
AM
16413+/* __find_mapping()
16414+ * find a mapping in the hash table
16415+ *
16416+ * caller must hold hash_lock
16417+ */
61333608 16418+static inline int __find_mapping(vxid_t xid, dev_t device, umode_t mode,
4bf69007
AM
16419+ struct vs_mapping **local, struct vs_mapping **global)
16420+{
16421+ struct hlist_head *hash = dmap_main_hash;
16422+ struct hlist_head *head = &hash[__hashval(device, DMAP_HASH_BITS)];
16423+ struct hlist_node *pos;
16424+ struct vs_mapping *vdm;
d337f35e 16425+
4bf69007
AM
16426+ *local = NULL;
16427+ if (global)
16428+ *global = NULL;
d337f35e 16429+
4bf69007
AM
16430+ hlist_for_each(pos, head) {
16431+ vdm = hlist_entry(pos, struct vs_mapping, dm_hlist);
d337f35e 16432+
4bf69007
AM
16433+ if ((vdm->device == device) &&
16434+ !((vdm->target.flags ^ mode) & S_IFMT)) {
16435+ if (vdm->xid == xid) {
16436+ *local = vdm;
16437+ return 1;
16438+ } else if (global && vdm->xid == 0)
16439+ *global = vdm;
2380c486
JR
16440+ }
16441+ }
16442+
4bf69007
AM
16443+ if (global && *global)
16444+ return 0;
16445+ else
16446+ return -ENOENT;
2380c486
JR
16447+}
16448+
16449+
4bf69007
AM
16450+/* __lookup_mapping()
16451+ * find a mapping and store the result in target and flags
16452+ */
16453+static inline int __lookup_mapping(struct vx_info *vxi,
16454+ dev_t device, dev_t *target, int *flags, umode_t mode)
2380c486 16455+{
4bf69007
AM
16456+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16457+ struct vs_mapping *vdm, *global;
16458+ struct vx_dmap_target *vdmt;
2380c486 16459+ int ret = 0;
61333608 16460+ vxid_t xid = vxi->vx_id;
4bf69007 16461+ int index;
2380c486 16462+
4bf69007
AM
16463+ spin_lock(hash_lock);
16464+ if (__find_mapping(xid, device, mode, &vdm, &global) > 0) {
2380c486 16465+ ret = 1;
4bf69007
AM
16466+ vdmt = &vdm->target;
16467+ goto found;
16468+ }
2380c486 16469+
4bf69007
AM
16470+ index = __mode_to_default(mode);
16471+ if (vxi && vxi->dmap.targets[index].flags) {
16472+ ret = 2;
16473+ vdmt = &vxi->dmap.targets[index];
16474+ } else if (global) {
16475+ ret = 3;
16476+ vdmt = &global->target;
16477+ goto found;
16478+ } else {
16479+ ret = 4;
16480+ vdmt = &dmap_defaults[index];
d337f35e 16481+ }
2380c486 16482+
4bf69007
AM
16483+found:
16484+ if (target && (vdmt->flags & DATTR_REMAP))
16485+ *target = vdmt->target;
16486+ else if (target)
16487+ *target = device;
16488+ if (flags)
16489+ *flags = vdmt->flags;
16490+
16491+ spin_unlock(hash_lock);
2380c486
JR
16492+
16493+ return ret;
d337f35e
JR
16494+}
16495+
16496+
4bf69007
AM
16497+/* __remove_mapping()
16498+ * remove a mapping from the hash table
16499+ */
16500+static inline int __remove_mapping(struct vx_info *vxi, dev_t device,
16501+ umode_t mode)
d337f35e 16502+{
4bf69007
AM
16503+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16504+ struct vs_mapping *vdm = NULL;
d337f35e
JR
16505+ int ret = 0;
16506+
4bf69007
AM
16507+ spin_lock(hash_lock);
16508+
16509+ ret = __find_mapping((vxi ? vxi->vx_id : 0), device, mode, &vdm,
16510+ NULL);
16511+ vxdprintk(VXD_CBIT(misc, 8), "__remove_mapping: %p[#%d] %08x %04x",
16512+ vxi, vxi ? vxi->vx_id : 0, device, mode);
16513+ if (ret < 0)
2380c486 16514+ goto out;
4bf69007 16515+ hlist_del(&vdm->dm_hlist);
2380c486 16516+
2380c486 16517+out:
4bf69007
AM
16518+ spin_unlock(hash_lock);
16519+ if (vdm)
16520+ kmem_cache_free(dmap_cachep, vdm);
2380c486
JR
16521+ return ret;
16522+}
16523+
16524+
2380c486 16525+
4bf69007
AM
16526+int vs_map_device(struct vx_info *vxi,
16527+ dev_t device, dev_t *target, umode_t mode)
2380c486 16528+{
4bf69007 16529+ int ret, flags = DATTR_MASK;
2380c486 16530+
4bf69007
AM
16531+ if (!vxi) {
16532+ if (target)
16533+ *target = device;
2380c486 16534+ goto out;
2380c486 16535+ }
4bf69007
AM
16536+ ret = __lookup_mapping(vxi, device, target, &flags, mode);
16537+ vxdprintk(VXD_CBIT(misc, 8), "vs_map_device: %08x target: %08x flags: %04x mode: %04x mapped=%d",
16538+ device, target ? *target : 0, flags, mode, ret);
2380c486 16539+out:
4bf69007 16540+ return (flags & DATTR_MASK);
2380c486
JR
16541+}
16542+
2380c486 16543+
4bf69007
AM
16544+
16545+static int do_set_mapping(struct vx_info *vxi,
16546+ dev_t device, dev_t target, int flags, umode_t mode)
2380c486 16547+{
4bf69007
AM
16548+ if (device) {
16549+ struct vs_mapping *new;
2380c486 16550+
4bf69007
AM
16551+ new = kmem_cache_alloc(dmap_cachep, GFP_KERNEL);
16552+ if (!new)
16553+ return -ENOMEM;
16554+
16555+ INIT_HLIST_NODE(&new->dm_hlist);
16556+ new->device = device;
16557+ new->target.target = target;
16558+ new->target.flags = flags | mode;
16559+ new->xid = (vxi ? vxi->vx_id : 0);
16560+
16561+ vxdprintk(VXD_CBIT(misc, 8), "do_set_mapping: %08x target: %08x flags: %04x", device, target, flags);
16562+ __hash_mapping(vxi, new);
16563+ } else {
16564+ struct vx_dmap_target new = {
16565+ .target = target,
16566+ .flags = flags | mode,
16567+ };
16568+ __set_default(vxi, mode, &new);
16569+ }
16570+ return 0;
2380c486
JR
16571+}
16572+
4bf69007
AM
16573+
16574+static int do_unset_mapping(struct vx_info *vxi,
16575+ dev_t device, dev_t target, int flags, umode_t mode)
2380c486 16576+{
4bf69007 16577+ int ret = -EINVAL;
763640ca 16578+
4bf69007
AM
16579+ if (device) {
16580+ ret = __remove_mapping(vxi, device, mode);
16581+ if (ret < 0)
16582+ goto out;
16583+ } else {
16584+ ret = __remove_default(vxi, mode);
16585+ if (ret < 0)
16586+ goto out;
16587+ }
2380c486 16588+
4bf69007
AM
16589+out:
16590+ return ret;
16591+}
2380c486 16592+
2380c486 16593+
4bf69007
AM
16594+static inline int __user_device(const char __user *name, dev_t *dev,
16595+ umode_t *mode)
16596+{
cc23e853 16597+ struct path path;
4bf69007 16598+ int ret;
2380c486 16599+
4bf69007
AM
16600+ if (!name) {
16601+ *dev = 0;
16602+ return 0;
16603+ }
cc23e853 16604+ ret = user_lpath(name, &path);
4bf69007
AM
16605+ if (ret)
16606+ return ret;
cc23e853
AM
16607+ if (path.dentry->d_inode) {
16608+ *dev = path.dentry->d_inode->i_rdev;
16609+ *mode = path.dentry->d_inode->i_mode;
4bf69007 16610+ }
cc23e853 16611+ path_put(&path);
4bf69007
AM
16612+ return 0;
16613+}
2380c486 16614+
4bf69007
AM
16615+static inline int __mapping_mode(dev_t device, dev_t target,
16616+ umode_t device_mode, umode_t target_mode, umode_t *mode)
16617+{
16618+ if (device)
16619+ *mode = device_mode & S_IFMT;
16620+ else if (target)
16621+ *mode = target_mode & S_IFMT;
16622+ else
16623+ return -EINVAL;
2380c486 16624+
4bf69007
AM
16625+ /* if both given, device and target mode have to match */
16626+ if (device && target &&
16627+ ((device_mode ^ target_mode) & S_IFMT))
16628+ return -EINVAL;
16629+ return 0;
16630+}
d337f35e 16631+
d337f35e 16632+
4bf69007
AM
16633+static inline int do_mapping(struct vx_info *vxi, const char __user *device_path,
16634+ const char __user *target_path, int flags, int set)
16635+{
16636+ dev_t device = ~0, target = ~0;
16637+ umode_t device_mode = 0, target_mode = 0, mode;
16638+ int ret;
2380c486 16639+
4bf69007
AM
16640+ ret = __user_device(device_path, &device, &device_mode);
16641+ if (ret)
16642+ return ret;
16643+ ret = __user_device(target_path, &target, &target_mode);
16644+ if (ret)
16645+ return ret;
2380c486 16646+
4bf69007
AM
16647+ ret = __mapping_mode(device, target,
16648+ device_mode, target_mode, &mode);
16649+ if (ret)
16650+ return ret;
2380c486 16651+
4bf69007
AM
16652+ if (set)
16653+ return do_set_mapping(vxi, device, target,
16654+ flags, mode);
16655+ else
16656+ return do_unset_mapping(vxi, device, target,
16657+ flags, mode);
d337f35e
JR
16658+}
16659+
d337f35e 16660+
4bf69007
AM
16661+int vc_set_mapping(struct vx_info *vxi, void __user *data)
16662+{
16663+ struct vcmd_set_mapping_v0 vc_data;
d337f35e 16664+
4bf69007
AM
16665+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16666+ return -EFAULT;
d337f35e 16667+
4bf69007
AM
16668+ return do_mapping(vxi, vc_data.device, vc_data.target,
16669+ vc_data.flags, 1);
16670+}
d337f35e 16671+
4bf69007 16672+int vc_unset_mapping(struct vx_info *vxi, void __user *data)
d337f35e 16673+{
4bf69007 16674+ struct vcmd_set_mapping_v0 vc_data;
d337f35e 16675+
4bf69007
AM
16676+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16677+ return -EFAULT;
16678+
16679+ return do_mapping(vxi, vc_data.device, vc_data.target,
16680+ vc_data.flags, 0);
d337f35e
JR
16681+}
16682+
16683+
4bf69007
AM
16684+#ifdef CONFIG_COMPAT
16685+
16686+int vc_set_mapping_x32(struct vx_info *vxi, void __user *data)
d337f35e 16687+{
4bf69007 16688+ struct vcmd_set_mapping_v0_x32 vc_data;
d337f35e 16689+
4bf69007
AM
16690+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16691+ return -EFAULT;
16692+
16693+ return do_mapping(vxi, compat_ptr(vc_data.device_ptr),
16694+ compat_ptr(vc_data.target_ptr), vc_data.flags, 1);
d337f35e
JR
16695+}
16696+
4bf69007
AM
16697+int vc_unset_mapping_x32(struct vx_info *vxi, void __user *data)
16698+{
16699+ struct vcmd_set_mapping_v0_x32 vc_data;
16700+
16701+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16702+ return -EFAULT;
d337f35e 16703+
4bf69007
AM
16704+ return do_mapping(vxi, compat_ptr(vc_data.device_ptr),
16705+ compat_ptr(vc_data.target_ptr), vc_data.flags, 0);
16706+}
d337f35e 16707+
4bf69007 16708+#endif /* CONFIG_COMPAT */
d337f35e 16709+
4bf69007 16710+
cef7ea10
AM
16711diff -NurpP --minimal linux-4.9.82/kernel/vserver/dlimit.c linux-4.9.82-vs2.3.9.7/kernel/vserver/dlimit.c
16712--- linux-4.9.82/kernel/vserver/dlimit.c 1970-01-01 00:00:00.000000000 +0000
16713+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/dlimit.c 2018-01-10 02:50:49.000000000 +0000
b00e13aa 16714@@ -0,0 +1,528 @@
d337f35e 16715+/*
4bf69007 16716+ * linux/kernel/vserver/dlimit.c
d337f35e 16717+ *
4bf69007 16718+ * Virtual Server: Context Disk Limits
d337f35e 16719+ *
cc23e853 16720+ * Copyright (C) 2004-2009 Herbert P?tzl
d337f35e 16721+ *
4bf69007
AM
16722+ * V0.01 initial version
16723+ * V0.02 compat32 splitup
16724+ * V0.03 extended interface
d337f35e
JR
16725+ *
16726+ */
16727+
4bf69007
AM
16728+#include <linux/statfs.h>
16729+#include <linux/sched.h>
2380c486 16730+#include <linux/namei.h>
d337f35e 16731+#include <linux/vs_tag.h>
4bf69007
AM
16732+#include <linux/vs_dlimit.h>
16733+#include <linux/vserver/dlimit_cmd.h>
16734+#include <linux/slab.h>
16735+// #include <linux/gfp.h>
d337f35e 16736+
d337f35e
JR
16737+#include <asm/uaccess.h>
16738+
4bf69007 16739+/* __alloc_dl_info()
d337f35e 16740+
4bf69007
AM
16741+ * allocate an initialized dl_info struct
16742+ * doesn't make it visible (hash) */
d337f35e 16743+
61333608 16744+static struct dl_info *__alloc_dl_info(struct super_block *sb, vtag_t tag)
4bf69007
AM
16745+{
16746+ struct dl_info *new = NULL;
d337f35e 16747+
4bf69007
AM
16748+ vxdprintk(VXD_CBIT(dlim, 5),
16749+ "alloc_dl_info(%p,%d)*", sb, tag);
d337f35e 16750+
4bf69007
AM
16751+ /* would this benefit from a slab cache? */
16752+ new = kmalloc(sizeof(struct dl_info), GFP_KERNEL);
16753+ if (!new)
16754+ return 0;
d337f35e 16755+
4bf69007
AM
16756+ memset(new, 0, sizeof(struct dl_info));
16757+ new->dl_tag = tag;
16758+ new->dl_sb = sb;
16759+ // INIT_RCU_HEAD(&new->dl_rcu);
16760+ INIT_HLIST_NODE(&new->dl_hlist);
16761+ spin_lock_init(&new->dl_lock);
16762+ atomic_set(&new->dl_refcnt, 0);
16763+ atomic_set(&new->dl_usecnt, 0);
d337f35e 16764+
4bf69007 16765+ /* rest of init goes here */
d337f35e 16766+
4bf69007
AM
16767+ vxdprintk(VXD_CBIT(dlim, 4),
16768+ "alloc_dl_info(%p,%d) = %p", sb, tag, new);
16769+ return new;
16770+}
d4263eb0 16771+
4bf69007 16772+/* __dealloc_dl_info()
d337f35e 16773+
4bf69007 16774+ * final disposal of dl_info */
d337f35e 16775+
4bf69007 16776+static void __dealloc_dl_info(struct dl_info *dli)
adc1caaa 16777+{
4bf69007
AM
16778+ vxdprintk(VXD_CBIT(dlim, 4),
16779+ "dealloc_dl_info(%p)", dli);
2380c486 16780+
4bf69007
AM
16781+ dli->dl_hlist.next = LIST_POISON1;
16782+ dli->dl_tag = -1;
16783+ dli->dl_sb = 0;
2380c486 16784+
4bf69007
AM
16785+ BUG_ON(atomic_read(&dli->dl_usecnt));
16786+ BUG_ON(atomic_read(&dli->dl_refcnt));
2380c486 16787+
4bf69007 16788+ kfree(dli);
adc1caaa 16789+}
2380c486 16790+
2380c486 16791+
4bf69007 16792+/* hash table for dl_info hash */
2380c486 16793+
4bf69007 16794+#define DL_HASH_SIZE 13
2380c486 16795+
4bf69007 16796+struct hlist_head dl_info_hash[DL_HASH_SIZE];
2380c486 16797+
4bf69007 16798+static DEFINE_SPINLOCK(dl_info_hash_lock);
2380c486 16799+
d33d7b00 16800+
61333608 16801+static inline unsigned int __hashval(struct super_block *sb, vtag_t tag)
adc1caaa 16802+{
4bf69007
AM
16803+ return ((tag ^ (unsigned long)sb) % DL_HASH_SIZE);
16804+}
2380c486 16805+
2380c486 16806+
2380c486 16807+
4bf69007 16808+/* __hash_dl_info()
2380c486 16809+
4bf69007
AM
16810+ * add the dli to the global hash table
16811+ * requires the hash_lock to be held */
2380c486 16812+
4bf69007
AM
16813+static inline void __hash_dl_info(struct dl_info *dli)
16814+{
16815+ struct hlist_head *head;
d337f35e 16816+
4bf69007
AM
16817+ vxdprintk(VXD_CBIT(dlim, 6),
16818+ "__hash_dl_info: %p[#%d]", dli, dli->dl_tag);
16819+ get_dl_info(dli);
16820+ head = &dl_info_hash[__hashval(dli->dl_sb, dli->dl_tag)];
16821+ hlist_add_head_rcu(&dli->dl_hlist, head);
16822+}
d337f35e 16823+
4bf69007 16824+/* __unhash_dl_info()
3bac966d 16825+
4bf69007
AM
16826+ * remove the dli from the global hash table
16827+ * requires the hash_lock to be held */
3bac966d 16828+
4bf69007
AM
16829+static inline void __unhash_dl_info(struct dl_info *dli)
16830+{
16831+ vxdprintk(VXD_CBIT(dlim, 6),
16832+ "__unhash_dl_info: %p[#%d]", dli, dli->dl_tag);
16833+ hlist_del_rcu(&dli->dl_hlist);
16834+ put_dl_info(dli);
16835+}
3bac966d 16836+
3bac966d 16837+
4bf69007 16838+/* __lookup_dl_info()
3bac966d 16839+
4bf69007
AM
16840+ * requires the rcu_read_lock()
16841+ * doesn't increment the dl_refcnt */
3bac966d 16842+
61333608 16843+static inline struct dl_info *__lookup_dl_info(struct super_block *sb, vtag_t tag)
4bf69007
AM
16844+{
16845+ struct hlist_head *head = &dl_info_hash[__hashval(sb, tag)];
4bf69007 16846+ struct dl_info *dli;
3bac966d 16847+
b00e13aa
AM
16848+ hlist_for_each_entry_rcu(dli, head, dl_hlist) {
16849+ if (dli->dl_tag == tag && dli->dl_sb == sb)
4bf69007 16850+ return dli;
d33d7b00 16851+ }
4bf69007
AM
16852+ return NULL;
16853+}
3bac966d 16854+
3bac966d 16855+
61333608 16856+struct dl_info *locate_dl_info(struct super_block *sb, vtag_t tag)
4bf69007
AM
16857+{
16858+ struct dl_info *dli;
16859+
16860+ rcu_read_lock();
16861+ dli = get_dl_info(__lookup_dl_info(sb, tag));
16862+ vxdprintk(VXD_CBIT(dlim, 7),
16863+ "locate_dl_info(%p,#%d) = %p", sb, tag, dli);
16864+ rcu_read_unlock();
16865+ return dli;
d33d7b00 16866+}
3bac966d 16867+
4bf69007 16868+void rcu_free_dl_info(struct rcu_head *head)
d33d7b00 16869+{
4bf69007
AM
16870+ struct dl_info *dli = container_of(head, struct dl_info, dl_rcu);
16871+ int usecnt, refcnt;
3bac966d 16872+
4bf69007 16873+ BUG_ON(!dli || !head);
3bac966d 16874+
4bf69007
AM
16875+ usecnt = atomic_read(&dli->dl_usecnt);
16876+ BUG_ON(usecnt < 0);
3bac966d 16877+
4bf69007
AM
16878+ refcnt = atomic_read(&dli->dl_refcnt);
16879+ BUG_ON(refcnt < 0);
16880+
16881+ vxdprintk(VXD_CBIT(dlim, 3),
16882+ "rcu_free_dl_info(%p)", dli);
16883+ if (!usecnt)
16884+ __dealloc_dl_info(dli);
16885+ else
16886+ printk("!!! rcu didn't free\n");
d33d7b00 16887+}
3bac966d 16888+
3bac966d 16889+
4bf69007
AM
16890+
16891+
16892+static int do_addrem_dlimit(uint32_t id, const char __user *name,
16893+ uint32_t flags, int add)
d33d7b00
AM
16894+{
16895+ struct path path;
d33d7b00 16896+ int ret;
3bac966d 16897+
4bf69007 16898+ ret = user_lpath(name, &path);
d33d7b00 16899+ if (!ret) {
4bf69007
AM
16900+ struct super_block *sb;
16901+ struct dl_info *dli;
16902+
16903+ ret = -EINVAL;
16904+ if (!path.dentry->d_inode)
16905+ goto out_release;
16906+ if (!(sb = path.dentry->d_inode->i_sb))
16907+ goto out_release;
16908+
16909+ if (add) {
16910+ dli = __alloc_dl_info(sb, id);
16911+ spin_lock(&dl_info_hash_lock);
16912+
16913+ ret = -EEXIST;
16914+ if (__lookup_dl_info(sb, id))
16915+ goto out_unlock;
16916+ __hash_dl_info(dli);
16917+ dli = NULL;
16918+ } else {
16919+ spin_lock(&dl_info_hash_lock);
16920+ dli = __lookup_dl_info(sb, id);
16921+
16922+ ret = -ESRCH;
16923+ if (!dli)
16924+ goto out_unlock;
16925+ __unhash_dl_info(dli);
16926+ }
16927+ ret = 0;
16928+ out_unlock:
16929+ spin_unlock(&dl_info_hash_lock);
16930+ if (add && dli)
16931+ __dealloc_dl_info(dli);
16932+ out_release:
d33d7b00
AM
16933+ path_put(&path);
16934+ }
d33d7b00
AM
16935+ return ret;
16936+}
3bac966d 16937+
4bf69007 16938+int vc_add_dlimit(uint32_t id, void __user *data)
d33d7b00 16939+{
4bf69007 16940+ struct vcmd_ctx_dlimit_base_v0 vc_data;
3bac966d 16941+
d33d7b00
AM
16942+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16943+ return -EFAULT;
3bac966d 16944+
4bf69007
AM
16945+ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 1);
16946+}
3bac966d 16947+
4bf69007
AM
16948+int vc_rem_dlimit(uint32_t id, void __user *data)
16949+{
16950+ struct vcmd_ctx_dlimit_base_v0 vc_data;
3bac966d 16951+
4bf69007 16952+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d33d7b00 16953+ return -EFAULT;
4bf69007
AM
16954+
16955+ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 0);
d33d7b00 16956+}
3bac966d 16957+
4bf69007 16958+#ifdef CONFIG_COMPAT
3bac966d 16959+
4bf69007
AM
16960+int vc_add_dlimit_x32(uint32_t id, void __user *data)
16961+{
16962+ struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
3bac966d 16963+
4bf69007
AM
16964+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16965+ return -EFAULT;
d337f35e 16966+
4bf69007
AM
16967+ return do_addrem_dlimit(id,
16968+ compat_ptr(vc_data.name_ptr), vc_data.flags, 1);
16969+}
d337f35e 16970+
4bf69007 16971+int vc_rem_dlimit_x32(uint32_t id, void __user *data)
d33d7b00 16972+{
4bf69007 16973+ struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
d337f35e 16974+
4bf69007
AM
16975+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16976+ return -EFAULT;
16977+
16978+ return do_addrem_dlimit(id,
16979+ compat_ptr(vc_data.name_ptr), vc_data.flags, 0);
d33d7b00 16980+}
d337f35e 16981+
4bf69007
AM
16982+#endif /* CONFIG_COMPAT */
16983+
16984+
16985+static inline
16986+int do_set_dlimit(uint32_t id, const char __user *name,
16987+ uint32_t space_used, uint32_t space_total,
16988+ uint32_t inodes_used, uint32_t inodes_total,
16989+ uint32_t reserved, uint32_t flags)
d33d7b00 16990+{
4bf69007
AM
16991+ struct path path;
16992+ int ret;
ba86f833 16993+
4bf69007
AM
16994+ ret = user_lpath(name, &path);
16995+ if (!ret) {
16996+ struct super_block *sb;
16997+ struct dl_info *dli;
d337f35e 16998+
4bf69007
AM
16999+ ret = -EINVAL;
17000+ if (!path.dentry->d_inode)
17001+ goto out_release;
17002+ if (!(sb = path.dentry->d_inode->i_sb))
17003+ goto out_release;
d337f35e 17004+
4bf69007
AM
17005+ /* sanity checks */
17006+ if ((reserved != CDLIM_KEEP &&
17007+ reserved > 100) ||
17008+ (inodes_used != CDLIM_KEEP &&
17009+ inodes_used > inodes_total) ||
17010+ (space_used != CDLIM_KEEP &&
17011+ space_used > space_total))
17012+ goto out_release;
d337f35e 17013+
4bf69007
AM
17014+ ret = -ESRCH;
17015+ dli = locate_dl_info(sb, id);
17016+ if (!dli)
17017+ goto out_release;
ba86f833 17018+
4bf69007 17019+ spin_lock(&dli->dl_lock);
d337f35e 17020+
4bf69007
AM
17021+ if (inodes_used != CDLIM_KEEP)
17022+ dli->dl_inodes_used = inodes_used;
17023+ if (inodes_total != CDLIM_KEEP)
17024+ dli->dl_inodes_total = inodes_total;
17025+ if (space_used != CDLIM_KEEP)
17026+ dli->dl_space_used = dlimit_space_32to64(
17027+ space_used, flags, DLIMS_USED);
d337f35e 17028+
4bf69007
AM
17029+ if (space_total == CDLIM_INFINITY)
17030+ dli->dl_space_total = DLIM_INFINITY;
17031+ else if (space_total != CDLIM_KEEP)
17032+ dli->dl_space_total = dlimit_space_32to64(
17033+ space_total, flags, DLIMS_TOTAL);
78865d5b 17034+
4bf69007
AM
17035+ if (reserved != CDLIM_KEEP)
17036+ dli->dl_nrlmult = (1 << 10) * (100 - reserved) / 100;
78865d5b 17037+
4bf69007 17038+ spin_unlock(&dli->dl_lock);
d337f35e 17039+
4bf69007
AM
17040+ put_dl_info(dli);
17041+ ret = 0;
d337f35e 17042+
4bf69007
AM
17043+ out_release:
17044+ path_put(&path);
17045+ }
17046+ return ret;
17047+}
d337f35e 17048+
4bf69007
AM
17049+int vc_set_dlimit(uint32_t id, void __user *data)
17050+{
17051+ struct vcmd_ctx_dlimit_v0 vc_data;
d337f35e 17052+
4bf69007
AM
17053+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17054+ return -EFAULT;
d337f35e 17055+
4bf69007
AM
17056+ return do_set_dlimit(id, vc_data.name,
17057+ vc_data.space_used, vc_data.space_total,
17058+ vc_data.inodes_used, vc_data.inodes_total,
17059+ vc_data.reserved, vc_data.flags);
17060+}
d337f35e 17061+
4bf69007 17062+#ifdef CONFIG_COMPAT
d337f35e 17063+
4bf69007
AM
17064+int vc_set_dlimit_x32(uint32_t id, void __user *data)
17065+{
17066+ struct vcmd_ctx_dlimit_v0_x32 vc_data;
d337f35e 17067+
4bf69007
AM
17068+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17069+ return -EFAULT;
d337f35e 17070+
4bf69007
AM
17071+ return do_set_dlimit(id, compat_ptr(vc_data.name_ptr),
17072+ vc_data.space_used, vc_data.space_total,
17073+ vc_data.inodes_used, vc_data.inodes_total,
17074+ vc_data.reserved, vc_data.flags);
17075+}
d337f35e 17076+
4bf69007 17077+#endif /* CONFIG_COMPAT */
d337f35e 17078+
d337f35e 17079+
4bf69007
AM
17080+static inline
17081+int do_get_dlimit(uint32_t id, const char __user *name,
17082+ uint32_t *space_used, uint32_t *space_total,
17083+ uint32_t *inodes_used, uint32_t *inodes_total,
17084+ uint32_t *reserved, uint32_t *flags)
17085+{
17086+ struct path path;
17087+ int ret;
d337f35e 17088+
4bf69007
AM
17089+ ret = user_lpath(name, &path);
17090+ if (!ret) {
17091+ struct super_block *sb;
17092+ struct dl_info *dli;
d337f35e 17093+
4bf69007
AM
17094+ ret = -EINVAL;
17095+ if (!path.dentry->d_inode)
17096+ goto out_release;
17097+ if (!(sb = path.dentry->d_inode->i_sb))
17098+ goto out_release;
d337f35e 17099+
4bf69007
AM
17100+ ret = -ESRCH;
17101+ dli = locate_dl_info(sb, id);
17102+ if (!dli)
17103+ goto out_release;
d337f35e 17104+
4bf69007
AM
17105+ spin_lock(&dli->dl_lock);
17106+ *inodes_used = dli->dl_inodes_used;
17107+ *inodes_total = dli->dl_inodes_total;
d337f35e 17108+
4bf69007
AM
17109+ *space_used = dlimit_space_64to32(
17110+ dli->dl_space_used, flags, DLIMS_USED);
d337f35e 17111+
4bf69007
AM
17112+ if (dli->dl_space_total == DLIM_INFINITY)
17113+ *space_total = CDLIM_INFINITY;
17114+ else
17115+ *space_total = dlimit_space_64to32(
17116+ dli->dl_space_total, flags, DLIMS_TOTAL);
d337f35e 17117+
4bf69007
AM
17118+ *reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10);
17119+ spin_unlock(&dli->dl_lock);
d337f35e 17120+
4bf69007
AM
17121+ put_dl_info(dli);
17122+ ret = -EFAULT;
d337f35e 17123+
4bf69007
AM
17124+ ret = 0;
17125+ out_release:
17126+ path_put(&path);
17127+ }
17128+ return ret;
d337f35e
JR
17129+}
17130+
4bf69007
AM
17131+
17132+int vc_get_dlimit(uint32_t id, void __user *data)
d337f35e 17133+{
4bf69007 17134+ struct vcmd_ctx_dlimit_v0 vc_data;
d337f35e
JR
17135+ int ret;
17136+
2380c486 17137+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
17138+ return -EFAULT;
17139+
4bf69007
AM
17140+ ret = do_get_dlimit(id, vc_data.name,
17141+ &vc_data.space_used, &vc_data.space_total,
17142+ &vc_data.inodes_used, &vc_data.inodes_total,
17143+ &vc_data.reserved, &vc_data.flags);
d337f35e
JR
17144+ if (ret)
17145+ return ret;
17146+
2380c486 17147+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
d337f35e
JR
17148+ return -EFAULT;
17149+ return 0;
17150+}
17151+
4bf69007 17152+#ifdef CONFIG_COMPAT
d337f35e 17153+
4bf69007 17154+int vc_get_dlimit_x32(uint32_t id, void __user *data)
d337f35e 17155+{
4bf69007 17156+ struct vcmd_ctx_dlimit_v0_x32 vc_data;
d337f35e
JR
17157+ int ret;
17158+
2380c486 17159+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
17160+ return -EFAULT;
17161+
4bf69007
AM
17162+ ret = do_get_dlimit(id, compat_ptr(vc_data.name_ptr),
17163+ &vc_data.space_used, &vc_data.space_total,
17164+ &vc_data.inodes_used, &vc_data.inodes_total,
17165+ &vc_data.reserved, &vc_data.flags);
d337f35e
JR
17166+ if (ret)
17167+ return ret;
17168+
2380c486 17169+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
d337f35e
JR
17170+ return -EFAULT;
17171+ return 0;
17172+}
17173+
4bf69007 17174+#endif /* CONFIG_COMPAT */
ec22aa5c
AM
17175+
17176+
4bf69007 17177+void vx_vsi_statfs(struct super_block *sb, struct kstatfs *buf)
ec22aa5c 17178+{
4bf69007
AM
17179+ struct dl_info *dli;
17180+ __u64 blimit, bfree, bavail;
17181+ __u32 ifree;
ec22aa5c 17182+
4bf69007
AM
17183+ dli = locate_dl_info(sb, dx_current_tag());
17184+ if (!dli)
17185+ return;
ec22aa5c 17186+
4bf69007
AM
17187+ spin_lock(&dli->dl_lock);
17188+ if (dli->dl_inodes_total == (unsigned long)DLIM_INFINITY)
17189+ goto no_ilim;
ec22aa5c 17190+
4bf69007
AM
17191+ /* reduce max inodes available to limit */
17192+ if (buf->f_files > dli->dl_inodes_total)
17193+ buf->f_files = dli->dl_inodes_total;
ec22aa5c 17194+
4bf69007
AM
17195+ ifree = dli->dl_inodes_total - dli->dl_inodes_used;
17196+ /* reduce free inodes to min */
17197+ if (ifree < buf->f_ffree)
17198+ buf->f_ffree = ifree;
b2252bc2 17199+
4bf69007
AM
17200+no_ilim:
17201+ if (dli->dl_space_total == DLIM_INFINITY)
17202+ goto no_blim;
d337f35e 17203+
4bf69007 17204+ blimit = dli->dl_space_total >> sb->s_blocksize_bits;
d337f35e 17205+
4bf69007
AM
17206+ if (dli->dl_space_total < dli->dl_space_used)
17207+ bfree = 0;
17208+ else
17209+ bfree = (dli->dl_space_total - dli->dl_space_used)
17210+ >> sb->s_blocksize_bits;
d337f35e 17211+
4bf69007
AM
17212+ bavail = ((dli->dl_space_total >> 10) * dli->dl_nrlmult);
17213+ if (bavail < dli->dl_space_used)
17214+ bavail = 0;
17215+ else
17216+ bavail = (bavail - dli->dl_space_used)
17217+ >> sb->s_blocksize_bits;
d337f35e 17218+
4bf69007
AM
17219+ /* reduce max space available to limit */
17220+ if (buf->f_blocks > blimit)
17221+ buf->f_blocks = blimit;
d337f35e 17222+
4bf69007
AM
17223+ /* reduce free space to min */
17224+ if (bfree < buf->f_bfree)
17225+ buf->f_bfree = bfree;
d337f35e 17226+
4bf69007
AM
17227+ /* reduce avail space to min */
17228+ if (bavail < buf->f_bavail)
17229+ buf->f_bavail = bavail;
d337f35e 17230+
4bf69007
AM
17231+no_blim:
17232+ spin_unlock(&dli->dl_lock);
17233+ put_dl_info(dli);
d337f35e 17234+
4bf69007 17235+ return;
d337f35e
JR
17236+}
17237+
4bf69007 17238+#include <linux/module.h>
d337f35e 17239+
4bf69007
AM
17240+EXPORT_SYMBOL_GPL(locate_dl_info);
17241+EXPORT_SYMBOL_GPL(rcu_free_dl_info);
e3afe727 17242+
cef7ea10
AM
17243diff -NurpP --minimal linux-4.9.82/kernel/vserver/helper.c linux-4.9.82-vs2.3.9.7/kernel/vserver/helper.c
17244--- linux-4.9.82/kernel/vserver/helper.c 1970-01-01 00:00:00.000000000 +0000
17245+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/helper.c 2018-01-10 02:50:49.000000000 +0000
09be7631 17246@@ -0,0 +1,242 @@
4bf69007
AM
17247+/*
17248+ * linux/kernel/vserver/helper.c
17249+ *
17250+ * Virtual Context Support
17251+ *
cc23e853 17252+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
17253+ *
17254+ * V0.01 basic helper
17255+ *
17256+ */
e3afe727 17257+
4bf69007
AM
17258+#include <linux/kmod.h>
17259+#include <linux/reboot.h>
17260+#include <linux/vs_context.h>
17261+#include <linux/vs_network.h>
17262+#include <linux/vserver/signal.h>
e3afe727 17263+
4bf69007
AM
17264+
17265+char vshelper_path[255] = "/sbin/vshelper";
17266+
17267+static int vshelper_init(struct subprocess_info *info, struct cred *new_cred)
17268+{
09be7631 17269+ current->flags &= ~PF_NO_SETAFFINITY;
4bf69007 17270+ return 0;
d337f35e
JR
17271+}
17272+
09be7631
JR
17273+static int vs_call_usermodehelper(char *path, char **argv, char **envp, int wait)
17274+{
17275+ struct subprocess_info *info;
17276+ gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
17277+
17278+ info = call_usermodehelper_setup(path, argv, envp, gfp_mask,
17279+ vshelper_init, NULL, NULL);
17280+ if (info == NULL)
17281+ return -ENOMEM;
17282+
17283+ return call_usermodehelper_exec(info, wait);
17284+}
17285+
4bf69007 17286+static int do_vshelper(char *name, char *argv[], char *envp[], int sync)
d337f35e 17287+{
4bf69007 17288+ int ret;
e3afe727 17289+
09be7631
JR
17290+ if ((ret = vs_call_usermodehelper(name, argv, envp,
17291+ sync ? UMH_WAIT_PROC : UMH_WAIT_EXEC))) {
4bf69007
AM
17292+ printk(KERN_WARNING "%s: (%s %s) returned %s with %d\n",
17293+ name, argv[1], argv[2],
17294+ sync ? "sync" : "async", ret);
17295+ }
17296+ vxdprintk(VXD_CBIT(switch, 4),
17297+ "%s: (%s %s) returned %s with %d",
17298+ name, argv[1], argv[2], sync ? "sync" : "async", ret);
17299+ return ret;
17300+}
e3afe727 17301+
4bf69007
AM
17302+/*
17303+ * vshelper path is set via /proc/sys
17304+ * invoked by vserver sys_reboot(), with
17305+ * the following arguments
17306+ *
17307+ * argv [0] = vshelper_path;
17308+ * argv [1] = action: "restart", "halt", "poweroff", ...
17309+ * argv [2] = context identifier
17310+ *
17311+ * envp [*] = type-specific parameters
17312+ */
e3afe727 17313+
4bf69007
AM
17314+long vs_reboot_helper(struct vx_info *vxi, int cmd, void __user *arg)
17315+{
17316+ char id_buf[8], cmd_buf[16];
17317+ char uid_buf[16], pid_buf[16];
17318+ int ret;
e3afe727 17319+
4bf69007
AM
17320+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
17321+ char *envp[] = {"HOME=/", "TERM=linux",
17322+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
17323+ uid_buf, pid_buf, cmd_buf, 0};
e3afe727 17324+
4bf69007
AM
17325+ if (vx_info_state(vxi, VXS_HELPER))
17326+ return -EAGAIN;
17327+ vxi->vx_state |= VXS_HELPER;
7b17263b 17328+
4bf69007 17329+ snprintf(id_buf, sizeof(id_buf), "%d", vxi->vx_id);
d337f35e 17330+
4bf69007 17331+ snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
8ce283e1
AM
17332+ snprintf(uid_buf, sizeof(uid_buf), "VS_UID=%d",
17333+ from_kuid(&init_user_ns, current_uid()));
4bf69007 17334+ snprintf(pid_buf, sizeof(pid_buf), "VS_PID=%d", current->pid);
e3afe727 17335+
4bf69007
AM
17336+ switch (cmd) {
17337+ case LINUX_REBOOT_CMD_RESTART:
17338+ argv[1] = "restart";
17339+ break;
07a627a5 17340+
4bf69007
AM
17341+ case LINUX_REBOOT_CMD_HALT:
17342+ argv[1] = "halt";
17343+ break;
e3afe727 17344+
4bf69007
AM
17345+ case LINUX_REBOOT_CMD_POWER_OFF:
17346+ argv[1] = "poweroff";
17347+ break;
d337f35e 17348+
4bf69007
AM
17349+ case LINUX_REBOOT_CMD_SW_SUSPEND:
17350+ argv[1] = "swsusp";
17351+ break;
d337f35e 17352+
4bf69007
AM
17353+ case LINUX_REBOOT_CMD_OOM:
17354+ argv[1] = "oom";
17355+ break;
d337f35e 17356+
4bf69007
AM
17357+ default:
17358+ vxi->vx_state &= ~VXS_HELPER;
17359+ return 0;
d337f35e 17360+ }
4bf69007
AM
17361+
17362+ ret = do_vshelper(vshelper_path, argv, envp, 0);
17363+ vxi->vx_state &= ~VXS_HELPER;
17364+ __wakeup_vx_info(vxi);
17365+ return (ret) ? -EPERM : 0;
d337f35e
JR
17366+}
17367+
4bf69007
AM
17368+
17369+long vs_reboot(unsigned int cmd, void __user *arg)
d337f35e 17370+{
4bf69007
AM
17371+ struct vx_info *vxi = current_vx_info();
17372+ long ret = 0;
d337f35e 17373+
4bf69007
AM
17374+ vxdprintk(VXD_CBIT(misc, 5),
17375+ "vs_reboot(%p[#%d],%u)",
17376+ vxi, vxi ? vxi->vx_id : 0, cmd);
17377+
17378+ ret = vs_reboot_helper(vxi, cmd, arg);
17379+ if (ret)
17380+ return ret;
17381+
17382+ vxi->reboot_cmd = cmd;
17383+ if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
17384+ switch (cmd) {
17385+ case LINUX_REBOOT_CMD_RESTART:
17386+ case LINUX_REBOOT_CMD_HALT:
17387+ case LINUX_REBOOT_CMD_POWER_OFF:
17388+ vx_info_kill(vxi, 0, SIGKILL);
17389+ vx_info_kill(vxi, 1, SIGKILL);
17390+ default:
17391+ break;
17392+ }
d337f35e 17393+ }
4bf69007 17394+ return 0;
d337f35e
JR
17395+}
17396+
4bf69007
AM
17397+long vs_oom_action(unsigned int cmd)
17398+{
17399+ struct vx_info *vxi = current_vx_info();
17400+ long ret = 0;
d337f35e 17401+
4bf69007
AM
17402+ vxdprintk(VXD_CBIT(misc, 5),
17403+ "vs_oom_action(%p[#%d],%u)",
17404+ vxi, vxi ? vxi->vx_id : 0, cmd);
d337f35e 17405+
4bf69007
AM
17406+ ret = vs_reboot_helper(vxi, cmd, NULL);
17407+ if (ret)
17408+ return ret;
d337f35e 17409+
4bf69007
AM
17410+ vxi->reboot_cmd = cmd;
17411+ if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
17412+ vx_info_kill(vxi, 0, SIGKILL);
17413+ vx_info_kill(vxi, 1, SIGKILL);
17414+ }
17415+ return 0;
17416+}
d337f35e 17417+
4bf69007
AM
17418+/*
17419+ * argv [0] = vshelper_path;
17420+ * argv [1] = action: "startup", "shutdown"
17421+ * argv [2] = context identifier
17422+ *
17423+ * envp [*] = type-specific parameters
17424+ */
d337f35e 17425+
4bf69007 17426+long vs_state_change(struct vx_info *vxi, unsigned int cmd)
d337f35e 17427+{
4bf69007
AM
17428+ char id_buf[8], cmd_buf[16];
17429+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
17430+ char *envp[] = {"HOME=/", "TERM=linux",
17431+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
17432+
17433+ if (!vx_info_flags(vxi, VXF_SC_HELPER, 0))
17434+ return 0;
17435+
17436+ snprintf(id_buf, sizeof(id_buf), "%d", vxi->vx_id);
17437+ snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
17438+
17439+ switch (cmd) {
17440+ case VSC_STARTUP:
17441+ argv[1] = "startup";
17442+ break;
17443+ case VSC_SHUTDOWN:
17444+ argv[1] = "shutdown";
17445+ break;
17446+ default:
17447+ return 0;
17448+ }
17449+
17450+ return do_vshelper(vshelper_path, argv, envp, 1);
d337f35e
JR
17451+}
17452+
d337f35e 17453+
4bf69007
AM
17454+/*
17455+ * argv [0] = vshelper_path;
17456+ * argv [1] = action: "netup", "netdown"
17457+ * argv [2] = context identifier
17458+ *
17459+ * envp [*] = type-specific parameters
17460+ */
17461+
17462+long vs_net_change(struct nx_info *nxi, unsigned int cmd)
17463+{
17464+ char id_buf[8], cmd_buf[16];
17465+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
17466+ char *envp[] = {"HOME=/", "TERM=linux",
17467+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
17468+
17469+ if (!nx_info_flags(nxi, NXF_SC_HELPER, 0))
17470+ return 0;
17471+
17472+ snprintf(id_buf, sizeof(id_buf), "%d", nxi->nx_id);
17473+ snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
17474+
17475+ switch (cmd) {
17476+ case VSC_NETUP:
17477+ argv[1] = "netup";
17478+ break;
17479+ case VSC_NETDOWN:
17480+ argv[1] = "netdown";
17481+ break;
17482+ default:
17483+ return 0;
17484+ }
17485+
17486+ return do_vshelper(vshelper_path, argv, envp, 1);
17487+}
d337f35e 17488+
cef7ea10
AM
17489diff -NurpP --minimal linux-4.9.82/kernel/vserver/history.c linux-4.9.82-vs2.3.9.7/kernel/vserver/history.c
17490--- linux-4.9.82/kernel/vserver/history.c 1970-01-01 00:00:00.000000000 +0000
17491+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/history.c 2018-01-10 02:50:49.000000000 +0000
4bf69007 17492@@ -0,0 +1,258 @@
d337f35e 17493+/*
4bf69007 17494+ * kernel/vserver/history.c
d337f35e 17495+ *
4bf69007 17496+ * Virtual Context History Backtrace
d337f35e 17497+ *
cc23e853 17498+ * Copyright (C) 2004-2007 Herbert P?tzl
d337f35e 17499+ *
4bf69007
AM
17500+ * V0.01 basic structure
17501+ * V0.02 hash/unhash and trace
17502+ * V0.03 preemption fixes
d337f35e
JR
17503+ *
17504+ */
17505+
4bf69007
AM
17506+#include <linux/module.h>
17507+#include <asm/uaccess.h>
d337f35e 17508+
4bf69007
AM
17509+#include <linux/vserver/context.h>
17510+#include <linux/vserver/debug.h>
17511+#include <linux/vserver/debug_cmd.h>
17512+#include <linux/vserver/history.h>
d337f35e
JR
17513+
17514+
4bf69007
AM
17515+#ifdef CONFIG_VSERVER_HISTORY
17516+#define VXH_SIZE CONFIG_VSERVER_HISTORY_SIZE
17517+#else
17518+#define VXH_SIZE 64
17519+#endif
d337f35e 17520+
4bf69007
AM
17521+struct _vx_history {
17522+ unsigned int counter;
2380c486 17523+
4bf69007
AM
17524+ struct _vx_hist_entry entry[VXH_SIZE + 1];
17525+};
2380c486 17526+
2380c486 17527+
4bf69007 17528+DEFINE_PER_CPU(struct _vx_history, vx_history_buffer);
2380c486 17529+
4bf69007 17530+unsigned volatile int vxh_active = 1;
2380c486 17531+
4bf69007 17532+static atomic_t sequence = ATOMIC_INIT(0);
2380c486 17533+
2380c486 17534+
4bf69007 17535+/* vxh_advance()
2380c486 17536+
4bf69007
AM
17537+ * requires disabled preemption */
17538+
17539+struct _vx_hist_entry *vxh_advance(void *loc)
2380c486 17540+{
4bf69007
AM
17541+ unsigned int cpu = smp_processor_id();
17542+ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
17543+ struct _vx_hist_entry *entry;
17544+ unsigned int index;
17545+
17546+ index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE;
17547+ entry = &hist->entry[index];
17548+
17549+ entry->seq = atomic_inc_return(&sequence);
17550+ entry->loc = loc;
17551+ return entry;
2380c486
JR
17552+}
17553+
4bf69007 17554+EXPORT_SYMBOL_GPL(vxh_advance);
2380c486 17555+
2380c486 17556+
4bf69007 17557+#define VXH_LOC_FMTS "(#%04x,*%d):%p"
2380c486 17558+
4bf69007 17559+#define VXH_LOC_ARGS(e) (e)->seq, cpu, (e)->loc
2380c486 17560+
2380c486 17561+
4bf69007 17562+#define VXH_VXI_FMTS "%p[#%d,%d.%d]"
2380c486 17563+
4bf69007
AM
17564+#define VXH_VXI_ARGS(e) (e)->vxi.ptr, \
17565+ (e)->vxi.ptr ? (e)->vxi.xid : 0, \
17566+ (e)->vxi.ptr ? (e)->vxi.usecnt : 0, \
17567+ (e)->vxi.ptr ? (e)->vxi.tasks : 0
17568+
17569+void vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu)
2380c486 17570+{
4bf69007
AM
17571+ switch (e->type) {
17572+ case VXH_THROW_OOPS:
17573+ printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e));
17574+ break;
2380c486 17575+
4bf69007
AM
17576+ case VXH_GET_VX_INFO:
17577+ case VXH_PUT_VX_INFO:
17578+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
17579+ VXH_LOC_ARGS(e),
17580+ (e->type == VXH_GET_VX_INFO) ? "get" : "put",
17581+ VXH_VXI_ARGS(e));
17582+ break;
2380c486 17583+
4bf69007
AM
17584+ case VXH_INIT_VX_INFO:
17585+ case VXH_SET_VX_INFO:
17586+ case VXH_CLR_VX_INFO:
17587+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
17588+ VXH_LOC_ARGS(e),
17589+ (e->type == VXH_INIT_VX_INFO) ? "init" :
17590+ ((e->type == VXH_SET_VX_INFO) ? "set" : "clr"),
17591+ VXH_VXI_ARGS(e), e->sc.data);
17592+ break;
2380c486 17593+
4bf69007
AM
17594+ case VXH_CLAIM_VX_INFO:
17595+ case VXH_RELEASE_VX_INFO:
17596+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
17597+ VXH_LOC_ARGS(e),
17598+ (e->type == VXH_CLAIM_VX_INFO) ? "claim" : "release",
17599+ VXH_VXI_ARGS(e), e->sc.data);
17600+ break;
2380c486 17601+
4bf69007
AM
17602+ case VXH_ALLOC_VX_INFO:
17603+ case VXH_DEALLOC_VX_INFO:
17604+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
17605+ VXH_LOC_ARGS(e),
17606+ (e->type == VXH_ALLOC_VX_INFO) ? "alloc" : "dealloc",
17607+ VXH_VXI_ARGS(e));
17608+ break;
2380c486 17609+
4bf69007
AM
17610+ case VXH_HASH_VX_INFO:
17611+ case VXH_UNHASH_VX_INFO:
17612+ printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n",
17613+ VXH_LOC_ARGS(e),
17614+ (e->type == VXH_HASH_VX_INFO) ? "hash" : "unhash",
17615+ VXH_VXI_ARGS(e));
17616+ break;
2380c486 17617+
4bf69007
AM
17618+ case VXH_LOC_VX_INFO:
17619+ case VXH_LOOKUP_VX_INFO:
17620+ case VXH_CREATE_VX_INFO:
17621+ printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n",
17622+ VXH_LOC_ARGS(e),
17623+ (e->type == VXH_CREATE_VX_INFO) ? "create" :
17624+ ((e->type == VXH_LOC_VX_INFO) ? "loc" : "lookup"),
17625+ e->ll.arg, VXH_VXI_ARGS(e));
17626+ break;
2380c486
JR
17627+ }
17628+}
17629+
4bf69007
AM
17630+static void __vxh_dump_history(void)
17631+{
17632+ unsigned int i, cpu;
d337f35e 17633+
4bf69007
AM
17634+ printk("History:\tSEQ: %8x\tNR_CPUS: %d\n",
17635+ atomic_read(&sequence), NR_CPUS);
d337f35e 17636+
4bf69007
AM
17637+ for (i = 0; i < VXH_SIZE; i++) {
17638+ for_each_online_cpu(cpu) {
17639+ struct _vx_history *hist =
17640+ &per_cpu(vx_history_buffer, cpu);
17641+ unsigned int index = (hist->counter - i) % VXH_SIZE;
17642+ struct _vx_hist_entry *entry = &hist->entry[index];
d337f35e 17643+
4bf69007
AM
17644+ vxh_dump_entry(entry, cpu);
17645+ }
17646+ }
17647+}
d337f35e 17648+
4bf69007
AM
17649+void vxh_dump_history(void)
17650+{
17651+ vxh_active = 0;
17652+#ifdef CONFIG_SMP
17653+ local_irq_enable();
17654+ smp_send_stop();
17655+ local_irq_disable();
17656+#endif
17657+ __vxh_dump_history();
17658+}
d337f35e 17659+
d337f35e 17660+
4bf69007 17661+/* vserver syscall commands below here */
d337f35e 17662+
d337f35e 17663+
4bf69007
AM
17664+int vc_dump_history(uint32_t id)
17665+{
17666+ vxh_active = 0;
17667+ __vxh_dump_history();
17668+ vxh_active = 1;
2380c486 17669+
4bf69007 17670+ return 0;
d337f35e
JR
17671+}
17672+
d337f35e 17673+
4bf69007
AM
17674+int do_read_history(struct __user _vx_hist_entry *data,
17675+ int cpu, uint32_t *index, uint32_t *count)
d337f35e 17676+{
4bf69007
AM
17677+ int pos, ret = 0;
17678+ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
17679+ int end = hist->counter;
17680+ int start = end - VXH_SIZE + 2;
17681+ int idx = *index;
d337f35e 17682+
4bf69007
AM
17683+ /* special case: get current pos */
17684+ if (!*count) {
17685+ *index = end;
17686+ return 0;
17687+ }
d337f35e 17688+
4bf69007
AM
17689+ /* have we lost some data? */
17690+ if (idx < start)
17691+ idx = start;
d337f35e 17692+
4bf69007
AM
17693+ for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) {
17694+ struct _vx_hist_entry *entry =
17695+ &hist->entry[idx % VXH_SIZE];
2380c486 17696+
4bf69007
AM
17697+ /* send entry to userspace */
17698+ ret = copy_to_user(&data[pos], entry, sizeof(*entry));
17699+ if (ret)
17700+ break;
17701+ }
17702+ /* save new index and count */
17703+ *index = idx;
17704+ *count = pos;
17705+ return ret ? ret : (*index < end);
d337f35e
JR
17706+}
17707+
4bf69007 17708+int vc_read_history(uint32_t id, void __user *data)
d337f35e 17709+{
4bf69007
AM
17710+ struct vcmd_read_history_v0 vc_data;
17711+ int ret;
d337f35e 17712+
4bf69007
AM
17713+ if (id >= NR_CPUS)
17714+ return -EINVAL;
d337f35e 17715+
4bf69007
AM
17716+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17717+ return -EFAULT;
d337f35e 17718+
4bf69007
AM
17719+ ret = do_read_history((struct __user _vx_hist_entry *)vc_data.data,
17720+ id, &vc_data.index, &vc_data.count);
d337f35e 17721+
4bf69007
AM
17722+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
17723+ return -EFAULT;
17724+ return ret;
d337f35e
JR
17725+}
17726+
4bf69007 17727+#ifdef CONFIG_COMPAT
d337f35e 17728+
4bf69007 17729+int vc_read_history_x32(uint32_t id, void __user *data)
d337f35e 17730+{
4bf69007
AM
17731+ struct vcmd_read_history_v0_x32 vc_data;
17732+ int ret;
d337f35e 17733+
4bf69007
AM
17734+ if (id >= NR_CPUS)
17735+ return -EINVAL;
d337f35e 17736+
4bf69007
AM
17737+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17738+ return -EFAULT;
2380c486 17739+
4bf69007
AM
17740+ ret = do_read_history((struct __user _vx_hist_entry *)
17741+ compat_ptr(vc_data.data_ptr),
17742+ id, &vc_data.index, &vc_data.count);
d337f35e 17743+
4bf69007
AM
17744+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
17745+ return -EFAULT;
17746+ return ret;
17747+}
d337f35e 17748+
4bf69007 17749+#endif /* CONFIG_COMPAT */
d337f35e 17750+
cef7ea10
AM
17751diff -NurpP --minimal linux-4.9.82/kernel/vserver/inet.c linux-4.9.82-vs2.3.9.7/kernel/vserver/inet.c
17752--- linux-4.9.82/kernel/vserver/inet.c 1970-01-01 00:00:00.000000000 +0000
17753+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/inet.c 2018-01-10 02:50:49.000000000 +0000
7a9e40b8 17754@@ -0,0 +1,236 @@
d337f35e 17755+
4bf69007
AM
17756+#include <linux/in.h>
17757+#include <linux/inetdevice.h>
17758+#include <linux/export.h>
17759+#include <linux/vs_inet.h>
17760+#include <linux/vs_inet6.h>
17761+#include <linux/vserver/debug.h>
17762+#include <net/route.h>
17763+#include <net/addrconf.h>
d337f35e
JR
17764+
17765+
4bf69007 17766+int nx_v4_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2)
d337f35e 17767+{
4bf69007
AM
17768+ int ret = 0;
17769+
17770+ if (!nxi1 || !nxi2 || nxi1 == nxi2)
17771+ ret = 1;
17772+ else {
17773+ struct nx_addr_v4 *ptr;
7a9e40b8 17774+ unsigned long irqflags;
d337f35e 17775+
7a9e40b8 17776+ spin_lock_irqsave(&nxi1->addr_lock, irqflags);
4bf69007
AM
17777+ for (ptr = &nxi1->v4; ptr; ptr = ptr->next) {
17778+ if (v4_nx_addr_in_nx_info(nxi2, ptr, -1)) {
17779+ ret = 1;
17780+ break;
17781+ }
17782+ }
7a9e40b8 17783+ spin_unlock_irqrestore(&nxi1->addr_lock, irqflags);
4bf69007 17784+ }
d337f35e 17785+
4bf69007
AM
17786+ vxdprintk(VXD_CBIT(net, 2),
17787+ "nx_v4_addr_conflict(%p,%p): %d",
17788+ nxi1, nxi2, ret);
d337f35e 17789+
4bf69007
AM
17790+ return ret;
17791+}
d337f35e 17792+
d337f35e 17793+
4bf69007
AM
17794+#ifdef CONFIG_IPV6
17795+
17796+int nx_v6_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2)
d337f35e 17797+{
4bf69007 17798+ int ret = 0;
d337f35e 17799+
4bf69007
AM
17800+ if (!nxi1 || !nxi2 || nxi1 == nxi2)
17801+ ret = 1;
17802+ else {
17803+ struct nx_addr_v6 *ptr;
7a9e40b8 17804+ unsigned long irqflags;
d337f35e 17805+
7a9e40b8 17806+ spin_lock_irqsave(&nxi1->addr_lock, irqflags);
4bf69007
AM
17807+ for (ptr = &nxi1->v6; ptr; ptr = ptr->next) {
17808+ if (v6_nx_addr_in_nx_info(nxi2, ptr, -1)) {
17809+ ret = 1;
17810+ break;
17811+ }
17812+ }
7a9e40b8 17813+ spin_unlock_irqrestore(&nxi1->addr_lock, irqflags);
4bf69007 17814+ }
d337f35e 17815+
4bf69007
AM
17816+ vxdprintk(VXD_CBIT(net, 2),
17817+ "nx_v6_addr_conflict(%p,%p): %d",
17818+ nxi1, nxi2, ret);
d337f35e 17819+
4bf69007
AM
17820+ return ret;
17821+}
d337f35e 17822+
4bf69007 17823+#endif
d337f35e 17824+
4bf69007 17825+int v4_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
d337f35e 17826+{
4bf69007
AM
17827+ struct in_device *in_dev;
17828+ struct in_ifaddr **ifap;
17829+ struct in_ifaddr *ifa;
17830+ int ret = 0;
d337f35e 17831+
4bf69007
AM
17832+ if (!dev)
17833+ goto out;
17834+ in_dev = in_dev_get(dev);
17835+ if (!in_dev)
17836+ goto out;
d337f35e 17837+
4bf69007
AM
17838+ for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
17839+ ifap = &ifa->ifa_next) {
17840+ if (v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW)) {
17841+ ret = 1;
17842+ break;
17843+ }
17844+ }
17845+ in_dev_put(in_dev);
17846+out:
17847+ return ret;
d337f35e
JR
17848+}
17849+
17850+
4bf69007 17851+#ifdef CONFIG_IPV6
d337f35e 17852+
4bf69007 17853+int v6_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
d337f35e 17854+{
4bf69007
AM
17855+ struct inet6_dev *in_dev;
17856+ struct inet6_ifaddr *ifa;
17857+ int ret = 0;
d337f35e 17858+
4bf69007
AM
17859+ if (!dev)
17860+ goto out;
17861+ in_dev = in6_dev_get(dev);
17862+ if (!in_dev)
17863+ goto out;
d337f35e 17864+
4bf69007
AM
17865+ // for (ifap = &in_dev->addr_list; (ifa = *ifap) != NULL;
17866+ list_for_each_entry(ifa, &in_dev->addr_list, if_list) {
17867+ if (v6_addr_in_nx_info(nxi, &ifa->addr, -1)) {
17868+ ret = 1;
17869+ break;
17870+ }
d337f35e 17871+ }
4bf69007
AM
17872+ in6_dev_put(in_dev);
17873+out:
17874+ return ret;
d337f35e
JR
17875+}
17876+
4bf69007 17877+#endif
d337f35e 17878+
4bf69007
AM
17879+int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
17880+{
17881+ int ret = 1;
d337f35e 17882+
4bf69007
AM
17883+ if (!nxi)
17884+ goto out;
17885+ if (nxi->v4.type && v4_dev_in_nx_info(dev, nxi))
17886+ goto out;
17887+#ifdef CONFIG_IPV6
17888+ ret = 2;
17889+ if (nxi->v6.type && v6_dev_in_nx_info(dev, nxi))
17890+ goto out;
17891+#endif
17892+ ret = 0;
17893+out:
17894+ vxdprintk(VXD_CBIT(net, 3),
17895+ "dev_in_nx_info(%p,%p[#%d]) = %d",
17896+ dev, nxi, nxi ? nxi->nx_id : 0, ret);
17897+ return ret;
17898+}
d337f35e 17899+
4bf69007
AM
17900+struct rtable *ip_v4_find_src(struct net *net, struct nx_info *nxi,
17901+ struct flowi4 *fl4)
d337f35e 17902+{
4bf69007 17903+ struct rtable *rt;
d337f35e 17904+
4bf69007
AM
17905+ if (!nxi)
17906+ return NULL;
d337f35e 17907+
4bf69007
AM
17908+ /* FIXME: handle lback only case */
17909+ if (!NX_IPV4(nxi))
17910+ return ERR_PTR(-EPERM);
d337f35e 17911+
4bf69007
AM
17912+ vxdprintk(VXD_CBIT(net, 4),
17913+ "ip_v4_find_src(%p[#%u]) " NIPQUAD_FMT " -> " NIPQUAD_FMT,
17914+ nxi, nxi ? nxi->nx_id : 0,
17915+ NIPQUAD(fl4->saddr), NIPQUAD(fl4->daddr));
d337f35e 17916+
4bf69007
AM
17917+ /* single IP is unconditional */
17918+ if (nx_info_flags(nxi, NXF_SINGLE_IP, 0) &&
17919+ (fl4->saddr == INADDR_ANY))
17920+ fl4->saddr = nxi->v4.ip[0].s_addr;
d337f35e 17921+
4bf69007
AM
17922+ if (fl4->saddr == INADDR_ANY) {
17923+ struct nx_addr_v4 *ptr;
17924+ __be32 found = 0;
17925+
17926+ rt = __ip_route_output_key(net, fl4);
17927+ if (!IS_ERR(rt)) {
17928+ found = fl4->saddr;
17929+ ip_rt_put(rt);
17930+ vxdprintk(VXD_CBIT(net, 4),
17931+ "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT,
17932+ nxi, nxi ? nxi->nx_id : 0, fl4->flowi4_oif, NIPQUAD(found));
17933+ if (v4_addr_in_nx_info(nxi, found, NXA_MASK_BIND))
17934+ goto found;
17935+ }
d337f35e 17936+
8d50a2ea 17937+ WARN_ON_ONCE(in_irq());
b00e13aa 17938+ spin_lock_bh(&nxi->addr_lock);
4bf69007
AM
17939+ for (ptr = &nxi->v4; ptr; ptr = ptr->next) {
17940+ __be32 primary = ptr->ip[0].s_addr;
17941+ __be32 mask = ptr->mask.s_addr;
17942+ __be32 neta = primary & mask;
d337f35e 17943+
4bf69007
AM
17944+ vxdprintk(VXD_CBIT(net, 4), "ip_v4_find_src(%p[#%u]) chk: "
17945+ NIPQUAD_FMT "/" NIPQUAD_FMT "/" NIPQUAD_FMT,
17946+ nxi, nxi ? nxi->nx_id : 0, NIPQUAD(primary),
17947+ NIPQUAD(mask), NIPQUAD(neta));
17948+ if ((found & mask) != neta)
17949+ continue;
d337f35e 17950+
4bf69007
AM
17951+ fl4->saddr = primary;
17952+ rt = __ip_route_output_key(net, fl4);
17953+ vxdprintk(VXD_CBIT(net, 4),
17954+ "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT,
17955+ nxi, nxi ? nxi->nx_id : 0, fl4->flowi4_oif, NIPQUAD(primary));
17956+ if (!IS_ERR(rt)) {
17957+ found = fl4->saddr;
17958+ ip_rt_put(rt);
17959+ if (found == primary)
5cb1760b 17960+ goto found_unlock;
4bf69007
AM
17961+ }
17962+ }
17963+ /* still no source ip? */
17964+ found = ipv4_is_loopback(fl4->daddr)
17965+ ? IPI_LOOPBACK : nxi->v4.ip[0].s_addr;
5cb1760b 17966+ found_unlock:
b00e13aa 17967+ spin_unlock_bh(&nxi->addr_lock);
4bf69007
AM
17968+ found:
17969+ /* assign src ip to flow */
17970+ fl4->saddr = found;
17971+
17972+ } else {
17973+ if (!v4_addr_in_nx_info(nxi, fl4->saddr, NXA_MASK_BIND))
17974+ return ERR_PTR(-EPERM);
17975+ }
d337f35e 17976+
4bf69007
AM
17977+ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0)) {
17978+ if (ipv4_is_loopback(fl4->daddr))
17979+ fl4->daddr = nxi->v4_lback.s_addr;
17980+ if (ipv4_is_loopback(fl4->saddr))
17981+ fl4->saddr = nxi->v4_lback.s_addr;
17982+ } else if (ipv4_is_loopback(fl4->daddr) &&
17983+ !nx_info_flags(nxi, NXF_LBACK_ALLOW, 0))
17984+ return ERR_PTR(-EPERM);
d337f35e 17985+
4bf69007 17986+ return NULL;
d337f35e
JR
17987+}
17988+
4bf69007 17989+EXPORT_SYMBOL_GPL(ip_v4_find_src);
d337f35e 17990+
cef7ea10
AM
17991diff -NurpP --minimal linux-4.9.82/kernel/vserver/init.c linux-4.9.82-vs2.3.9.7/kernel/vserver/init.c
17992--- linux-4.9.82/kernel/vserver/init.c 1970-01-01 00:00:00.000000000 +0000
17993+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/init.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 17994@@ -0,0 +1,46 @@
4bf69007
AM
17995+/*
17996+ * linux/kernel/init.c
17997+ *
17998+ * Virtual Server Init
17999+ *
cc23e853 18000+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
18001+ *
18002+ * V0.01 basic structure
18003+ *
18004+ */
d337f35e 18005+
4bf69007 18006+#include <linux/init.h>
cc23e853 18007+#include <linux/module.h>
4bf69007
AM
18008+
18009+int vserver_register_sysctl(void);
18010+void vserver_unregister_sysctl(void);
18011+
18012+
18013+static int __init init_vserver(void)
d337f35e 18014+{
4bf69007 18015+ int ret = 0;
d337f35e 18016+
4bf69007
AM
18017+#ifdef CONFIG_VSERVER_DEBUG
18018+ vserver_register_sysctl();
18019+#endif
18020+ return ret;
d337f35e
JR
18021+}
18022+
d337f35e 18023+
4bf69007 18024+static void __exit exit_vserver(void)
d337f35e 18025+{
d337f35e 18026+
4bf69007
AM
18027+#ifdef CONFIG_VSERVER_DEBUG
18028+ vserver_unregister_sysctl();
18029+#endif
18030+ return;
d337f35e
JR
18031+}
18032+
4bf69007
AM
18033+/* FIXME: GFP_ZONETYPES gone
18034+long vx_slab[GFP_ZONETYPES]; */
18035+long vx_area;
d337f35e 18036+
d337f35e 18037+
4bf69007
AM
18038+module_init(init_vserver);
18039+module_exit(exit_vserver);
d337f35e 18040+
cef7ea10
AM
18041diff -NurpP --minimal linux-4.9.82/kernel/vserver/inode.c linux-4.9.82-vs2.3.9.7/kernel/vserver/inode.c
18042--- linux-4.9.82/kernel/vserver/inode.c 1970-01-01 00:00:00.000000000 +0000
18043+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/inode.c 2018-01-13 03:26:08.000000000 +0000
09be7631 18044@@ -0,0 +1,440 @@
4bf69007
AM
18045+/*
18046+ * linux/kernel/vserver/inode.c
18047+ *
18048+ * Virtual Server: File System Support
18049+ *
cc23e853 18050+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
18051+ *
18052+ * V0.01 separated from vcontext V0.05
18053+ * V0.02 moved to tag (instead of xid)
18054+ *
18055+ */
d337f35e 18056+
4bf69007
AM
18057+#include <linux/tty.h>
18058+#include <linux/proc_fs.h>
18059+#include <linux/devpts_fs.h>
18060+#include <linux/fs.h>
18061+#include <linux/file.h>
18062+#include <linux/mount.h>
18063+#include <linux/parser.h>
18064+#include <linux/namei.h>
09be7631
JR
18065+#include <linux/magic.h>
18066+#include <linux/slab.h>
4bf69007
AM
18067+#include <linux/vserver/inode.h>
18068+#include <linux/vserver/inode_cmd.h>
18069+#include <linux/vs_base.h>
18070+#include <linux/vs_tag.h>
d337f35e 18071+
4bf69007 18072+#include <asm/uaccess.h>
09be7631 18073+#include <../../fs/proc/internal.h>
d337f35e 18074+
d337f35e 18075+
4bf69007 18076+static int __vc_get_iattr(struct inode *in, uint32_t *tag, uint32_t *flags, uint32_t *mask)
d337f35e 18077+{
4bf69007 18078+ struct proc_dir_entry *entry;
d337f35e 18079+
4bf69007
AM
18080+ if (!in || !in->i_sb)
18081+ return -ESRCH;
d337f35e 18082+
4bf69007
AM
18083+ *flags = IATTR_TAG
18084+ | (IS_IMMUTABLE(in) ? IATTR_IMMUTABLE : 0)
18085+ | (IS_IXUNLINK(in) ? IATTR_IXUNLINK : 0)
18086+ | (IS_BARRIER(in) ? IATTR_BARRIER : 0)
18087+ | (IS_COW(in) ? IATTR_COW : 0);
18088+ *mask = IATTR_IXUNLINK | IATTR_IMMUTABLE | IATTR_COW;
d337f35e 18089+
4bf69007
AM
18090+ if (S_ISDIR(in->i_mode))
18091+ *mask |= IATTR_BARRIER;
d337f35e 18092+
4bf69007
AM
18093+ if (IS_TAGGED(in)) {
18094+ *tag = i_tag_read(in);
18095+ *mask |= IATTR_TAG;
18096+ }
2380c486 18097+
4bf69007
AM
18098+ switch (in->i_sb->s_magic) {
18099+ case PROC_SUPER_MAGIC:
18100+ entry = PROC_I(in)->pde;
d337f35e 18101+
4bf69007
AM
18102+ /* check for specific inodes? */
18103+ if (entry)
18104+ *mask |= IATTR_FLAGS;
18105+ if (entry)
18106+ *flags |= (entry->vx_flags & IATTR_FLAGS);
18107+ else
18108+ *flags |= (PROC_I(in)->vx_flags & IATTR_FLAGS);
18109+ break;
d337f35e 18110+
4bf69007
AM
18111+ case DEVPTS_SUPER_MAGIC:
18112+ *tag = i_tag_read(in);
18113+ *mask |= IATTR_TAG;
18114+ break;
d337f35e 18115+
4bf69007
AM
18116+ default:
18117+ break;
18118+ }
18119+ return 0;
d337f35e
JR
18120+}
18121+
4bf69007 18122+int vc_get_iattr(void __user *data)
d337f35e 18123+{
4bf69007
AM
18124+ struct path path;
18125+ struct vcmd_ctx_iattr_v1 vc_data = { .tag = -1 };
18126+ int ret;
d337f35e 18127+
4bf69007
AM
18128+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18129+ return -EFAULT;
d337f35e 18130+
4bf69007
AM
18131+ ret = user_lpath(vc_data.name, &path);
18132+ if (!ret) {
18133+ ret = __vc_get_iattr(path.dentry->d_inode,
18134+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18135+ path_put(&path);
18136+ }
18137+ if (ret)
18138+ return ret;
d337f35e 18139+
4bf69007
AM
18140+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18141+ ret = -EFAULT;
18142+ return ret;
d337f35e
JR
18143+}
18144+
4bf69007 18145+#ifdef CONFIG_COMPAT
d337f35e 18146+
4bf69007 18147+int vc_get_iattr_x32(void __user *data)
d337f35e 18148+{
4bf69007
AM
18149+ struct path path;
18150+ struct vcmd_ctx_iattr_v1_x32 vc_data = { .tag = -1 };
18151+ int ret;
d337f35e 18152+
4bf69007
AM
18153+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18154+ return -EFAULT;
d337f35e 18155+
4bf69007
AM
18156+ ret = user_lpath(compat_ptr(vc_data.name_ptr), &path);
18157+ if (!ret) {
18158+ ret = __vc_get_iattr(path.dentry->d_inode,
18159+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18160+ path_put(&path);
18161+ }
18162+ if (ret)
18163+ return ret;
d337f35e 18164+
2380c486 18165+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
4bf69007
AM
18166+ ret = -EFAULT;
18167+ return ret;
d337f35e
JR
18168+}
18169+
4bf69007 18170+#endif /* CONFIG_COMPAT */
d337f35e 18171+
d337f35e 18172+
4bf69007 18173+int vc_fget_iattr(uint32_t fd, void __user *data)
d337f35e 18174+{
4bf69007
AM
18175+ struct file *filp;
18176+ struct vcmd_ctx_fiattr_v0 vc_data = { .tag = -1 };
d337f35e
JR
18177+ int ret;
18178+
4bf69007 18179+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
18180+ return -EFAULT;
18181+
4bf69007 18182+ filp = fget(fd);
cc23e853 18183+ if (!filp || !filp->f_path.dentry || !filp->f_path.dentry->d_inode)
4bf69007 18184+ return -EBADF;
2380c486 18185+
cc23e853 18186+ ret = __vc_get_iattr(filp->f_path.dentry->d_inode,
4bf69007 18187+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
2380c486 18188+
4bf69007 18189+ fput(filp);
2380c486 18190+
4bf69007
AM
18191+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18192+ ret = -EFAULT;
d337f35e
JR
18193+ return ret;
18194+}
18195+
18196+
4bf69007 18197+static int __vc_set_iattr(struct dentry *de, uint32_t *tag, uint32_t *flags, uint32_t *mask)
2380c486 18198+{
4bf69007
AM
18199+ struct inode *in = de->d_inode;
18200+ int error = 0, is_proc = 0, has_tag = 0;
18201+ struct iattr attr = { 0 };
2380c486 18202+
4bf69007
AM
18203+ if (!in || !in->i_sb)
18204+ return -ESRCH;
2380c486 18205+
4bf69007
AM
18206+ is_proc = (in->i_sb->s_magic == PROC_SUPER_MAGIC);
18207+ if ((*mask & IATTR_FLAGS) && !is_proc)
18208+ return -EINVAL;
2380c486 18209+
4bf69007
AM
18210+ has_tag = IS_TAGGED(in) ||
18211+ (in->i_sb->s_magic == DEVPTS_SUPER_MAGIC);
18212+ if ((*mask & IATTR_TAG) && !has_tag)
18213+ return -EINVAL;
2380c486 18214+
cc23e853 18215+ inode_lock(in);
4bf69007 18216+ if (*mask & IATTR_TAG) {
8ce283e1 18217+ attr.ia_tag = make_ktag(&init_user_ns, *tag);
4bf69007 18218+ attr.ia_valid |= ATTR_TAG;
2380c486
JR
18219+ }
18220+
4bf69007
AM
18221+ if (*mask & IATTR_FLAGS) {
18222+ struct proc_dir_entry *entry = PROC_I(in)->pde;
18223+ unsigned int iflags = PROC_I(in)->vx_flags;
2380c486 18224+
4bf69007
AM
18225+ iflags = (iflags & ~(*mask & IATTR_FLAGS))
18226+ | (*flags & IATTR_FLAGS);
18227+ PROC_I(in)->vx_flags = iflags;
18228+ if (entry)
18229+ entry->vx_flags = iflags;
18230+ }
9f7054f1 18231+
4bf69007
AM
18232+ if (*mask & (IATTR_IMMUTABLE | IATTR_IXUNLINK |
18233+ IATTR_BARRIER | IATTR_COW)) {
18234+ int iflags = in->i_flags;
18235+ int vflags = in->i_vflags;
9f7054f1 18236+
4bf69007
AM
18237+ if (*mask & IATTR_IMMUTABLE) {
18238+ if (*flags & IATTR_IMMUTABLE)
18239+ iflags |= S_IMMUTABLE;
18240+ else
18241+ iflags &= ~S_IMMUTABLE;
18242+ }
18243+ if (*mask & IATTR_IXUNLINK) {
18244+ if (*flags & IATTR_IXUNLINK)
18245+ iflags |= S_IXUNLINK;
18246+ else
18247+ iflags &= ~S_IXUNLINK;
18248+ }
18249+ if (S_ISDIR(in->i_mode) && (*mask & IATTR_BARRIER)) {
18250+ if (*flags & IATTR_BARRIER)
18251+ vflags |= V_BARRIER;
18252+ else
18253+ vflags &= ~V_BARRIER;
18254+ }
18255+ if (S_ISREG(in->i_mode) && (*mask & IATTR_COW)) {
18256+ if (*flags & IATTR_COW)
18257+ vflags |= V_COW;
18258+ else
18259+ vflags &= ~V_COW;
18260+ }
18261+ if (in->i_op && in->i_op->sync_flags) {
18262+ error = in->i_op->sync_flags(in, iflags, vflags);
18263+ if (error)
18264+ goto out;
18265+ }
18266+ }
9f7054f1 18267+
4bf69007
AM
18268+ if (attr.ia_valid) {
18269+ if (in->i_op && in->i_op->setattr)
18270+ error = in->i_op->setattr(de, &attr);
18271+ else {
cc23e853 18272+ error = setattr_prepare(de, &attr);
4bf69007
AM
18273+ if (!error) {
18274+ setattr_copy(in, &attr);
18275+ mark_inode_dirty(in);
18276+ }
18277+ }
9f7054f1 18278+ }
9f7054f1 18279+
4bf69007 18280+out:
cc23e853 18281+ inode_unlock(in);
4bf69007
AM
18282+ return error;
18283+}
2380c486 18284+
4bf69007 18285+int vc_set_iattr(void __user *data)
d337f35e 18286+{
4bf69007
AM
18287+ struct path path;
18288+ struct vcmd_ctx_iattr_v1 vc_data;
18289+ int ret;
d337f35e 18290+
4bf69007
AM
18291+ if (!capable(CAP_LINUX_IMMUTABLE))
18292+ return -EPERM;
18293+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
18294+ return -EFAULT;
18295+
4bf69007
AM
18296+ ret = user_lpath(vc_data.name, &path);
18297+ if (!ret) {
18298+ ret = __vc_set_iattr(path.dentry,
18299+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18300+ path_put(&path);
d337f35e 18301+ }
4bf69007
AM
18302+
18303+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18304+ ret = -EFAULT;
d337f35e
JR
18305+ return ret;
18306+}
18307+
4bf69007
AM
18308+#ifdef CONFIG_COMPAT
18309+
18310+int vc_set_iattr_x32(void __user *data)
d337f35e 18311+{
4bf69007
AM
18312+ struct path path;
18313+ struct vcmd_ctx_iattr_v1_x32 vc_data;
18314+ int ret;
d337f35e 18315+
4bf69007
AM
18316+ if (!capable(CAP_LINUX_IMMUTABLE))
18317+ return -EPERM;
18318+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486
JR
18319+ return -EFAULT;
18320+
4bf69007
AM
18321+ ret = user_lpath(compat_ptr(vc_data.name_ptr), &path);
18322+ if (!ret) {
18323+ ret = __vc_set_iattr(path.dentry,
18324+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18325+ path_put(&path);
2380c486 18326+ }
4bf69007
AM
18327+
18328+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18329+ ret = -EFAULT;
18330+ return ret;
2380c486
JR
18331+}
18332+
4bf69007 18333+#endif /* CONFIG_COMPAT */
2380c486 18334+
4bf69007 18335+int vc_fset_iattr(uint32_t fd, void __user *data)
2380c486 18336+{
4bf69007
AM
18337+ struct file *filp;
18338+ struct vcmd_ctx_fiattr_v0 vc_data;
18339+ int ret;
2380c486 18340+
4bf69007
AM
18341+ if (!capable(CAP_LINUX_IMMUTABLE))
18342+ return -EPERM;
18343+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486
JR
18344+ return -EFAULT;
18345+
4bf69007 18346+ filp = fget(fd);
cc23e853 18347+ if (!filp || !filp->f_path.dentry || !filp->f_path.dentry->d_inode)
4bf69007 18348+ return -EBADF;
2380c486 18349+
cc23e853 18350+ ret = __vc_set_iattr(filp->f_path.dentry, &vc_data.tag,
4bf69007 18351+ &vc_data.flags, &vc_data.mask);
2380c486 18352+
4bf69007 18353+ fput(filp);
2380c486 18354+
4bf69007
AM
18355+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18356+ return -EFAULT;
18357+ return ret;
2380c486
JR
18358+}
18359+
2380c486 18360+
4bf69007 18361+enum { Opt_notagcheck, Opt_tag, Opt_notag, Opt_tagid, Opt_err };
2380c486 18362+
4bf69007
AM
18363+static match_table_t tokens = {
18364+ {Opt_notagcheck, "notagcheck"},
18365+#ifdef CONFIG_PROPAGATE
18366+ {Opt_notag, "notag"},
18367+ {Opt_tag, "tag"},
18368+ {Opt_tagid, "tagid=%u"},
18369+#endif
18370+ {Opt_err, NULL}
18371+};
2380c486 18372+
9f7054f1 18373+
4bf69007
AM
18374+static void __dx_parse_remove(char *string, char *opt)
18375+{
18376+ char *p = strstr(string, opt);
18377+ char *q = p;
2380c486 18378+
4bf69007
AM
18379+ if (p) {
18380+ while (*q != '\0' && *q != ',')
18381+ q++;
18382+ while (*q)
18383+ *p++ = *q++;
18384+ while (*p)
18385+ *p++ = '\0';
2380c486 18386+ }
2380c486
JR
18387+}
18388+
61333608 18389+int dx_parse_tag(char *string, vtag_t *tag, int remove, int *mnt_flags,
4bf69007 18390+ unsigned long *flags)
9f7054f1 18391+{
4bf69007
AM
18392+ int set = 0;
18393+ substring_t args[MAX_OPT_ARGS];
18394+ int token;
18395+ char *s, *p, *opts;
18396+#if defined(CONFIG_PROPAGATE) || defined(CONFIG_VSERVER_DEBUG)
18397+ int option = 0;
18398+#endif
9f7054f1 18399+
4bf69007
AM
18400+ if (!string)
18401+ return 0;
18402+ s = kstrdup(string, GFP_KERNEL | GFP_ATOMIC);
18403+ if (!s)
18404+ return 0;
9f7054f1 18405+
4bf69007
AM
18406+ opts = s;
18407+ while ((p = strsep(&opts, ",")) != NULL) {
18408+ token = match_token(p, tokens, args);
9f7054f1 18409+
4bf69007
AM
18410+ switch (token) {
18411+#ifdef CONFIG_PROPAGATE
18412+ case Opt_tag:
18413+ if (tag)
18414+ *tag = 0;
18415+ if (remove)
18416+ __dx_parse_remove(s, "tag");
18417+ *mnt_flags |= MNT_TAGID;
18418+ set |= MNT_TAGID;
18419+ break;
18420+ case Opt_notag:
18421+ if (remove)
18422+ __dx_parse_remove(s, "notag");
18423+ *mnt_flags |= MNT_NOTAG;
18424+ set |= MNT_NOTAG;
18425+ break;
18426+ case Opt_tagid:
18427+ if (tag && !match_int(args, &option))
18428+ *tag = option;
18429+ if (remove)
18430+ __dx_parse_remove(s, "tagid");
18431+ *mnt_flags |= MNT_TAGID;
18432+ set |= MNT_TAGID;
18433+ break;
18434+#endif /* CONFIG_PROPAGATE */
18435+ case Opt_notagcheck:
18436+ if (remove)
18437+ __dx_parse_remove(s, "notagcheck");
18438+ *flags |= MS_NOTAGCHECK;
18439+ set |= MS_NOTAGCHECK;
18440+ break;
18441+ }
18442+ vxdprintk(VXD_CBIT(tag, 7),
18443+ "dx_parse_tag(" VS_Q("%s") "): %d:#%d",
18444+ p, token, option);
18445+ }
18446+ if (set)
18447+ strcpy(string, s);
18448+ kfree(s);
18449+ return set;
9f7054f1 18450+}
2380c486 18451+
4bf69007 18452+#ifdef CONFIG_PROPAGATE
2380c486 18453+
4bf69007 18454+void __dx_propagate_tag(struct nameidata *nd, struct inode *inode)
2380c486 18455+{
61333608 18456+ vtag_t new_tag = 0;
4bf69007
AM
18457+ struct vfsmount *mnt;
18458+ int propagate;
2380c486 18459+
4bf69007
AM
18460+ if (!nd)
18461+ return;
18462+ mnt = nd->path.mnt;
18463+ if (!mnt)
18464+ return;
2380c486 18465+
4bf69007
AM
18466+ propagate = (mnt->mnt_flags & MNT_TAGID);
18467+ if (propagate)
18468+ new_tag = mnt->mnt_tag;
2380c486 18469+
4bf69007
AM
18470+ vxdprintk(VXD_CBIT(tag, 7),
18471+ "dx_propagate_tag(%p[#%lu.%d]): %d,%d",
18472+ inode, inode->i_ino, inode->i_tag,
18473+ new_tag, (propagate) ? 1 : 0);
18474+
18475+ if (propagate)
18476+ i_tag_write(inode, new_tag);
2380c486
JR
18477+}
18478+
4bf69007 18479+#include <linux/module.h>
2380c486 18480+
4bf69007 18481+EXPORT_SYMBOL_GPL(__dx_propagate_tag);
2380c486 18482+
4bf69007 18483+#endif /* CONFIG_PROPAGATE */
2380c486 18484+
cef7ea10
AM
18485diff -NurpP --minimal linux-4.9.82/kernel/vserver/limit.c linux-4.9.82-vs2.3.9.7/kernel/vserver/limit.c
18486--- linux-4.9.82/kernel/vserver/limit.c 1970-01-01 00:00:00.000000000 +0000
18487+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/limit.c 2018-01-25 00:07:15.000000000 +0000
369dbd59 18488@@ -0,0 +1,386 @@
4bf69007
AM
18489+/*
18490+ * linux/kernel/vserver/limit.c
18491+ *
18492+ * Virtual Server: Context Limits
18493+ *
cc23e853 18494+ * Copyright (C) 2004-2010 Herbert P?tzl
4bf69007
AM
18495+ *
18496+ * V0.01 broken out from vcontext V0.05
18497+ * V0.02 changed vcmds to vxi arg
18498+ * V0.03 added memory cgroup support
18499+ *
18500+ */
2380c486 18501+
4bf69007
AM
18502+#include <linux/sched.h>
18503+#include <linux/module.h>
18504+#include <linux/memcontrol.h>
cc23e853 18505+#include <linux/page_counter.h>
4bf69007
AM
18506+#include <linux/vs_limit.h>
18507+#include <linux/vserver/limit.h>
18508+#include <linux/vserver/limit_cmd.h>
2380c486 18509+
4bf69007 18510+#include <asm/uaccess.h>
d337f35e 18511+
d337f35e 18512+
4bf69007
AM
18513+const char *vlimit_name[NUM_LIMITS] = {
18514+ [RLIMIT_CPU] = "CPU",
18515+ [RLIMIT_NPROC] = "NPROC",
18516+ [RLIMIT_NOFILE] = "NOFILE",
18517+ [RLIMIT_LOCKS] = "LOCKS",
18518+ [RLIMIT_SIGPENDING] = "SIGP",
18519+ [RLIMIT_MSGQUEUE] = "MSGQ",
d337f35e 18520+
4bf69007
AM
18521+ [VLIMIT_NSOCK] = "NSOCK",
18522+ [VLIMIT_OPENFD] = "OPENFD",
18523+ [VLIMIT_SHMEM] = "SHMEM",
18524+ [VLIMIT_DENTRY] = "DENTRY",
18525+};
2380c486 18526+
4bf69007 18527+EXPORT_SYMBOL_GPL(vlimit_name);
2380c486 18528+
4bf69007 18529+#define MASK_ENTRY(x) (1 << (x))
d337f35e 18530+
4bf69007
AM
18531+const struct vcmd_ctx_rlimit_mask_v0 vlimit_mask = {
18532+ /* minimum */
18533+ 0
18534+ , /* softlimit */
18535+ 0
18536+ , /* maximum */
18537+ MASK_ENTRY( RLIMIT_NPROC ) |
18538+ MASK_ENTRY( RLIMIT_NOFILE ) |
18539+ MASK_ENTRY( RLIMIT_LOCKS ) |
18540+ MASK_ENTRY( RLIMIT_MSGQUEUE ) |
d337f35e 18541+
4bf69007
AM
18542+ MASK_ENTRY( VLIMIT_NSOCK ) |
18543+ MASK_ENTRY( VLIMIT_OPENFD ) |
18544+ MASK_ENTRY( VLIMIT_SHMEM ) |
18545+ MASK_ENTRY( VLIMIT_DENTRY ) |
18546+ 0
18547+};
18548+ /* accounting only */
18549+uint32_t account_mask =
18550+ MASK_ENTRY( VLIMIT_SEMARY ) |
18551+ MASK_ENTRY( VLIMIT_NSEMS ) |
18552+ MASK_ENTRY( VLIMIT_MAPPED ) |
18553+ 0;
d337f35e 18554+
4bf69007
AM
18555+
18556+static int is_valid_vlimit(int id)
18557+{
18558+ uint32_t mask = vlimit_mask.minimum |
18559+ vlimit_mask.softlimit | vlimit_mask.maximum;
18560+ return mask & (1 << id);
d337f35e
JR
18561+}
18562+
4bf69007 18563+static int is_accounted_vlimit(int id)
d337f35e 18564+{
4bf69007
AM
18565+ if (is_valid_vlimit(id))
18566+ return 1;
18567+ return account_mask & (1 << id);
18568+}
d337f35e 18569+
d337f35e 18570+
4bf69007
AM
18571+static inline uint64_t vc_get_soft(struct vx_info *vxi, int id)
18572+{
18573+ rlim_t limit = __rlim_soft(&vxi->limit, id);
18574+ return VX_VLIM(limit);
18575+}
d337f35e 18576+
4bf69007
AM
18577+static inline uint64_t vc_get_hard(struct vx_info *vxi, int id)
18578+{
18579+ rlim_t limit = __rlim_hard(&vxi->limit, id);
18580+ return VX_VLIM(limit);
18581+}
d337f35e 18582+
4bf69007
AM
18583+static int do_get_rlimit(struct vx_info *vxi, uint32_t id,
18584+ uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum)
18585+{
18586+ if (!is_valid_vlimit(id))
18587+ return -EINVAL;
18588+
18589+ if (minimum)
18590+ *minimum = CRLIM_UNSET;
18591+ if (softlimit)
18592+ *softlimit = vc_get_soft(vxi, id);
18593+ if (maximum)
18594+ *maximum = vc_get_hard(vxi, id);
d337f35e
JR
18595+ return 0;
18596+}
18597+
4bf69007 18598+int vc_get_rlimit(struct vx_info *vxi, void __user *data)
d337f35e 18599+{
4bf69007
AM
18600+ struct vcmd_ctx_rlimit_v0 vc_data;
18601+ int ret;
d337f35e 18602+
4bf69007
AM
18603+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18604+ return -EFAULT;
18605+
18606+ ret = do_get_rlimit(vxi, vc_data.id,
18607+ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
18608+ if (ret)
18609+ return ret;
d337f35e 18610+
2380c486 18611+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
d337f35e
JR
18612+ return -EFAULT;
18613+ return 0;
18614+}
18615+
4bf69007
AM
18616+static int do_set_rlimit(struct vx_info *vxi, uint32_t id,
18617+ uint64_t minimum, uint64_t softlimit, uint64_t maximum)
d337f35e 18618+{
4bf69007
AM
18619+ if (!is_valid_vlimit(id))
18620+ return -EINVAL;
d337f35e 18621+
4bf69007
AM
18622+ if (maximum != CRLIM_KEEP)
18623+ __rlim_hard(&vxi->limit, id) = VX_RLIM(maximum);
18624+ if (softlimit != CRLIM_KEEP)
18625+ __rlim_soft(&vxi->limit, id) = VX_RLIM(softlimit);
18626+
18627+ /* clamp soft limit */
18628+ if (__rlim_soft(&vxi->limit, id) > __rlim_hard(&vxi->limit, id))
18629+ __rlim_soft(&vxi->limit, id) = __rlim_hard(&vxi->limit, id);
d337f35e 18630+
d337f35e
JR
18631+ return 0;
18632+}
18633+
4bf69007
AM
18634+int vc_set_rlimit(struct vx_info *vxi, void __user *data)
18635+{
18636+ struct vcmd_ctx_rlimit_v0 vc_data;
d337f35e 18637+
4bf69007
AM
18638+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18639+ return -EFAULT;
d337f35e 18640+
4bf69007
AM
18641+ return do_set_rlimit(vxi, vc_data.id,
18642+ vc_data.minimum, vc_data.softlimit, vc_data.maximum);
18643+}
d337f35e 18644+
4bf69007 18645+#ifdef CONFIG_IA32_EMULATION
2380c486 18646+
4bf69007
AM
18647+int vc_set_rlimit_x32(struct vx_info *vxi, void __user *data)
18648+{
18649+ struct vcmd_ctx_rlimit_v0_x32 vc_data;
d337f35e 18650+
4bf69007
AM
18651+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18652+ return -EFAULT;
d337f35e 18653+
4bf69007
AM
18654+ return do_set_rlimit(vxi, vc_data.id,
18655+ vc_data.minimum, vc_data.softlimit, vc_data.maximum);
18656+}
d337f35e 18657+
4bf69007
AM
18658+int vc_get_rlimit_x32(struct vx_info *vxi, void __user *data)
18659+{
18660+ struct vcmd_ctx_rlimit_v0_x32 vc_data;
18661+ int ret;
d337f35e 18662+
4bf69007
AM
18663+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18664+ return -EFAULT;
d337f35e 18665+
4bf69007
AM
18666+ ret = do_get_rlimit(vxi, vc_data.id,
18667+ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
18668+ if (ret)
18669+ return ret;
2380c486 18670+
4bf69007
AM
18671+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18672+ return -EFAULT;
18673+ return 0;
2380c486 18674+}
d337f35e 18675+
4bf69007 18676+#endif /* CONFIG_IA32_EMULATION */
d337f35e
JR
18677+
18678+
4bf69007
AM
18679+int vc_get_rlimit_mask(uint32_t id, void __user *data)
18680+{
18681+ if (copy_to_user(data, &vlimit_mask, sizeof(vlimit_mask)))
18682+ return -EFAULT;
18683+ return 0;
18684+}
d337f35e
JR
18685+
18686+
4bf69007
AM
18687+static inline void vx_reset_hits(struct _vx_limit *limit)
18688+{
18689+ int lim;
d337f35e 18690+
4bf69007
AM
18691+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18692+ atomic_set(&__rlim_lhit(limit, lim), 0);
18693+ }
18694+}
d337f35e 18695+
4bf69007 18696+int vc_reset_hits(struct vx_info *vxi, void __user *data)
d337f35e 18697+{
4bf69007
AM
18698+ vx_reset_hits(&vxi->limit);
18699+ return 0;
d337f35e
JR
18700+}
18701+
4bf69007 18702+static inline void vx_reset_minmax(struct _vx_limit *limit)
d337f35e 18703+{
4bf69007
AM
18704+ rlim_t value;
18705+ int lim;
18706+
18707+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18708+ value = __rlim_get(limit, lim);
18709+ __rlim_rmax(limit, lim) = value;
18710+ __rlim_rmin(limit, lim) = value;
18711+ }
d337f35e
JR
18712+}
18713+
4bf69007 18714+int vc_reset_minmax(struct vx_info *vxi, void __user *data)
d337f35e 18715+{
4bf69007
AM
18716+ vx_reset_minmax(&vxi->limit);
18717+ return 0;
d337f35e
JR
18718+}
18719+
18720+
4bf69007 18721+int vc_rlimit_stat(struct vx_info *vxi, void __user *data)
d337f35e 18722+{
4bf69007
AM
18723+ struct vcmd_rlimit_stat_v0 vc_data;
18724+ struct _vx_limit *limit = &vxi->limit;
18725+ int id;
d337f35e 18726+
4bf69007
AM
18727+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18728+ return -EFAULT;
d337f35e 18729+
4bf69007
AM
18730+ id = vc_data.id;
18731+ if (!is_accounted_vlimit(id))
18732+ return -EINVAL;
2380c486 18733+
4bf69007
AM
18734+ vx_limit_fixup(limit, id);
18735+ vc_data.hits = atomic_read(&__rlim_lhit(limit, id));
18736+ vc_data.value = __rlim_get(limit, id);
18737+ vc_data.minimum = __rlim_rmin(limit, id);
18738+ vc_data.maximum = __rlim_rmax(limit, id);
2380c486 18739+
4bf69007
AM
18740+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18741+ return -EFAULT;
18742+ return 0;
d337f35e
JR
18743+}
18744+
d337f35e 18745+
cc23e853 18746+#ifdef CONFIG_MEMCG
369dbd59
AM
18747+
18748+void dump_sysinfo(struct sysinfo *si)
18749+{
18750+ printk(KERN_INFO "sysinfo: memunit=%u\n"
18751+ "\ttotalram:\t%lu\n"
18752+ "\tfreeram:\t%lu\n"
18753+ "\tsharedram:\t%lu\n"
18754+ "\tbufferram:\t%lu\n"
18755+ "\ttotalswap:\t%lu\n"
18756+ "\tfreeswap:\t%lu\n"
18757+ "\ttotalhigh:\t%lu\n"
18758+ "\tfreehigh:\t%lu\n",
18759+ si->mem_unit,
18760+ si->totalram,
18761+ si->freeram,
18762+ si->sharedram,
18763+ si->bufferram,
18764+ si->totalswap,
18765+ si->freeswap,
18766+ si->totalhigh,
18767+ si->freehigh);
18768+}
18769+
4bf69007 18770+void vx_vsi_meminfo(struct sysinfo *val)
d337f35e 18771+{
4bf69007 18772+ struct mem_cgroup *mcg;
369dbd59
AM
18773+ unsigned long res_limit, res_usage;
18774+ unsigned shift;
18775+
18776+ if (VXD_CBIT(cvirt, 4))
18777+ dump_sysinfo(val);
d337f35e 18778+
4bf69007
AM
18779+ rcu_read_lock();
18780+ mcg = mem_cgroup_from_task(current);
369dbd59
AM
18781+ if (VXD_CBIT(cvirt, 5))
18782+ dump_mem_cgroup(mcg);
4bf69007
AM
18783+ rcu_read_unlock();
18784+ if (!mcg)
18785+ goto out;
d337f35e 18786+
cc23e853
AM
18787+ res_limit = mem_cgroup_mem_limit_pages(mcg);
18788+ res_usage = mem_cgroup_mem_usage_pages(mcg);
369dbd59 18789+ shift = val->mem_unit == 1 ? PAGE_SHIFT : 0;
2380c486 18790+
cc23e853 18791+ if (res_limit != PAGE_COUNTER_MAX)
369dbd59
AM
18792+ val->totalram = res_limit << shift;
18793+ val->freeram = val->totalram - (res_usage << shift);
4bf69007
AM
18794+ val->bufferram = 0;
18795+ val->totalhigh = 0;
18796+ val->freehigh = 0;
18797+out:
4bf69007 18798+ return;
d337f35e
JR
18799+}
18800+
4bf69007 18801+void vx_vsi_swapinfo(struct sysinfo *val)
d337f35e 18802+{
4bf69007
AM
18803+#ifdef CONFIG_MEMCG_SWAP
18804+ struct mem_cgroup *mcg;
369dbd59
AM
18805+ unsigned long res_limit, res_usage, memsw_limit, memsw_usage;
18806+ signed long swap_limit, swap_usage;
18807+ unsigned shift;
18808+
18809+ if (VXD_CBIT(cvirt, 6))
18810+ dump_sysinfo(val);
d337f35e 18811+
4bf69007
AM
18812+ rcu_read_lock();
18813+ mcg = mem_cgroup_from_task(current);
369dbd59
AM
18814+ if (VXD_CBIT(cvirt, 7))
18815+ dump_mem_cgroup(mcg);
4bf69007
AM
18816+ rcu_read_unlock();
18817+ if (!mcg)
18818+ goto out;
d337f35e 18819+
cc23e853 18820+ res_limit = mem_cgroup_mem_limit_pages(mcg);
d337f35e 18821+
4bf69007 18822+ /* memory unlimited */
cc23e853 18823+ if (res_limit == PAGE_COUNTER_MAX)
4bf69007 18824+ goto out;
d337f35e 18825+
369dbd59
AM
18826+ res_usage = mem_cgroup_mem_usage_pages(mcg);
18827+ memsw_limit = mem_cgroup_memsw_limit_pages(mcg);
18828+ memsw_usage = mem_cgroup_memsw_usage_pages(mcg);
18829+ shift = val->mem_unit == 1 ? PAGE_SHIFT : 0;
18830+
4bf69007
AM
18831+ swap_limit = memsw_limit - res_limit;
18832+ /* we have a swap limit? */
cc23e853 18833+ if (memsw_limit != PAGE_COUNTER_MAX)
369dbd59 18834+ val->totalswap = swap_limit << shift;
d337f35e 18835+
4bf69007
AM
18836+ /* calculate swap part */
18837+ swap_usage = (memsw_usage > res_usage) ?
18838+ memsw_usage - res_usage : 0;
18839+
18840+ /* total shown minus usage gives free swap */
18841+ val->freeswap = (swap_usage < swap_limit) ?
369dbd59 18842+ val->totalswap - (swap_usage << shift) : 0;
4bf69007
AM
18843+out:
18844+#else /* !CONFIG_MEMCG_SWAP */
18845+ val->totalswap = 0;
18846+ val->freeswap = 0;
18847+#endif /* !CONFIG_MEMCG_SWAP */
4bf69007 18848+ return;
d337f35e
JR
18849+}
18850+
4bf69007 18851+long vx_vsi_cached(struct sysinfo *val)
d337f35e 18852+{
4bf69007 18853+ long cache = 0;
cc23e853 18854+#ifdef CONFIG_MEMCG_BROKEN
4bf69007 18855+ struct mem_cgroup *mcg;
d337f35e 18856+
369dbd59
AM
18857+ if (VXD_CBIT(cvirt, 8))
18858+ dump_sysinfo(val);
18859+
4bf69007
AM
18860+ rcu_read_lock();
18861+ mcg = mem_cgroup_from_task(current);
369dbd59
AM
18862+ if (VXD_CBIT(cvirt, 9))
18863+ dump_mem_cgroup(mcg);
4bf69007
AM
18864+ rcu_read_unlock();
18865+ if (!mcg)
18866+ goto out;
2380c486 18867+
cc23e853 18868+ // cache = mem_cgroup_stat_read_cache(mcg);
4bf69007 18869+out:
2380c486 18870+#endif
4bf69007 18871+ return cache;
d337f35e 18872+}
cc23e853 18873+#endif /* !CONFIG_MEMCG */
d337f35e 18874+
cef7ea10
AM
18875diff -NurpP --minimal linux-4.9.82/kernel/vserver/limit_init.h linux-4.9.82-vs2.3.9.7/kernel/vserver/limit_init.h
18876--- linux-4.9.82/kernel/vserver/limit_init.h 1970-01-01 00:00:00.000000000 +0000
18877+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/limit_init.h 2018-01-10 02:50:49.000000000 +0000
4bf69007 18878@@ -0,0 +1,31 @@
d337f35e
JR
18879+
18880+
4bf69007
AM
18881+static inline void vx_info_init_limit(struct _vx_limit *limit)
18882+{
18883+ int lim;
d337f35e 18884+
4bf69007
AM
18885+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18886+ __rlim_soft(limit, lim) = RLIM_INFINITY;
18887+ __rlim_hard(limit, lim) = RLIM_INFINITY;
18888+ __rlim_set(limit, lim, 0);
18889+ atomic_set(&__rlim_lhit(limit, lim), 0);
18890+ __rlim_rmin(limit, lim) = 0;
18891+ __rlim_rmax(limit, lim) = 0;
18892+ }
18893+}
d337f35e 18894+
4bf69007 18895+static inline void vx_info_exit_limit(struct _vx_limit *limit)
d337f35e 18896+{
4bf69007
AM
18897+ rlim_t value;
18898+ int lim;
d337f35e 18899+
4bf69007
AM
18900+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18901+ if ((1 << lim) & VLIM_NOCHECK)
18902+ continue;
18903+ value = __rlim_get(limit, lim);
18904+ vxwprintk_xid(value,
18905+ "!!! limit: %p[%s,%d] = %ld on exit.",
18906+ limit, vlimit_name[lim], lim, (long)value);
18907+ }
18908+}
d337f35e 18909+
cef7ea10
AM
18910diff -NurpP --minimal linux-4.9.82/kernel/vserver/limit_proc.h linux-4.9.82-vs2.3.9.7/kernel/vserver/limit_proc.h
18911--- linux-4.9.82/kernel/vserver/limit_proc.h 1970-01-01 00:00:00.000000000 +0000
18912+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/limit_proc.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
18913@@ -0,0 +1,57 @@
18914+#ifndef _VX_LIMIT_PROC_H
18915+#define _VX_LIMIT_PROC_H
d337f35e 18916+
4bf69007 18917+#include <linux/vserver/limit_int.h>
d337f35e 18918+
d337f35e 18919+
4bf69007
AM
18920+#define VX_LIMIT_FMT ":\t%8ld\t%8ld/%8ld\t%8lld/%8lld\t%6d\n"
18921+#define VX_LIMIT_TOP \
18922+ "Limit\t current\t min/max\t\t soft/hard\t\thits\n"
d337f35e 18923+
4bf69007
AM
18924+#define VX_LIMIT_ARG(r) \
18925+ (unsigned long)__rlim_get(limit, r), \
18926+ (unsigned long)__rlim_rmin(limit, r), \
18927+ (unsigned long)__rlim_rmax(limit, r), \
18928+ VX_VLIM(__rlim_soft(limit, r)), \
18929+ VX_VLIM(__rlim_hard(limit, r)), \
18930+ atomic_read(&__rlim_lhit(limit, r))
d337f35e 18931+
4bf69007
AM
18932+static inline int vx_info_proc_limit(struct _vx_limit *limit, char *buffer)
18933+{
18934+ vx_limit_fixup(limit, -1);
18935+ return sprintf(buffer, VX_LIMIT_TOP
18936+ "PROC" VX_LIMIT_FMT
18937+ "VM" VX_LIMIT_FMT
18938+ "VML" VX_LIMIT_FMT
18939+ "RSS" VX_LIMIT_FMT
18940+ "ANON" VX_LIMIT_FMT
18941+ "RMAP" VX_LIMIT_FMT
18942+ "FILES" VX_LIMIT_FMT
18943+ "OFD" VX_LIMIT_FMT
18944+ "LOCKS" VX_LIMIT_FMT
18945+ "SOCK" VX_LIMIT_FMT
18946+ "MSGQ" VX_LIMIT_FMT
18947+ "SHM" VX_LIMIT_FMT
18948+ "SEMA" VX_LIMIT_FMT
18949+ "SEMS" VX_LIMIT_FMT
18950+ "DENT" VX_LIMIT_FMT,
18951+ VX_LIMIT_ARG(RLIMIT_NPROC),
18952+ VX_LIMIT_ARG(RLIMIT_AS),
18953+ VX_LIMIT_ARG(RLIMIT_MEMLOCK),
18954+ VX_LIMIT_ARG(RLIMIT_RSS),
18955+ VX_LIMIT_ARG(VLIMIT_ANON),
18956+ VX_LIMIT_ARG(VLIMIT_MAPPED),
18957+ VX_LIMIT_ARG(RLIMIT_NOFILE),
18958+ VX_LIMIT_ARG(VLIMIT_OPENFD),
18959+ VX_LIMIT_ARG(RLIMIT_LOCKS),
18960+ VX_LIMIT_ARG(VLIMIT_NSOCK),
18961+ VX_LIMIT_ARG(RLIMIT_MSGQUEUE),
18962+ VX_LIMIT_ARG(VLIMIT_SHMEM),
18963+ VX_LIMIT_ARG(VLIMIT_SEMARY),
18964+ VX_LIMIT_ARG(VLIMIT_NSEMS),
18965+ VX_LIMIT_ARG(VLIMIT_DENTRY));
d337f35e
JR
18966+}
18967+
4bf69007 18968+#endif /* _VX_LIMIT_PROC_H */
d337f35e 18969+
d337f35e 18970+
cef7ea10
AM
18971diff -NurpP --minimal linux-4.9.82/kernel/vserver/network.c linux-4.9.82-vs2.3.9.7/kernel/vserver/network.c
18972--- linux-4.9.82/kernel/vserver/network.c 1970-01-01 00:00:00.000000000 +0000
18973+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/network.c 2018-01-10 02:50:49.000000000 +0000
5cb1760b 18974@@ -0,0 +1,1053 @@
d337f35e 18975+/*
4bf69007 18976+ * linux/kernel/vserver/network.c
d337f35e 18977+ *
4bf69007
AM
18978+ * Virtual Server: Network Support
18979+ *
cc23e853 18980+ * Copyright (C) 2003-2007 Herbert P?tzl
4bf69007
AM
18981+ *
18982+ * V0.01 broken out from vcontext V0.05
18983+ * V0.02 cleaned up implementation
18984+ * V0.03 added equiv nx commands
18985+ * V0.04 switch to RCU based hash
18986+ * V0.05 and back to locking again
18987+ * V0.06 changed vcmds to nxi arg
18988+ * V0.07 have __create claim() the nxi
d337f35e 18989+ *
d337f35e 18990+ */
d337f35e 18991+
4bf69007
AM
18992+#include <linux/err.h>
18993+#include <linux/slab.h>
18994+#include <linux/rcupdate.h>
18995+#include <net/ipv6.h>
d337f35e 18996+
4bf69007
AM
18997+#include <linux/vs_network.h>
18998+#include <linux/vs_pid.h>
18999+#include <linux/vserver/network_cmd.h>
d337f35e
JR
19000+
19001+
4bf69007
AM
19002+atomic_t nx_global_ctotal = ATOMIC_INIT(0);
19003+atomic_t nx_global_cactive = ATOMIC_INIT(0);
d337f35e 19004+
4bf69007
AM
19005+static struct kmem_cache *nx_addr_v4_cachep = NULL;
19006+static struct kmem_cache *nx_addr_v6_cachep = NULL;
d337f35e 19007+
d337f35e 19008+
4bf69007 19009+static int __init init_network(void)
d337f35e 19010+{
4bf69007
AM
19011+ nx_addr_v4_cachep = kmem_cache_create("nx_v4_addr_cache",
19012+ sizeof(struct nx_addr_v4), 0,
19013+ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
19014+ nx_addr_v6_cachep = kmem_cache_create("nx_v6_addr_cache",
19015+ sizeof(struct nx_addr_v6), 0,
19016+ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
d337f35e
JR
19017+ return 0;
19018+}
19019+
19020+
4bf69007 19021+/* __alloc_nx_addr_v4() */
d337f35e 19022+
4bf69007 19023+static inline struct nx_addr_v4 *__alloc_nx_addr_v4(void)
d337f35e 19024+{
4bf69007
AM
19025+ struct nx_addr_v4 *nxa = kmem_cache_alloc(
19026+ nx_addr_v4_cachep, GFP_KERNEL);
92598135 19027+
4bf69007
AM
19028+ if (!IS_ERR(nxa))
19029+ memset(nxa, 0, sizeof(*nxa));
19030+ return nxa;
d337f35e
JR
19031+}
19032+
4bf69007 19033+/* __dealloc_nx_addr_v4() */
d337f35e 19034+
4bf69007
AM
19035+static inline void __dealloc_nx_addr_v4(struct nx_addr_v4 *nxa)
19036+{
19037+ kmem_cache_free(nx_addr_v4_cachep, nxa);
19038+}
d337f35e 19039+
4bf69007 19040+/* __dealloc_nx_addr_v4_all() */
d337f35e 19041+
4bf69007 19042+static inline void __dealloc_nx_addr_v4_all(struct nx_addr_v4 *nxa)
d337f35e 19043+{
4bf69007
AM
19044+ while (nxa) {
19045+ struct nx_addr_v4 *next = nxa->next;
d337f35e 19046+
4bf69007
AM
19047+ __dealloc_nx_addr_v4(nxa);
19048+ nxa = next;
19049+ }
19050+}
d337f35e 19051+
d337f35e 19052+
4bf69007 19053+#ifdef CONFIG_IPV6
d337f35e 19054+
4bf69007 19055+/* __alloc_nx_addr_v6() */
d337f35e 19056+
4bf69007
AM
19057+static inline struct nx_addr_v6 *__alloc_nx_addr_v6(void)
19058+{
19059+ struct nx_addr_v6 *nxa = kmem_cache_alloc(
19060+ nx_addr_v6_cachep, GFP_KERNEL);
d337f35e 19061+
4bf69007
AM
19062+ if (!IS_ERR(nxa))
19063+ memset(nxa, 0, sizeof(*nxa));
19064+ return nxa;
d337f35e
JR
19065+}
19066+
4bf69007
AM
19067+/* __dealloc_nx_addr_v6() */
19068+
19069+static inline void __dealloc_nx_addr_v6(struct nx_addr_v6 *nxa)
d337f35e 19070+{
4bf69007
AM
19071+ kmem_cache_free(nx_addr_v6_cachep, nxa);
19072+}
d337f35e 19073+
4bf69007 19074+/* __dealloc_nx_addr_v6_all() */
d337f35e 19075+
4bf69007
AM
19076+static inline void __dealloc_nx_addr_v6_all(struct nx_addr_v6 *nxa)
19077+{
19078+ while (nxa) {
19079+ struct nx_addr_v6 *next = nxa->next;
d337f35e 19080+
4bf69007
AM
19081+ __dealloc_nx_addr_v6(nxa);
19082+ nxa = next;
19083+ }
19084+}
d337f35e 19085+
4bf69007 19086+#endif /* CONFIG_IPV6 */
d337f35e 19087+
4bf69007 19088+/* __alloc_nx_info()
d337f35e 19089+
4bf69007
AM
19090+ * allocate an initialized nx_info struct
19091+ * doesn't make it visible (hash) */
d337f35e 19092+
61333608 19093+static struct nx_info *__alloc_nx_info(vnid_t nid)
d337f35e 19094+{
4bf69007 19095+ struct nx_info *new = NULL;
d337f35e 19096+
4bf69007 19097+ vxdprintk(VXD_CBIT(nid, 1), "alloc_nx_info(%d)*", nid);
d337f35e 19098+
4bf69007
AM
19099+ /* would this benefit from a slab cache? */
19100+ new = kmalloc(sizeof(struct nx_info), GFP_KERNEL);
19101+ if (!new)
19102+ return 0;
d337f35e 19103+
4bf69007
AM
19104+ memset(new, 0, sizeof(struct nx_info));
19105+ new->nx_id = nid;
19106+ INIT_HLIST_NODE(&new->nx_hlist);
19107+ atomic_set(&new->nx_usecnt, 0);
19108+ atomic_set(&new->nx_tasks, 0);
19109+ spin_lock_init(&new->addr_lock);
19110+ new->nx_state = 0;
d337f35e 19111+
4bf69007 19112+ new->nx_flags = NXF_INIT_SET;
d337f35e 19113+
4bf69007 19114+ /* rest of init goes here */
d337f35e 19115+
4bf69007
AM
19116+ new->v4_lback.s_addr = htonl(INADDR_LOOPBACK);
19117+ new->v4_bcast.s_addr = htonl(INADDR_BROADCAST);
19118+
19119+ vxdprintk(VXD_CBIT(nid, 0),
19120+ "alloc_nx_info(%d) = %p", nid, new);
19121+ atomic_inc(&nx_global_ctotal);
19122+ return new;
d337f35e
JR
19123+}
19124+
4bf69007 19125+/* __dealloc_nx_info()
d337f35e 19126+
4bf69007 19127+ * final disposal of nx_info */
d337f35e 19128+
4bf69007
AM
19129+static void __dealloc_nx_info(struct nx_info *nxi)
19130+{
19131+ vxdprintk(VXD_CBIT(nid, 0),
19132+ "dealloc_nx_info(%p)", nxi);
d337f35e 19133+
4bf69007
AM
19134+ nxi->nx_hlist.next = LIST_POISON1;
19135+ nxi->nx_id = -1;
d337f35e 19136+
4bf69007
AM
19137+ BUG_ON(atomic_read(&nxi->nx_usecnt));
19138+ BUG_ON(atomic_read(&nxi->nx_tasks));
19139+
19140+ __dealloc_nx_addr_v4_all(nxi->v4.next);
19141+#ifdef CONFIG_IPV6
19142+ __dealloc_nx_addr_v6_all(nxi->v6.next);
19143+#endif
19144+
19145+ nxi->nx_state |= NXS_RELEASED;
19146+ kfree(nxi);
19147+ atomic_dec(&nx_global_ctotal);
d337f35e
JR
19148+}
19149+
4bf69007
AM
19150+static void __shutdown_nx_info(struct nx_info *nxi)
19151+{
19152+ nxi->nx_state |= NXS_SHUTDOWN;
19153+ vs_net_change(nxi, VSC_NETDOWN);
19154+}
d337f35e 19155+
4bf69007 19156+/* exported stuff */
d337f35e 19157+
4bf69007
AM
19158+void free_nx_info(struct nx_info *nxi)
19159+{
19160+ /* context shutdown is mandatory */
19161+ BUG_ON(nxi->nx_state != NXS_SHUTDOWN);
d337f35e 19162+
4bf69007
AM
19163+ /* context must not be hashed */
19164+ BUG_ON(nxi->nx_state & NXS_HASHED);
d337f35e 19165+
4bf69007
AM
19166+ BUG_ON(atomic_read(&nxi->nx_usecnt));
19167+ BUG_ON(atomic_read(&nxi->nx_tasks));
d337f35e 19168+
4bf69007
AM
19169+ __dealloc_nx_info(nxi);
19170+}
d337f35e 19171+
d337f35e 19172+
4bf69007
AM
19173+void __nx_set_lback(struct nx_info *nxi)
19174+{
19175+ int nid = nxi->nx_id;
19176+ __be32 lback = htonl(INADDR_LOOPBACK ^ ((nid & 0xFFFF) << 8));
d337f35e 19177+
4bf69007
AM
19178+ nxi->v4_lback.s_addr = lback;
19179+}
d337f35e 19180+
4bf69007
AM
19181+extern int __nx_inet_add_lback(__be32 addr);
19182+extern int __nx_inet_del_lback(__be32 addr);
d337f35e
JR
19183+
19184+
4bf69007 19185+/* hash table for nx_info hash */
d337f35e 19186+
4bf69007 19187+#define NX_HASH_SIZE 13
d337f35e 19188+
4bf69007
AM
19189+struct hlist_head nx_info_hash[NX_HASH_SIZE];
19190+
19191+static DEFINE_SPINLOCK(nx_info_hash_lock);
19192+
19193+
61333608 19194+static inline unsigned int __hashval(vnid_t nid)
d337f35e 19195+{
4bf69007 19196+ return (nid % NX_HASH_SIZE);
d337f35e
JR
19197+}
19198+
d337f35e 19199+
d337f35e 19200+
4bf69007 19201+/* __hash_nx_info()
d337f35e 19202+
4bf69007
AM
19203+ * add the nxi to the global hash table
19204+ * requires the hash_lock to be held */
19205+
19206+static inline void __hash_nx_info(struct nx_info *nxi)
d337f35e 19207+{
4bf69007 19208+ struct hlist_head *head;
d337f35e 19209+
4bf69007
AM
19210+ vxd_assert_lock(&nx_info_hash_lock);
19211+ vxdprintk(VXD_CBIT(nid, 4),
19212+ "__hash_nx_info: %p[#%d]", nxi, nxi->nx_id);
d337f35e 19213+
4bf69007
AM
19214+ /* context must not be hashed */
19215+ BUG_ON(nx_info_state(nxi, NXS_HASHED));
d337f35e 19216+
4bf69007
AM
19217+ nxi->nx_state |= NXS_HASHED;
19218+ head = &nx_info_hash[__hashval(nxi->nx_id)];
19219+ hlist_add_head(&nxi->nx_hlist, head);
19220+ atomic_inc(&nx_global_cactive);
19221+}
d337f35e 19222+
4bf69007 19223+/* __unhash_nx_info()
d337f35e 19224+
4bf69007
AM
19225+ * remove the nxi from the global hash table
19226+ * requires the hash_lock to be held */
d337f35e 19227+
4bf69007
AM
19228+static inline void __unhash_nx_info(struct nx_info *nxi)
19229+{
19230+ vxd_assert_lock(&nx_info_hash_lock);
19231+ vxdprintk(VXD_CBIT(nid, 4),
19232+ "__unhash_nx_info: %p[#%d.%d.%d]", nxi, nxi->nx_id,
19233+ atomic_read(&nxi->nx_usecnt), atomic_read(&nxi->nx_tasks));
d337f35e 19234+
4bf69007
AM
19235+ /* context must be hashed */
19236+ BUG_ON(!nx_info_state(nxi, NXS_HASHED));
19237+ /* but without tasks */
19238+ BUG_ON(atomic_read(&nxi->nx_tasks));
d337f35e 19239+
4bf69007
AM
19240+ nxi->nx_state &= ~NXS_HASHED;
19241+ hlist_del(&nxi->nx_hlist);
19242+ atomic_dec(&nx_global_cactive);
d337f35e
JR
19243+}
19244+
d337f35e 19245+
4bf69007 19246+/* __lookup_nx_info()
d337f35e 19247+
4bf69007
AM
19248+ * requires the hash_lock to be held
19249+ * doesn't increment the nx_refcnt */
d337f35e 19250+
61333608 19251+static inline struct nx_info *__lookup_nx_info(vnid_t nid)
d337f35e 19252+{
4bf69007
AM
19253+ struct hlist_head *head = &nx_info_hash[__hashval(nid)];
19254+ struct hlist_node *pos;
19255+ struct nx_info *nxi;
d337f35e 19256+
4bf69007
AM
19257+ vxd_assert_lock(&nx_info_hash_lock);
19258+ hlist_for_each(pos, head) {
19259+ nxi = hlist_entry(pos, struct nx_info, nx_hlist);
19260+
19261+ if (nxi->nx_id == nid)
19262+ goto found;
d337f35e 19263+ }
4bf69007
AM
19264+ nxi = NULL;
19265+found:
19266+ vxdprintk(VXD_CBIT(nid, 0),
19267+ "__lookup_nx_info(#%u): %p[#%u]",
19268+ nid, nxi, nxi ? nxi->nx_id : 0);
19269+ return nxi;
d337f35e
JR
19270+}
19271+
19272+
4bf69007 19273+/* __create_nx_info()
d337f35e 19274+
4bf69007
AM
19275+ * create the requested context
19276+ * get(), claim() and hash it */
d337f35e 19277+
4bf69007
AM
19278+static struct nx_info *__create_nx_info(int id)
19279+{
19280+ struct nx_info *new, *nxi = NULL;
d337f35e 19281+
4bf69007 19282+ vxdprintk(VXD_CBIT(nid, 1), "create_nx_info(%d)*", id);
d337f35e 19283+
4bf69007
AM
19284+ if (!(new = __alloc_nx_info(id)))
19285+ return ERR_PTR(-ENOMEM);
d337f35e 19286+
4bf69007
AM
19287+ /* required to make dynamic xids unique */
19288+ spin_lock(&nx_info_hash_lock);
d337f35e 19289+
4bf69007
AM
19290+ /* static context requested */
19291+ if ((nxi = __lookup_nx_info(id))) {
19292+ vxdprintk(VXD_CBIT(nid, 0),
19293+ "create_nx_info(%d) = %p (already there)", id, nxi);
19294+ if (nx_info_flags(nxi, NXF_STATE_SETUP, 0))
19295+ nxi = ERR_PTR(-EBUSY);
19296+ else
19297+ nxi = ERR_PTR(-EEXIST);
19298+ goto out_unlock;
19299+ }
19300+ /* new context */
19301+ vxdprintk(VXD_CBIT(nid, 0),
19302+ "create_nx_info(%d) = %p (new)", id, new);
19303+ claim_nx_info(new, NULL);
19304+ __nx_set_lback(new);
19305+ __hash_nx_info(get_nx_info(new));
19306+ nxi = new, new = NULL;
d337f35e 19307+
4bf69007
AM
19308+out_unlock:
19309+ spin_unlock(&nx_info_hash_lock);
19310+ if (new)
19311+ __dealloc_nx_info(new);
19312+ return nxi;
19313+}
d337f35e
JR
19314+
19315+
d337f35e 19316+
4bf69007 19317+/* exported stuff */
d337f35e 19318+
d337f35e 19319+
4bf69007
AM
19320+void unhash_nx_info(struct nx_info *nxi)
19321+{
19322+ __shutdown_nx_info(nxi);
19323+ spin_lock(&nx_info_hash_lock);
19324+ __unhash_nx_info(nxi);
19325+ spin_unlock(&nx_info_hash_lock);
d337f35e
JR
19326+}
19327+
4bf69007 19328+/* lookup_nx_info()
d337f35e 19329+
4bf69007
AM
19330+ * search for a nx_info and get() it
19331+ * negative id means current */
d337f35e 19332+
4bf69007 19333+struct nx_info *lookup_nx_info(int id)
d337f35e 19334+{
4bf69007 19335+ struct nx_info *nxi = NULL;
d337f35e 19336+
4bf69007
AM
19337+ if (id < 0) {
19338+ nxi = get_nx_info(current_nx_info());
19339+ } else if (id > 1) {
19340+ spin_lock(&nx_info_hash_lock);
19341+ nxi = get_nx_info(__lookup_nx_info(id));
19342+ spin_unlock(&nx_info_hash_lock);
d337f35e 19343+ }
4bf69007
AM
19344+ return nxi;
19345+}
d337f35e 19346+
4bf69007 19347+/* nid_is_hashed()
d337f35e 19348+
4bf69007
AM
19349+ * verify that nid is still hashed */
19350+
61333608 19351+int nid_is_hashed(vnid_t nid)
4bf69007
AM
19352+{
19353+ int hashed;
19354+
19355+ spin_lock(&nx_info_hash_lock);
19356+ hashed = (__lookup_nx_info(nid) != NULL);
19357+ spin_unlock(&nx_info_hash_lock);
19358+ return hashed;
d337f35e
JR
19359+}
19360+
19361+
4bf69007 19362+#ifdef CONFIG_PROC_FS
d337f35e 19363+
4bf69007
AM
19364+/* get_nid_list()
19365+
19366+ * get a subset of hashed nids for proc
19367+ * assumes size is at least one */
19368+
19369+int get_nid_list(int index, unsigned int *nids, int size)
d337f35e 19370+{
4bf69007 19371+ int hindex, nr_nids = 0;
d337f35e 19372+
4bf69007
AM
19373+ /* only show current and children */
19374+ if (!nx_check(0, VS_ADMIN | VS_WATCH)) {
19375+ if (index > 0)
19376+ return 0;
19377+ nids[nr_nids] = nx_current_nid();
19378+ return 1;
19379+ }
d337f35e 19380+
4bf69007
AM
19381+ for (hindex = 0; hindex < NX_HASH_SIZE; hindex++) {
19382+ struct hlist_head *head = &nx_info_hash[hindex];
19383+ struct hlist_node *pos;
d337f35e 19384+
4bf69007
AM
19385+ spin_lock(&nx_info_hash_lock);
19386+ hlist_for_each(pos, head) {
19387+ struct nx_info *nxi;
19388+
19389+ if (--index > 0)
19390+ continue;
19391+
19392+ nxi = hlist_entry(pos, struct nx_info, nx_hlist);
19393+ nids[nr_nids] = nxi->nx_id;
19394+ if (++nr_nids >= size) {
19395+ spin_unlock(&nx_info_hash_lock);
d337f35e 19396+ goto out;
4bf69007 19397+ }
d337f35e 19398+ }
4bf69007
AM
19399+ /* keep the lock time short */
19400+ spin_unlock(&nx_info_hash_lock);
d337f35e
JR
19401+ }
19402+out:
4bf69007 19403+ return nr_nids;
d337f35e 19404+}
4bf69007 19405+#endif
d337f35e 19406+
4bf69007
AM
19407+
19408+/*
19409+ * migrate task to new network
19410+ * gets nxi, puts old_nxi on change
19411+ */
19412+
19413+int nx_migrate_task(struct task_struct *p, struct nx_info *nxi)
2380c486 19414+{
4bf69007
AM
19415+ struct nx_info *old_nxi;
19416+ int ret = 0;
2380c486 19417+
4bf69007
AM
19418+ if (!p || !nxi)
19419+ BUG();
d337f35e 19420+
4bf69007
AM
19421+ vxdprintk(VXD_CBIT(nid, 5),
19422+ "nx_migrate_task(%p,%p[#%d.%d.%d])",
19423+ p, nxi, nxi->nx_id,
19424+ atomic_read(&nxi->nx_usecnt),
19425+ atomic_read(&nxi->nx_tasks));
d337f35e 19426+
4bf69007
AM
19427+ if (nx_info_flags(nxi, NXF_INFO_PRIVATE, 0) &&
19428+ !nx_info_flags(nxi, NXF_STATE_SETUP, 0))
19429+ return -EACCES;
d337f35e 19430+
4bf69007
AM
19431+ if (nx_info_state(nxi, NXS_SHUTDOWN))
19432+ return -EFAULT;
d337f35e 19433+
4bf69007
AM
19434+ /* maybe disallow this completely? */
19435+ old_nxi = task_get_nx_info(p);
19436+ if (old_nxi == nxi)
19437+ goto out;
d337f35e 19438+
4bf69007
AM
19439+ task_lock(p);
19440+ if (old_nxi)
19441+ clr_nx_info(&p->nx_info);
19442+ claim_nx_info(nxi, p);
19443+ set_nx_info(&p->nx_info, nxi);
19444+ p->nid = nxi->nx_id;
19445+ task_unlock(p);
d337f35e 19446+
4bf69007
AM
19447+ vxdprintk(VXD_CBIT(nid, 5),
19448+ "moved task %p into nxi:%p[#%d]",
19449+ p, nxi, nxi->nx_id);
d337f35e 19450+
4bf69007
AM
19451+ if (old_nxi)
19452+ release_nx_info(old_nxi, p);
19453+ ret = 0;
19454+out:
19455+ put_nx_info(old_nxi);
19456+ return ret;
19457+}
d337f35e 19458+
d337f35e 19459+
4bf69007
AM
19460+void nx_set_persistent(struct nx_info *nxi)
19461+{
19462+ vxdprintk(VXD_CBIT(nid, 6),
19463+ "nx_set_persistent(%p[#%d])", nxi, nxi->nx_id);
d337f35e 19464+
4bf69007
AM
19465+ get_nx_info(nxi);
19466+ claim_nx_info(nxi, NULL);
d337f35e
JR
19467+}
19468+
4bf69007 19469+void nx_clear_persistent(struct nx_info *nxi)
2380c486 19470+{
4bf69007
AM
19471+ vxdprintk(VXD_CBIT(nid, 6),
19472+ "nx_clear_persistent(%p[#%d])", nxi, nxi->nx_id);
2380c486 19473+
4bf69007
AM
19474+ release_nx_info(nxi, NULL);
19475+ put_nx_info(nxi);
2380c486 19476+}
d337f35e 19477+
4bf69007
AM
19478+void nx_update_persistent(struct nx_info *nxi)
19479+{
19480+ if (nx_info_flags(nxi, NXF_PERSISTENT, 0))
19481+ nx_set_persistent(nxi);
19482+ else
19483+ nx_clear_persistent(nxi);
19484+}
d337f35e 19485+
4bf69007
AM
19486+/* vserver syscall commands below here */
19487+
19488+/* taks nid and nx_info functions */
d337f35e 19489+
4bf69007 19490+#include <asm/uaccess.h>
d337f35e
JR
19491+
19492+
4bf69007 19493+int vc_task_nid(uint32_t id)
d337f35e 19494+{
61333608 19495+ vnid_t nid;
d337f35e 19496+
4bf69007
AM
19497+ if (id) {
19498+ struct task_struct *tsk;
d337f35e 19499+
4bf69007
AM
19500+ rcu_read_lock();
19501+ tsk = find_task_by_real_pid(id);
19502+ nid = (tsk) ? tsk->nid : -ESRCH;
19503+ rcu_read_unlock();
19504+ } else
19505+ nid = nx_current_nid();
19506+ return nid;
d337f35e
JR
19507+}
19508+
19509+
4bf69007
AM
19510+int vc_nx_info(struct nx_info *nxi, void __user *data)
19511+{
19512+ struct vcmd_nx_info_v0 vc_data;
d337f35e 19513+
4bf69007 19514+ vc_data.nid = nxi->nx_id;
d337f35e 19515+
4bf69007
AM
19516+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
19517+ return -EFAULT;
19518+ return 0;
19519+}
d337f35e 19520+
d337f35e 19521+
4bf69007 19522+/* network functions */
d337f35e 19523+
4bf69007
AM
19524+int vc_net_create(uint32_t nid, void __user *data)
19525+{
19526+ struct vcmd_net_create vc_data = { .flagword = NXF_INIT_SET };
19527+ struct nx_info *new_nxi;
19528+ int ret;
d337f35e 19529+
4bf69007
AM
19530+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19531+ return -EFAULT;
d337f35e 19532+
4bf69007
AM
19533+ if ((nid > MAX_S_CONTEXT) || (nid < 2))
19534+ return -EINVAL;
d337f35e 19535+
4bf69007
AM
19536+ new_nxi = __create_nx_info(nid);
19537+ if (IS_ERR(new_nxi))
19538+ return PTR_ERR(new_nxi);
d337f35e 19539+
4bf69007
AM
19540+ /* initial flags */
19541+ new_nxi->nx_flags = vc_data.flagword;
d337f35e 19542+
4bf69007
AM
19543+ ret = -ENOEXEC;
19544+ if (vs_net_change(new_nxi, VSC_NETUP))
19545+ goto out;
d337f35e 19546+
4bf69007
AM
19547+ ret = nx_migrate_task(current, new_nxi);
19548+ if (ret)
d337f35e
JR
19549+ goto out;
19550+
4bf69007
AM
19551+ /* return context id on success */
19552+ ret = new_nxi->nx_id;
d337f35e 19553+
4bf69007
AM
19554+ /* get a reference for persistent contexts */
19555+ if ((vc_data.flagword & NXF_PERSISTENT))
19556+ nx_set_persistent(new_nxi);
d337f35e 19557+out:
4bf69007
AM
19558+ release_nx_info(new_nxi, NULL);
19559+ put_nx_info(new_nxi);
19560+ return ret;
d337f35e
JR
19561+}
19562+
d337f35e 19563+
4bf69007
AM
19564+int vc_net_migrate(struct nx_info *nxi, void __user *data)
19565+{
19566+ return nx_migrate_task(current, nxi);
19567+}
d337f35e 19568+
2380c486 19569+
4bf69007
AM
19570+static inline
19571+struct nx_addr_v4 *__find_v4_addr(struct nx_info *nxi,
19572+ __be32 ip, __be32 ip2, __be32 mask, uint16_t type, uint16_t flags,
19573+ struct nx_addr_v4 **prev)
d337f35e 19574+{
4bf69007
AM
19575+ struct nx_addr_v4 *nxa = &nxi->v4;
19576+
19577+ for (; nxa; nxa = nxa->next) {
19578+ if ((nxa->ip[0].s_addr == ip) &&
19579+ (nxa->ip[1].s_addr == ip2) &&
19580+ (nxa->mask.s_addr == mask) &&
19581+ (nxa->type == type) &&
19582+ (nxa->flags == flags))
19583+ return nxa;
19584+
19585+ /* save previous entry */
19586+ if (prev)
19587+ *prev = nxa;
19588+ }
19589+ return NULL;
2380c486
JR
19590+}
19591+
4bf69007
AM
19592+int do_add_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask,
19593+ uint16_t type, uint16_t flags)
d337f35e 19594+{
4bf69007
AM
19595+ struct nx_addr_v4 *nxa = NULL;
19596+ struct nx_addr_v4 *new = __alloc_nx_addr_v4();
5cb1760b 19597+ unsigned long irqflags;
4bf69007 19598+ int ret = -EEXIST;
d337f35e 19599+
4bf69007
AM
19600+ if (IS_ERR(new))
19601+ return PTR_ERR(new);
d337f35e 19602+
5cb1760b 19603+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19604+ if (__find_v4_addr(nxi, ip, ip2, mask, type, flags, &nxa))
19605+ goto out_unlock;
2380c486 19606+
4bf69007
AM
19607+ if (NX_IPV4(nxi)) {
19608+ nxa->next = new;
19609+ nxa = new;
19610+ new = NULL;
19611+
19612+ /* remove single ip for ip list */
19613+ nxi->nx_flags &= ~NXF_SINGLE_IP;
19614+ }
19615+
19616+ nxa->ip[0].s_addr = ip;
19617+ nxa->ip[1].s_addr = ip2;
19618+ nxa->mask.s_addr = mask;
19619+ nxa->type = type;
19620+ nxa->flags = flags;
19621+ ret = 0;
19622+out_unlock:
5cb1760b 19623+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19624+ if (new)
19625+ __dealloc_nx_addr_v4(new);
19626+ return ret;
d337f35e
JR
19627+}
19628+
4bf69007
AM
19629+int do_remove_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask,
19630+ uint16_t type, uint16_t flags)
2380c486 19631+{
4bf69007
AM
19632+ struct nx_addr_v4 *nxa = NULL;
19633+ struct nx_addr_v4 *old = NULL;
5cb1760b 19634+ unsigned long irqflags;
4bf69007 19635+ int ret = 0;
2380c486 19636+
5cb1760b 19637+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19638+ switch (type) {
19639+ case NXA_TYPE_ADDR:
19640+ old = __find_v4_addr(nxi, ip, ip2, mask, type, flags, &nxa);
19641+ if (old) {
19642+ if (nxa) {
19643+ nxa->next = old->next;
19644+ old->next = NULL;
19645+ } else {
19646+ if (old->next) {
19647+ nxa = old;
19648+ old = old->next;
19649+ *nxa = *old;
19650+ old->next = NULL;
19651+ } else {
19652+ memset(old, 0, sizeof(*old));
19653+ old = NULL;
19654+ }
19655+ }
19656+ } else
19657+ ret = -ESRCH;
19658+ break;
2380c486 19659+
4bf69007
AM
19660+ case NXA_TYPE_ANY:
19661+ nxa = &nxi->v4;
19662+ old = nxa->next;
19663+ memset(nxa, 0, sizeof(*nxa));
19664+ break;
19665+
19666+ default:
19667+ ret = -EINVAL;
19668+ }
5cb1760b 19669+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19670+ __dealloc_nx_addr_v4_all(old);
19671+ return ret;
2380c486
JR
19672+}
19673+
4bf69007
AM
19674+
19675+int vc_net_add(struct nx_info *nxi, void __user *data)
2380c486 19676+{
4bf69007
AM
19677+ struct vcmd_net_addr_v0 vc_data;
19678+ int index, ret = 0;
2380c486 19679+
4bf69007 19680+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486
JR
19681+ return -EFAULT;
19682+
4bf69007
AM
19683+ switch (vc_data.type) {
19684+ case NXA_TYPE_IPV4:
19685+ if ((vc_data.count < 1) || (vc_data.count > 4))
19686+ return -EINVAL;
adc1caaa 19687+
4bf69007
AM
19688+ index = 0;
19689+ while (index < vc_data.count) {
19690+ ret = do_add_v4_addr(nxi, vc_data.ip[index].s_addr, 0,
19691+ vc_data.mask[index].s_addr, NXA_TYPE_ADDR, 0);
19692+ if (ret)
19693+ return ret;
19694+ index++;
19695+ }
19696+ ret = index;
19697+ break;
2380c486 19698+
4bf69007
AM
19699+ case NXA_TYPE_IPV4|NXA_MOD_BCAST:
19700+ nxi->v4_bcast = vc_data.ip[0];
19701+ ret = 1;
19702+ break;
2380c486 19703+
4bf69007
AM
19704+ case NXA_TYPE_IPV4|NXA_MOD_LBACK:
19705+ nxi->v4_lback = vc_data.ip[0];
19706+ ret = 1;
19707+ break;
19708+
19709+ default:
19710+ ret = -EINVAL;
19711+ break;
19712+ }
19713+ return ret;
19714+}
19715+
19716+int vc_net_remove(struct nx_info *nxi, void __user *data)
19717+{
19718+ struct vcmd_net_addr_v0 vc_data;
19719+
19720+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486 19721+ return -EFAULT;
4bf69007
AM
19722+
19723+ switch (vc_data.type) {
19724+ case NXA_TYPE_ANY:
19725+ return do_remove_v4_addr(nxi, 0, 0, 0, vc_data.type, 0);
19726+ default:
19727+ return -EINVAL;
19728+ }
2380c486
JR
19729+ return 0;
19730+}
19731+
d337f35e 19732+
4bf69007 19733+int vc_net_add_ipv4_v1(struct nx_info *nxi, void __user *data)
d337f35e 19734+{
4bf69007
AM
19735+ struct vcmd_net_addr_ipv4_v1 vc_data;
19736+
19737+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19738+ return -EFAULT;
19739+
19740+ switch (vc_data.type) {
19741+ case NXA_TYPE_ADDR:
19742+ case NXA_TYPE_MASK:
19743+ return do_add_v4_addr(nxi, vc_data.ip.s_addr, 0,
19744+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
19745+
19746+ case NXA_TYPE_ADDR | NXA_MOD_BCAST:
19747+ nxi->v4_bcast = vc_data.ip;
19748+ break;
19749+
19750+ case NXA_TYPE_ADDR | NXA_MOD_LBACK:
19751+ nxi->v4_lback = vc_data.ip;
19752+ break;
19753+
19754+ default:
19755+ return -EINVAL;
19756+ }
19757+ return 0;
d337f35e
JR
19758+}
19759+
4bf69007 19760+int vc_net_add_ipv4(struct nx_info *nxi, void __user *data)
d337f35e 19761+{
4bf69007 19762+ struct vcmd_net_addr_ipv4_v2 vc_data;
d337f35e 19763+
4bf69007
AM
19764+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19765+ return -EFAULT;
19766+
19767+ switch (vc_data.type) {
19768+ case NXA_TYPE_ADDR:
19769+ case NXA_TYPE_MASK:
19770+ case NXA_TYPE_RANGE:
19771+ return do_add_v4_addr(nxi, vc_data.ip.s_addr, vc_data.ip2.s_addr,
19772+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
19773+
19774+ case NXA_TYPE_ADDR | NXA_MOD_BCAST:
19775+ nxi->v4_bcast = vc_data.ip;
19776+ break;
19777+
19778+ case NXA_TYPE_ADDR | NXA_MOD_LBACK:
19779+ nxi->v4_lback = vc_data.ip;
19780+ break;
19781+
19782+ default:
19783+ return -EINVAL;
19784+ }
19785+ return 0;
d337f35e
JR
19786+}
19787+
4bf69007 19788+int vc_net_rem_ipv4_v1(struct nx_info *nxi, void __user *data)
d337f35e 19789+{
4bf69007
AM
19790+ struct vcmd_net_addr_ipv4_v1 vc_data;
19791+
19792+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19793+ return -EFAULT;
19794+
19795+ return do_remove_v4_addr(nxi, vc_data.ip.s_addr, 0,
19796+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
d337f35e
JR
19797+}
19798+
4bf69007 19799+int vc_net_rem_ipv4(struct nx_info *nxi, void __user *data)
d337f35e 19800+{
4bf69007
AM
19801+ struct vcmd_net_addr_ipv4_v2 vc_data;
19802+
19803+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19804+ return -EFAULT;
19805+
19806+ return do_remove_v4_addr(nxi, vc_data.ip.s_addr, vc_data.ip2.s_addr,
19807+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
d337f35e 19808+}
d337f35e 19809+
4bf69007 19810+#ifdef CONFIG_IPV6
d337f35e
JR
19811+
19812+static inline
4bf69007
AM
19813+struct nx_addr_v6 *__find_v6_addr(struct nx_info *nxi,
19814+ struct in6_addr *ip, struct in6_addr *mask,
19815+ uint32_t prefix, uint16_t type, uint16_t flags,
19816+ struct nx_addr_v6 **prev)
d337f35e 19817+{
4bf69007 19818+ struct nx_addr_v6 *nxa = &nxi->v6;
d337f35e 19819+
4bf69007
AM
19820+ for (; nxa; nxa = nxa->next) {
19821+ if (ipv6_addr_equal(&nxa->ip, ip) &&
19822+ ipv6_addr_equal(&nxa->mask, mask) &&
19823+ (nxa->prefix == prefix) &&
19824+ (nxa->type == type) &&
19825+ (nxa->flags == flags))
19826+ return nxa;
19827+
19828+ /* save previous entry */
19829+ if (prev)
19830+ *prev = nxa;
19831+ }
19832+ return NULL;
d337f35e
JR
19833+}
19834+
d337f35e 19835+
4bf69007
AM
19836+int do_add_v6_addr(struct nx_info *nxi,
19837+ struct in6_addr *ip, struct in6_addr *mask,
19838+ uint32_t prefix, uint16_t type, uint16_t flags)
19839+{
19840+ struct nx_addr_v6 *nxa = NULL;
19841+ struct nx_addr_v6 *new = __alloc_nx_addr_v6();
5cb1760b 19842+ unsigned long irqflags;
4bf69007 19843+ int ret = -EEXIST;
d337f35e 19844+
4bf69007
AM
19845+ if (IS_ERR(new))
19846+ return PTR_ERR(new);
d337f35e 19847+
5cb1760b 19848+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19849+ if (__find_v6_addr(nxi, ip, mask, prefix, type, flags, &nxa))
19850+ goto out_unlock;
d337f35e 19851+
4bf69007
AM
19852+ if (NX_IPV6(nxi)) {
19853+ nxa->next = new;
19854+ nxa = new;
19855+ new = NULL;
19856+ }
d337f35e 19857+
4bf69007
AM
19858+ nxa->ip = *ip;
19859+ nxa->mask = *mask;
19860+ nxa->prefix = prefix;
19861+ nxa->type = type;
19862+ nxa->flags = flags;
19863+ ret = 0;
19864+out_unlock:
5cb1760b 19865+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19866+ if (new)
19867+ __dealloc_nx_addr_v6(new);
19868+ return ret;
19869+}
d337f35e 19870+
4bf69007
AM
19871+int do_remove_v6_addr(struct nx_info *nxi,
19872+ struct in6_addr *ip, struct in6_addr *mask,
19873+ uint32_t prefix, uint16_t type, uint16_t flags)
d337f35e 19874+{
4bf69007
AM
19875+ struct nx_addr_v6 *nxa = NULL;
19876+ struct nx_addr_v6 *old = NULL;
5cb1760b 19877+ unsigned long irqflags;
4bf69007 19878+ int ret = 0;
d337f35e 19879+
5cb1760b 19880+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19881+ switch (type) {
19882+ case NXA_TYPE_ADDR:
19883+ old = __find_v6_addr(nxi, ip, mask, prefix, type, flags, &nxa);
19884+ if (old) {
19885+ if (nxa) {
19886+ nxa->next = old->next;
19887+ old->next = NULL;
19888+ } else {
19889+ if (old->next) {
19890+ nxa = old;
19891+ old = old->next;
19892+ *nxa = *old;
19893+ old->next = NULL;
19894+ } else {
19895+ memset(old, 0, sizeof(*old));
19896+ old = NULL;
19897+ }
19898+ }
19899+ } else
19900+ ret = -ESRCH;
19901+ break;
d337f35e 19902+
4bf69007
AM
19903+ case NXA_TYPE_ANY:
19904+ nxa = &nxi->v6;
19905+ old = nxa->next;
19906+ memset(nxa, 0, sizeof(*nxa));
d337f35e
JR
19907+ break;
19908+
d337f35e 19909+ default:
4bf69007 19910+ ret = -EINVAL;
d337f35e 19911+ }
5cb1760b 19912+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19913+ __dealloc_nx_addr_v6_all(old);
19914+ return ret;
d337f35e
JR
19915+}
19916+
4bf69007 19917+int vc_net_add_ipv6(struct nx_info *nxi, void __user *data)
d337f35e 19918+{
4bf69007 19919+ struct vcmd_net_addr_ipv6_v1 vc_data;
d337f35e 19920+
4bf69007 19921+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
19922+ return -EFAULT;
19923+
4bf69007
AM
19924+ switch (vc_data.type) {
19925+ case NXA_TYPE_ADDR:
19926+ memset(&vc_data.mask, ~0, sizeof(vc_data.mask));
19927+ /* fallthrough */
19928+ case NXA_TYPE_MASK:
19929+ return do_add_v6_addr(nxi, &vc_data.ip, &vc_data.mask,
19930+ vc_data.prefix, vc_data.type, vc_data.flags);
19931+ default:
19932+ return -EINVAL;
19933+ }
19934+ return 0;
19935+}
d337f35e 19936+
4bf69007
AM
19937+int vc_net_remove_ipv6(struct nx_info *nxi, void __user *data)
19938+{
19939+ struct vcmd_net_addr_ipv6_v1 vc_data;
19940+
19941+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19942+ return -EFAULT;
19943+
19944+ switch (vc_data.type) {
19945+ case NXA_TYPE_ADDR:
19946+ memset(&vc_data.mask, ~0, sizeof(vc_data.mask));
19947+ /* fallthrough */
19948+ case NXA_TYPE_MASK:
19949+ return do_remove_v6_addr(nxi, &vc_data.ip, &vc_data.mask,
19950+ vc_data.prefix, vc_data.type, vc_data.flags);
19951+ case NXA_TYPE_ANY:
19952+ return do_remove_v6_addr(nxi, NULL, NULL, 0, vc_data.type, 0);
19953+ default:
19954+ return -EINVAL;
19955+ }
19956+ return 0;
d337f35e
JR
19957+}
19958+
4bf69007 19959+#endif /* CONFIG_IPV6 */
d337f35e 19960+
4bf69007
AM
19961+
19962+int vc_get_nflags(struct nx_info *nxi, void __user *data)
d337f35e 19963+{
4bf69007 19964+ struct vcmd_net_flags_v0 vc_data;
d337f35e 19965+
4bf69007 19966+ vc_data.flagword = nxi->nx_flags;
d337f35e 19967+
4bf69007
AM
19968+ /* special STATE flag handling */
19969+ vc_data.mask = vs_mask_flags(~0ULL, nxi->nx_flags, NXF_ONE_TIME);
d337f35e 19970+
4bf69007
AM
19971+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
19972+ return -EFAULT;
19973+ return 0;
d337f35e
JR
19974+}
19975+
4bf69007
AM
19976+int vc_set_nflags(struct nx_info *nxi, void __user *data)
19977+{
19978+ struct vcmd_net_flags_v0 vc_data;
19979+ uint64_t mask, trigger;
19980+
19981+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
19982+ return -EFAULT;
d337f35e 19983+
4bf69007
AM
19984+ /* special STATE flag handling */
19985+ mask = vs_mask_mask(vc_data.mask, nxi->nx_flags, NXF_ONE_TIME);
19986+ trigger = (mask & nxi->nx_flags) ^ (mask & vc_data.flagword);
d337f35e 19987+
4bf69007
AM
19988+ nxi->nx_flags = vs_mask_flags(nxi->nx_flags,
19989+ vc_data.flagword, mask);
19990+ if (trigger & NXF_PERSISTENT)
19991+ nx_update_persistent(nxi);
19992+
19993+ return 0;
19994+}
19995+
19996+int vc_get_ncaps(struct nx_info *nxi, void __user *data)
d337f35e 19997+{
4bf69007 19998+ struct vcmd_net_caps_v0 vc_data;
d337f35e 19999+
4bf69007
AM
20000+ vc_data.ncaps = nxi->nx_ncaps;
20001+ vc_data.cmask = ~0ULL;
d337f35e 20002+
2380c486 20003+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
4bf69007
AM
20004+ return -EFAULT;
20005+ return 0;
d337f35e
JR
20006+}
20007+
4bf69007
AM
20008+int vc_set_ncaps(struct nx_info *nxi, void __user *data)
20009+{
20010+ struct vcmd_net_caps_v0 vc_data;
20011+
20012+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
20013+ return -EFAULT;
20014+
20015+ nxi->nx_ncaps = vs_mask_flags(nxi->nx_ncaps,
20016+ vc_data.ncaps, vc_data.cmask);
20017+ return 0;
20018+}
20019+
20020+
20021+#include <linux/module.h>
20022+
20023+module_init(init_network);
20024+
20025+EXPORT_SYMBOL_GPL(free_nx_info);
20026+EXPORT_SYMBOL_GPL(unhash_nx_info);
20027+
cef7ea10
AM
20028diff -NurpP --minimal linux-4.9.82/kernel/vserver/proc.c linux-4.9.82-vs2.3.9.7/kernel/vserver/proc.c
20029--- linux-4.9.82/kernel/vserver/proc.c 1970-01-01 00:00:00.000000000 +0000
20030+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/proc.c 2018-01-13 04:17:12.000000000 +0000
cc23e853 20031@@ -0,0 +1,1040 @@
d337f35e 20032+/*
4bf69007 20033+ * linux/kernel/vserver/proc.c
d337f35e 20034+ *
4bf69007 20035+ * Virtual Context Support
d337f35e 20036+ *
cc23e853 20037+ * Copyright (C) 2003-2011 Herbert P?tzl
d337f35e 20038+ *
4bf69007
AM
20039+ * V0.01 basic structure
20040+ * V0.02 adaptation vs1.3.0
20041+ * V0.03 proc permissions
20042+ * V0.04 locking/generic
20043+ * V0.05 next generation procfs
20044+ * V0.06 inode validation
20045+ * V0.07 generic rewrite vid
20046+ * V0.08 remove inode type
20047+ * V0.09 added u/wmask info
d337f35e
JR
20048+ *
20049+ */
20050+
4bf69007 20051+#include <linux/proc_fs.h>
ec22aa5c 20052+#include <linux/fs_struct.h>
4bf69007
AM
20053+#include <linux/mount.h>
20054+#include <linux/namei.h>
20055+#include <asm/unistd.h>
2380c486 20056+
d337f35e 20057+#include <linux/vs_context.h>
4bf69007
AM
20058+#include <linux/vs_network.h>
20059+#include <linux/vs_cvirt.h>
d337f35e 20060+
4bf69007
AM
20061+#include <linux/in.h>
20062+#include <linux/inetdevice.h>
20063+#include <linux/vs_inet.h>
20064+#include <linux/vs_inet6.h>
d337f35e 20065+
4bf69007 20066+#include <linux/vserver/global.h>
d337f35e 20067+
4bf69007
AM
20068+#include "cvirt_proc.h"
20069+#include "cacct_proc.h"
20070+#include "limit_proc.h"
20071+#include "sched_proc.h"
20072+#include "vci_config.h"
d337f35e 20073+
09be7631
JR
20074+#include <../../fs/proc/internal.h>
20075+
2380c486 20076+
4bf69007
AM
20077+static inline char *print_cap_t(char *buffer, kernel_cap_t *c)
20078+{
20079+ unsigned __capi;
2380c486 20080+
4bf69007
AM
20081+ CAP_FOR_EACH_U32(__capi) {
20082+ buffer += sprintf(buffer, "%08x",
20083+ c->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]);
20084+ }
20085+ return buffer;
20086+}
2380c486 20087+
d337f35e 20088+
4bf69007 20089+static struct proc_dir_entry *proc_virtual;
d337f35e 20090+
4bf69007 20091+static struct proc_dir_entry *proc_virtnet;
d337f35e 20092+
d337f35e 20093+
4bf69007 20094+/* first the actual feeds */
d337f35e 20095+
d337f35e 20096+
4bf69007
AM
20097+static int proc_vci(char *buffer)
20098+{
20099+ return sprintf(buffer,
20100+ "VCIVersion:\t%04x:%04x\n"
20101+ "VCISyscall:\t%d\n"
20102+ "VCIKernel:\t%08x\n",
20103+ VCI_VERSION >> 16,
20104+ VCI_VERSION & 0xFFFF,
20105+ __NR_vserver,
20106+ vci_kernel_config());
20107+}
d337f35e 20108+
4bf69007
AM
20109+static int proc_virtual_info(char *buffer)
20110+{
20111+ return proc_vci(buffer);
d337f35e
JR
20112+}
20113+
4bf69007
AM
20114+static int proc_virtual_status(char *buffer)
20115+{
20116+ return sprintf(buffer,
20117+ "#CTotal:\t%d\n"
20118+ "#CActive:\t%d\n"
20119+ "#NSProxy:\t%d\t%d %d %d %d %d %d\n"
20120+ "#InitTask:\t%d\t%d %d\n",
20121+ atomic_read(&vx_global_ctotal),
20122+ atomic_read(&vx_global_cactive),
20123+ atomic_read(&vs_global_nsproxy),
20124+ atomic_read(&vs_global_fs),
20125+ atomic_read(&vs_global_mnt_ns),
20126+ atomic_read(&vs_global_uts_ns),
cc23e853 20127+ atomic_read(&vs_global_ipc_ns),
4bf69007
AM
20128+ atomic_read(&vs_global_user_ns),
20129+ atomic_read(&vs_global_pid_ns),
20130+ atomic_read(&init_task.usage),
20131+ atomic_read(&init_task.nsproxy->count),
20132+ init_task.fs->users);
20133+}
2380c486 20134+
2380c486 20135+
4bf69007 20136+int proc_vxi_info(struct vx_info *vxi, char *buffer)
d337f35e 20137+{
4bf69007 20138+ int length;
d337f35e 20139+
4bf69007
AM
20140+ length = sprintf(buffer,
20141+ "ID:\t%d\n"
20142+ "Info:\t%p\n"
20143+ "Init:\t%d\n"
20144+ "OOM:\t%lld\n",
20145+ vxi->vx_id,
20146+ vxi,
20147+ vxi->vx_initpid,
20148+ vxi->vx_badness_bias);
20149+ return length;
d337f35e
JR
20150+}
20151+
4bf69007 20152+int proc_vxi_status(struct vx_info *vxi, char *buffer)
d337f35e 20153+{
4bf69007 20154+ char *orig = buffer;
d337f35e 20155+
4bf69007
AM
20156+ buffer += sprintf(buffer,
20157+ "UseCnt:\t%d\n"
20158+ "Tasks:\t%d\n"
20159+ "Flags:\t%016llx\n",
20160+ atomic_read(&vxi->vx_usecnt),
20161+ atomic_read(&vxi->vx_tasks),
20162+ (unsigned long long)vxi->vx_flags);
d337f35e 20163+
4bf69007
AM
20164+ buffer += sprintf(buffer, "BCaps:\t");
20165+ buffer = print_cap_t(buffer, &vxi->vx_bcaps);
20166+ buffer += sprintf(buffer, "\n");
ab30d09f 20167+
4bf69007
AM
20168+ buffer += sprintf(buffer,
20169+ "CCaps:\t%016llx\n"
20170+ "Umask:\t%16llx\n"
20171+ "Wmask:\t%16llx\n"
20172+ "Spaces:\t%08lx %08lx\n",
20173+ (unsigned long long)vxi->vx_ccaps,
20174+ (unsigned long long)vxi->vx_umask,
20175+ (unsigned long long)vxi->vx_wmask,
20176+ vxi->space[0].vx_nsmask, vxi->space[1].vx_nsmask);
20177+ return buffer - orig;
20178+}
ab30d09f 20179+
4bf69007
AM
20180+int proc_vxi_limit(struct vx_info *vxi, char *buffer)
20181+{
20182+ return vx_info_proc_limit(&vxi->limit, buffer);
20183+}
d337f35e 20184+
4bf69007
AM
20185+int proc_vxi_sched(struct vx_info *vxi, char *buffer)
20186+{
20187+ int cpu, length;
d337f35e 20188+
4bf69007
AM
20189+ length = vx_info_proc_sched(&vxi->sched, buffer);
20190+ for_each_online_cpu(cpu) {
20191+ length += vx_info_proc_sched_pc(
20192+ &vx_per_cpu(vxi, sched_pc, cpu),
20193+ buffer + length, cpu);
ec22aa5c 20194+ }
4bf69007
AM
20195+ return length;
20196+}
ec22aa5c 20197+
4bf69007
AM
20198+int proc_vxi_nsproxy0(struct vx_info *vxi, char *buffer)
20199+{
20200+ return vx_info_proc_nsproxy(vxi->space[0].vx_nsproxy, buffer);
20201+}
d337f35e 20202+
4bf69007
AM
20203+int proc_vxi_nsproxy1(struct vx_info *vxi, char *buffer)
20204+{
20205+ return vx_info_proc_nsproxy(vxi->space[1].vx_nsproxy, buffer);
20206+}
ec22aa5c 20207+
4bf69007
AM
20208+int proc_vxi_cvirt(struct vx_info *vxi, char *buffer)
20209+{
20210+ int cpu, length;
d33d7b00 20211+
4bf69007
AM
20212+ vx_update_load(vxi);
20213+ length = vx_info_proc_cvirt(&vxi->cvirt, buffer);
20214+ for_each_online_cpu(cpu) {
20215+ length += vx_info_proc_cvirt_pc(
20216+ &vx_per_cpu(vxi, cvirt_pc, cpu),
20217+ buffer + length, cpu);
3bac966d 20218+ }
4bf69007
AM
20219+ return length;
20220+}
3bac966d 20221+
4bf69007
AM
20222+int proc_vxi_cacct(struct vx_info *vxi, char *buffer)
20223+{
20224+ return vx_info_proc_cacct(&vxi->cacct, buffer);
d337f35e
JR
20225+}
20226+
20227+
4bf69007 20228+static int proc_virtnet_info(char *buffer)
d337f35e 20229+{
4bf69007
AM
20230+ return proc_vci(buffer);
20231+}
ab30d09f 20232+
4bf69007
AM
20233+static int proc_virtnet_status(char *buffer)
20234+{
20235+ return sprintf(buffer,
20236+ "#CTotal:\t%d\n"
20237+ "#CActive:\t%d\n",
20238+ atomic_read(&nx_global_ctotal),
20239+ atomic_read(&nx_global_cactive));
20240+}
d337f35e 20241+
4bf69007
AM
20242+int proc_nxi_info(struct nx_info *nxi, char *buffer)
20243+{
20244+ struct nx_addr_v4 *v4a;
20245+#ifdef CONFIG_IPV6
20246+ struct nx_addr_v6 *v6a;
20247+#endif
20248+ int length, i;
ab30d09f 20249+
4bf69007
AM
20250+ length = sprintf(buffer,
20251+ "ID:\t%d\n"
20252+ "Info:\t%p\n"
20253+ "Bcast:\t" NIPQUAD_FMT "\n"
20254+ "Lback:\t" NIPQUAD_FMT "\n",
20255+ nxi->nx_id,
20256+ nxi,
20257+ NIPQUAD(nxi->v4_bcast.s_addr),
20258+ NIPQUAD(nxi->v4_lback.s_addr));
ab30d09f 20259+
4bf69007
AM
20260+ if (!NX_IPV4(nxi))
20261+ goto skip_v4;
20262+ for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next)
20263+ length += sprintf(buffer + length, "%d:\t" NXAV4_FMT "\n",
20264+ i, NXAV4(v4a));
20265+skip_v4:
20266+#ifdef CONFIG_IPV6
20267+ if (!NX_IPV6(nxi))
20268+ goto skip_v6;
20269+ for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next)
20270+ length += sprintf(buffer + length, "%d:\t" NXAV6_FMT "\n",
20271+ i, NXAV6(v6a));
20272+skip_v6:
20273+#endif
20274+ return length;
20275+}
2380c486 20276+
4bf69007
AM
20277+int proc_nxi_status(struct nx_info *nxi, char *buffer)
20278+{
20279+ int length;
ec22aa5c 20280+
4bf69007
AM
20281+ length = sprintf(buffer,
20282+ "UseCnt:\t%d\n"
20283+ "Tasks:\t%d\n"
20284+ "Flags:\t%016llx\n"
20285+ "NCaps:\t%016llx\n",
20286+ atomic_read(&nxi->nx_usecnt),
20287+ atomic_read(&nxi->nx_tasks),
20288+ (unsigned long long)nxi->nx_flags,
20289+ (unsigned long long)nxi->nx_ncaps);
20290+ return length;
20291+}
ec22aa5c 20292+
ec22aa5c 20293+
d337f35e 20294+
4bf69007 20295+/* here the inode helpers */
d337f35e 20296+
4bf69007
AM
20297+struct vs_entry {
20298+ int len;
20299+ char *name;
20300+ mode_t mode;
20301+ struct inode_operations *iop;
20302+ struct file_operations *fop;
20303+ union proc_op op;
20304+};
d337f35e 20305+
4bf69007
AM
20306+static struct inode *vs_proc_make_inode(struct super_block *sb, struct vs_entry *p)
20307+{
20308+ struct inode *inode = new_inode(sb);
3bac966d 20309+
4bf69007
AM
20310+ if (!inode)
20311+ goto out;
3bac966d 20312+
4bf69007
AM
20313+ inode->i_mode = p->mode;
20314+ if (p->iop)
20315+ inode->i_op = p->iop;
20316+ if (p->fop)
20317+ inode->i_fop = p->fop;
3bac966d 20318+
4bf69007
AM
20319+ set_nlink(inode, (p->mode & S_IFDIR) ? 2 : 1);
20320+ inode->i_flags |= S_IMMUTABLE;
3bac966d 20321+
4bf69007 20322+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
2380c486 20323+
8ce283e1
AM
20324+ i_uid_write(inode, 0);
20325+ i_gid_write(inode, 0);
20326+ i_tag_write(inode, 0);
4bf69007
AM
20327+out:
20328+ return inode;
d337f35e
JR
20329+}
20330+
4bf69007
AM
20331+static struct dentry *vs_proc_instantiate(struct inode *dir,
20332+ struct dentry *dentry, int id, void *ptr)
2380c486 20333+{
4bf69007
AM
20334+ struct vs_entry *p = ptr;
20335+ struct inode *inode = vs_proc_make_inode(dir->i_sb, p);
20336+ struct dentry *error = ERR_PTR(-EINVAL);
2380c486 20337+
4bf69007
AM
20338+ if (!inode)
20339+ goto out;
2380c486 20340+
4bf69007
AM
20341+ PROC_I(inode)->op = p->op;
20342+ PROC_I(inode)->fd = id;
20343+ d_add(dentry, inode);
20344+ error = NULL;
20345+out:
20346+ return error;
2380c486
JR
20347+}
20348+
4bf69007 20349+/* Lookups */
2380c486 20350+
09be7631
JR
20351+typedef struct dentry *vx_instantiate_t(struct inode *, struct dentry *, int, void *);
20352+
2380c486 20353+
4bf69007
AM
20354+/*
20355+ * Fill a directory entry.
20356+ *
20357+ * If possible create the dcache entry and derive our inode number and
20358+ * file type from dcache entry.
20359+ *
20360+ * Since all of the proc inode numbers are dynamically generated, the inode
20361+ * numbers do not exist until the inode is cache. This means creating the
c2e5f7c8
JR
20362+ * the dcache entry in iterate is necessary to keep the inode numbers
20363+ * reported by iterate in sync with the inode numbers reported
4bf69007
AM
20364+ * by stat.
20365+ */
c2e5f7c8 20366+static int vx_proc_fill_cache(struct file *filp, struct dir_context *ctx,
09be7631 20367+ char *name, int len, vx_instantiate_t instantiate, int id, void *ptr)
2380c486 20368+{
cc23e853 20369+ struct dentry *child, *dir = filp->f_path.dentry;
4bf69007
AM
20370+ struct inode *inode;
20371+ struct qstr qname;
20372+ ino_t ino = 0;
20373+ unsigned type = DT_UNKNOWN;
d337f35e 20374+
4bf69007
AM
20375+ qname.name = name;
20376+ qname.len = len;
cc23e853 20377+ qname.hash = full_name_hash(NULL, name, len);
d337f35e 20378+
4bf69007
AM
20379+ child = d_lookup(dir, &qname);
20380+ if (!child) {
20381+ struct dentry *new;
20382+ new = d_alloc(dir, &qname);
20383+ if (new) {
20384+ child = instantiate(dir->d_inode, new, id, ptr);
20385+ if (child)
20386+ dput(new);
20387+ else
20388+ child = new;
20389+ }
20390+ }
20391+ if (!child || IS_ERR(child) || !child->d_inode)
20392+ goto end_instantiate;
20393+ inode = child->d_inode;
20394+ if (inode) {
20395+ ino = inode->i_ino;
20396+ type = inode->i_mode >> 12;
20397+ }
20398+ dput(child);
20399+end_instantiate:
20400+ if (!ino)
4bf69007 20401+ ino = 1;
c2e5f7c8 20402+ return !dir_emit(ctx, name, len, ino, type);
4bf69007 20403+}
d337f35e 20404+
d337f35e 20405+
d337f35e 20406+
4bf69007 20407+/* get and revalidate vx_info/xid */
2380c486 20408+
4bf69007
AM
20409+static inline
20410+struct vx_info *get_proc_vx_info(struct inode *inode)
20411+{
20412+ return lookup_vx_info(PROC_I(inode)->fd);
d337f35e
JR
20413+}
20414+
4bf69007 20415+static int proc_xid_revalidate(struct dentry *dentry, unsigned int flags)
d337f35e 20416+{
4bf69007 20417+ struct inode *inode = dentry->d_inode;
61333608 20418+ vxid_t xid = PROC_I(inode)->fd;
2380c486 20419+
4bf69007
AM
20420+ if (flags & LOOKUP_RCU) /* FIXME: can be dropped? */
20421+ return -ECHILD;
2380c486 20422+
4bf69007
AM
20423+ if (!xid || xid_is_hashed(xid))
20424+ return 1;
20425+ d_drop(dentry);
d337f35e
JR
20426+ return 0;
20427+}
20428+
d337f35e 20429+
4bf69007 20430+/* get and revalidate nx_info/nid */
d337f35e 20431+
4bf69007
AM
20432+static int proc_nid_revalidate(struct dentry *dentry, unsigned int flags)
20433+{
20434+ struct inode *inode = dentry->d_inode;
61333608 20435+ vnid_t nid = PROC_I(inode)->fd;
2380c486 20436+
4bf69007
AM
20437+ if (flags & LOOKUP_RCU) /* FIXME: can be dropped? */
20438+ return -ECHILD;
2380c486 20439+
4bf69007
AM
20440+ if (!nid || nid_is_hashed(nid))
20441+ return 1;
20442+ d_drop(dentry);
20443+ return 0;
d337f35e
JR
20444+}
20445+
4bf69007
AM
20446+
20447+
20448+#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
20449+
20450+static ssize_t proc_vs_info_read(struct file *file, char __user *buf,
20451+ size_t count, loff_t *ppos)
d337f35e 20452+{
cc23e853 20453+ struct inode *inode = file->f_path.dentry->d_inode;
4bf69007
AM
20454+ unsigned long page;
20455+ ssize_t length = 0;
20456+
20457+ if (count > PROC_BLOCK_SIZE)
20458+ count = PROC_BLOCK_SIZE;
20459+
20460+ /* fade that out as soon as stable */
20461+ WARN_ON(PROC_I(inode)->fd);
20462+
20463+ if (!(page = __get_free_page(GFP_KERNEL)))
20464+ return -ENOMEM;
20465+
20466+ BUG_ON(!PROC_I(inode)->op.proc_vs_read);
20467+ length = PROC_I(inode)->op.proc_vs_read((char *)page);
20468+
20469+ if (length >= 0)
20470+ length = simple_read_from_buffer(buf, count, ppos,
20471+ (char *)page, length);
20472+
20473+ free_page(page);
20474+ return length;
d337f35e
JR
20475+}
20476+
4bf69007
AM
20477+static ssize_t proc_vx_info_read(struct file *file, char __user *buf,
20478+ size_t count, loff_t *ppos)
20479+{
cc23e853 20480+ struct inode *inode = file->f_path.dentry->d_inode;
4bf69007 20481+ struct vx_info *vxi = NULL;
61333608 20482+ vxid_t xid = PROC_I(inode)->fd;
4bf69007
AM
20483+ unsigned long page;
20484+ ssize_t length = 0;
d337f35e 20485+
4bf69007
AM
20486+ if (count > PROC_BLOCK_SIZE)
20487+ count = PROC_BLOCK_SIZE;
20488+
20489+ /* fade that out as soon as stable */
20490+ WARN_ON(!xid);
20491+ vxi = lookup_vx_info(xid);
20492+ if (!vxi)
20493+ goto out;
d337f35e 20494+
4bf69007
AM
20495+ length = -ENOMEM;
20496+ if (!(page = __get_free_page(GFP_KERNEL)))
20497+ goto out_put;
d337f35e 20498+
4bf69007
AM
20499+ BUG_ON(!PROC_I(inode)->op.proc_vxi_read);
20500+ length = PROC_I(inode)->op.proc_vxi_read(vxi, (char *)page);
d337f35e 20501+
4bf69007
AM
20502+ if (length >= 0)
20503+ length = simple_read_from_buffer(buf, count, ppos,
20504+ (char *)page, length);
d337f35e 20505+
4bf69007
AM
20506+ free_page(page);
20507+out_put:
20508+ put_vx_info(vxi);
20509+out:
20510+ return length;
20511+}
20512+
20513+static ssize_t proc_nx_info_read(struct file *file, char __user *buf,
20514+ size_t count, loff_t *ppos)
d337f35e 20515+{
cc23e853 20516+ struct inode *inode = file->f_path.dentry->d_inode;
4bf69007 20517+ struct nx_info *nxi = NULL;
61333608 20518+ vnid_t nid = PROC_I(inode)->fd;
4bf69007
AM
20519+ unsigned long page;
20520+ ssize_t length = 0;
d337f35e 20521+
4bf69007
AM
20522+ if (count > PROC_BLOCK_SIZE)
20523+ count = PROC_BLOCK_SIZE;
d337f35e 20524+
4bf69007
AM
20525+ /* fade that out as soon as stable */
20526+ WARN_ON(!nid);
20527+ nxi = lookup_nx_info(nid);
20528+ if (!nxi)
20529+ goto out;
d337f35e 20530+
4bf69007
AM
20531+ length = -ENOMEM;
20532+ if (!(page = __get_free_page(GFP_KERNEL)))
20533+ goto out_put;
d337f35e 20534+
4bf69007
AM
20535+ BUG_ON(!PROC_I(inode)->op.proc_nxi_read);
20536+ length = PROC_I(inode)->op.proc_nxi_read(nxi, (char *)page);
2380c486 20537+
4bf69007
AM
20538+ if (length >= 0)
20539+ length = simple_read_from_buffer(buf, count, ppos,
20540+ (char *)page, length);
d337f35e 20541+
4bf69007
AM
20542+ free_page(page);
20543+out_put:
20544+ put_nx_info(nxi);
20545+out:
20546+ return length;
20547+}
2380c486 20548+
d337f35e 20549+
763640ca 20550+
4bf69007 20551+/* here comes the lower level */
763640ca 20552+
265d6dcc 20553+
4bf69007
AM
20554+#define NOD(NAME, MODE, IOP, FOP, OP) { \
20555+ .len = sizeof(NAME) - 1, \
20556+ .name = (NAME), \
20557+ .mode = MODE, \
20558+ .iop = IOP, \
20559+ .fop = FOP, \
20560+ .op = OP, \
20561+}
d337f35e 20562+
d337f35e 20563+
4bf69007
AM
20564+#define DIR(NAME, MODE, OTYPE) \
20565+ NOD(NAME, (S_IFDIR | (MODE)), \
20566+ &proc_ ## OTYPE ## _inode_operations, \
20567+ &proc_ ## OTYPE ## _file_operations, { } )
d337f35e 20568+
4bf69007
AM
20569+#define INF(NAME, MODE, OTYPE) \
20570+ NOD(NAME, (S_IFREG | (MODE)), NULL, \
20571+ &proc_vs_info_file_operations, \
20572+ { .proc_vs_read = &proc_##OTYPE } )
d337f35e 20573+
4bf69007
AM
20574+#define VINF(NAME, MODE, OTYPE) \
20575+ NOD(NAME, (S_IFREG | (MODE)), NULL, \
20576+ &proc_vx_info_file_operations, \
20577+ { .proc_vxi_read = &proc_##OTYPE } )
2380c486 20578+
4bf69007
AM
20579+#define NINF(NAME, MODE, OTYPE) \
20580+ NOD(NAME, (S_IFREG | (MODE)), NULL, \
20581+ &proc_nx_info_file_operations, \
20582+ { .proc_nxi_read = &proc_##OTYPE } )
d337f35e 20583+
d337f35e 20584+
4bf69007
AM
20585+static struct file_operations proc_vs_info_file_operations = {
20586+ .read = proc_vs_info_read,
20587+};
d337f35e 20588+
4bf69007
AM
20589+static struct file_operations proc_vx_info_file_operations = {
20590+ .read = proc_vx_info_read,
20591+};
d337f35e 20592+
4bf69007
AM
20593+static struct dentry_operations proc_xid_dentry_operations = {
20594+ .d_revalidate = proc_xid_revalidate,
20595+};
d337f35e 20596+
4bf69007
AM
20597+static struct vs_entry vx_base_stuff[] = {
20598+ VINF("info", S_IRUGO, vxi_info),
20599+ VINF("status", S_IRUGO, vxi_status),
20600+ VINF("limit", S_IRUGO, vxi_limit),
20601+ VINF("sched", S_IRUGO, vxi_sched),
20602+ VINF("nsproxy", S_IRUGO, vxi_nsproxy0),
20603+ VINF("nsproxy1",S_IRUGO, vxi_nsproxy1),
20604+ VINF("cvirt", S_IRUGO, vxi_cvirt),
20605+ VINF("cacct", S_IRUGO, vxi_cacct),
20606+ {}
20607+};
2380c486 20608+
d337f35e 20609+
d337f35e 20610+
d337f35e 20611+
4bf69007
AM
20612+static struct dentry *proc_xid_instantiate(struct inode *dir,
20613+ struct dentry *dentry, int id, void *ptr)
20614+{
20615+ dentry->d_op = &proc_xid_dentry_operations;
20616+ return vs_proc_instantiate(dir, dentry, id, ptr);
20617+}
2380c486 20618+
4bf69007
AM
20619+static struct dentry *proc_xid_lookup(struct inode *dir,
20620+ struct dentry *dentry, unsigned int flags)
20621+{
20622+ struct vs_entry *p = vx_base_stuff;
20623+ struct dentry *error = ERR_PTR(-ENOENT);
2380c486 20624+
4bf69007
AM
20625+ for (; p->name; p++) {
20626+ if (p->len != dentry->d_name.len)
20627+ continue;
20628+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20629+ break;
20630+ }
20631+ if (!p->name)
20632+ goto out;
d337f35e 20633+
4bf69007
AM
20634+ error = proc_xid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
20635+out:
20636+ return error;
20637+}
9f7054f1 20638+
c2e5f7c8 20639+static int proc_xid_iterate(struct file *filp, struct dir_context *ctx)
4bf69007 20640+{
cc23e853 20641+ struct dentry *dentry = filp->f_path.dentry;
4bf69007
AM
20642+ struct inode *inode = dentry->d_inode;
20643+ struct vs_entry *p = vx_base_stuff;
20644+ int size = sizeof(vx_base_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20645+ int index;
2380c486 20646+
cc23e853
AM
20647+ if (!dir_emit_dots(filp, ctx))
20648+ return 0;
20649+
20650+ index = ctx->pos - 2;
20651+ if (index < size) {
4bf69007 20652+ for (p += index; p->name; p++) {
c2e5f7c8 20653+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007 20654+ vs_proc_instantiate, PROC_I(inode)->fd, p))
cc23e853 20655+ return 0;
c2e5f7c8 20656+ ctx->pos++;
4bf69007 20657+ }
d337f35e 20658+ }
4bf69007 20659+ return 1;
d337f35e
JR
20660+}
20661+
20662+
d337f35e 20663+
4bf69007
AM
20664+static struct file_operations proc_nx_info_file_operations = {
20665+ .read = proc_nx_info_read,
20666+};
d337f35e 20667+
4bf69007
AM
20668+static struct dentry_operations proc_nid_dentry_operations = {
20669+ .d_revalidate = proc_nid_revalidate,
20670+};
d337f35e 20671+
4bf69007
AM
20672+static struct vs_entry nx_base_stuff[] = {
20673+ NINF("info", S_IRUGO, nxi_info),
20674+ NINF("status", S_IRUGO, nxi_status),
20675+ {}
20676+};
2380c486 20677+
d337f35e 20678+
4bf69007
AM
20679+static struct dentry *proc_nid_instantiate(struct inode *dir,
20680+ struct dentry *dentry, int id, void *ptr)
d337f35e 20681+{
4bf69007
AM
20682+ dentry->d_op = &proc_nid_dentry_operations;
20683+ return vs_proc_instantiate(dir, dentry, id, ptr);
20684+}
d337f35e 20685+
4bf69007
AM
20686+static struct dentry *proc_nid_lookup(struct inode *dir,
20687+ struct dentry *dentry, unsigned int flags)
20688+{
20689+ struct vs_entry *p = nx_base_stuff;
20690+ struct dentry *error = ERR_PTR(-ENOENT);
d337f35e 20691+
4bf69007
AM
20692+ for (; p->name; p++) {
20693+ if (p->len != dentry->d_name.len)
20694+ continue;
20695+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20696+ break;
20697+ }
20698+ if (!p->name)
20699+ goto out;
d337f35e 20700+
4bf69007
AM
20701+ error = proc_nid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
20702+out:
20703+ return error;
20704+}
d337f35e 20705+
c2e5f7c8 20706+static int proc_nid_iterate(struct file *filp, struct dir_context *ctx)
4bf69007 20707+{
cc23e853 20708+ struct dentry *dentry = filp->f_path.dentry;
4bf69007
AM
20709+ struct inode *inode = dentry->d_inode;
20710+ struct vs_entry *p = nx_base_stuff;
20711+ int size = sizeof(nx_base_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20712+ int index;
d337f35e 20713+
cc23e853
AM
20714+ if (!dir_emit_dots(filp, ctx))
20715+ return 0;
20716+
20717+ index = ctx->pos - 2;
20718+ if (index < size) {
4bf69007 20719+ for (p += index; p->name; p++) {
c2e5f7c8 20720+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007 20721+ vs_proc_instantiate, PROC_I(inode)->fd, p))
cc23e853 20722+ return 0;
c2e5f7c8 20723+ ctx->pos++;
4bf69007
AM
20724+ }
20725+ }
4bf69007
AM
20726+ return 1;
20727+}
2380c486 20728+
d337f35e 20729+
4bf69007 20730+#define MAX_MULBY10 ((~0U - 9) / 10)
d337f35e 20731+
4bf69007
AM
20732+static inline int atovid(const char *str, int len)
20733+{
20734+ int vid, c;
d337f35e 20735+
4bf69007
AM
20736+ vid = 0;
20737+ while (len-- > 0) {
20738+ c = *str - '0';
20739+ str++;
20740+ if (c > 9)
20741+ return -1;
20742+ if (vid >= MAX_MULBY10)
20743+ return -1;
20744+ vid *= 10;
20745+ vid += c;
20746+ if (!vid)
20747+ return -1;
20748+ }
20749+ return vid;
20750+}
2380c486 20751+
4bf69007 20752+/* now the upper level (virtual) */
2380c486 20753+
2380c486 20754+
4bf69007
AM
20755+static struct file_operations proc_xid_file_operations = {
20756+ .read = generic_read_dir,
c2e5f7c8 20757+ .iterate = proc_xid_iterate,
4bf69007 20758+};
2380c486 20759+
4bf69007
AM
20760+static struct inode_operations proc_xid_inode_operations = {
20761+ .lookup = proc_xid_lookup,
20762+};
d337f35e 20763+
4bf69007
AM
20764+static struct vs_entry vx_virtual_stuff[] = {
20765+ INF("info", S_IRUGO, virtual_info),
20766+ INF("status", S_IRUGO, virtual_status),
20767+ DIR(NULL, S_IRUGO | S_IXUGO, xid),
20768+};
2380c486 20769+
d337f35e 20770+
4bf69007
AM
20771+static struct dentry *proc_virtual_lookup(struct inode *dir,
20772+ struct dentry *dentry, unsigned int flags)
20773+{
20774+ struct vs_entry *p = vx_virtual_stuff;
20775+ struct dentry *error = ERR_PTR(-ENOENT);
20776+ int id = 0;
d337f35e 20777+
4bf69007
AM
20778+ for (; p->name; p++) {
20779+ if (p->len != dentry->d_name.len)
20780+ continue;
20781+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20782+ break;
20783+ }
20784+ if (p->name)
20785+ goto instantiate;
d337f35e 20786+
4bf69007
AM
20787+ id = atovid(dentry->d_name.name, dentry->d_name.len);
20788+ if ((id < 0) || !xid_is_hashed(id))
d337f35e
JR
20789+ goto out;
20790+
4bf69007
AM
20791+instantiate:
20792+ error = proc_xid_instantiate(dir, dentry, id, p);
20793+out:
20794+ return error;
20795+}
d337f35e 20796+
4bf69007
AM
20797+static struct file_operations proc_nid_file_operations = {
20798+ .read = generic_read_dir,
c2e5f7c8 20799+ .iterate = proc_nid_iterate,
4bf69007 20800+};
d337f35e 20801+
4bf69007
AM
20802+static struct inode_operations proc_nid_inode_operations = {
20803+ .lookup = proc_nid_lookup,
20804+};
d337f35e 20805+
4bf69007
AM
20806+static struct vs_entry nx_virtnet_stuff[] = {
20807+ INF("info", S_IRUGO, virtnet_info),
20808+ INF("status", S_IRUGO, virtnet_status),
20809+ DIR(NULL, S_IRUGO | S_IXUGO, nid),
20810+};
d337f35e 20811+
d337f35e 20812+
4bf69007
AM
20813+static struct dentry *proc_virtnet_lookup(struct inode *dir,
20814+ struct dentry *dentry, unsigned int flags)
20815+{
20816+ struct vs_entry *p = nx_virtnet_stuff;
20817+ struct dentry *error = ERR_PTR(-ENOENT);
20818+ int id = 0;
d337f35e 20819+
4bf69007
AM
20820+ for (; p->name; p++) {
20821+ if (p->len != dentry->d_name.len)
20822+ continue;
20823+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20824+ break;
20825+ }
20826+ if (p->name)
20827+ goto instantiate;
d337f35e 20828+
4bf69007
AM
20829+ id = atovid(dentry->d_name.name, dentry->d_name.len);
20830+ if ((id < 0) || !nid_is_hashed(id))
d337f35e
JR
20831+ goto out;
20832+
4bf69007
AM
20833+instantiate:
20834+ error = proc_nid_instantiate(dir, dentry, id, p);
20835+out:
20836+ return error;
20837+}
2380c486 20838+
d337f35e 20839+
4bf69007
AM
20840+#define PROC_MAXVIDS 32
20841+
c2e5f7c8 20842+int proc_virtual_iterate(struct file *filp, struct dir_context *ctx)
4bf69007 20843+{
4bf69007
AM
20844+ struct vs_entry *p = vx_virtual_stuff;
20845+ int size = sizeof(vx_virtual_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20846+ int index;
4bf69007
AM
20847+ unsigned int xid_array[PROC_MAXVIDS];
20848+ char buf[PROC_NUMBUF];
20849+ unsigned int nr_xids, i;
4bf69007 20850+
cc23e853
AM
20851+ if (!dir_emit_dots(filp, ctx))
20852+ return 0;
20853+
20854+ index = ctx->pos - 2;
20855+ if (index < size) {
4bf69007 20856+ for (p += index; p->name; p++) {
c2e5f7c8 20857+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007 20858+ vs_proc_instantiate, 0, p))
cc23e853 20859+ return 0;
c2e5f7c8 20860+ ctx->pos++;
d337f35e
JR
20861+ }
20862+ }
cc23e853
AM
20863+
20864+ index = ctx->pos - size;
20865+ p = &vx_virtual_stuff[size - 1];
20866+ nr_xids = get_xid_list(index, xid_array, PROC_MAXVIDS);
20867+ for (i = 0; i < nr_xids; i++) {
20868+ int n, xid = xid_array[i];
20869+ unsigned int j = PROC_NUMBUF;
20870+
20871+ n = xid;
20872+ do
20873+ buf[--j] = '0' + (n % 10);
20874+ while (n /= 10);
20875+
20876+ if (vx_proc_fill_cache(filp, ctx,
20877+ buf + j, PROC_NUMBUF - j,
20878+ vs_proc_instantiate, xid, p))
20879+ return 0;
20880+ ctx->pos++;
20881+ }
4bf69007 20882+ return 0;
d337f35e
JR
20883+}
20884+
4bf69007
AM
20885+static int proc_virtual_getattr(struct vfsmount *mnt,
20886+ struct dentry *dentry, struct kstat *stat)
d337f35e 20887+{
4bf69007 20888+ struct inode *inode = dentry->d_inode;
d337f35e 20889+
4bf69007
AM
20890+ generic_fillattr(inode, stat);
20891+ stat->nlink = 2 + atomic_read(&vx_global_cactive);
20892+ return 0;
d337f35e
JR
20893+}
20894+
4bf69007
AM
20895+static struct file_operations proc_virtual_dir_operations = {
20896+ .read = generic_read_dir,
c2e5f7c8 20897+ .iterate = proc_virtual_iterate,
d337f35e
JR
20898+};
20899+
4bf69007
AM
20900+static struct inode_operations proc_virtual_dir_inode_operations = {
20901+ .getattr = proc_virtual_getattr,
20902+ .lookup = proc_virtual_lookup,
20903+};
d337f35e 20904+
d337f35e
JR
20905+
20906+
c2e5f7c8 20907+int proc_virtnet_iterate(struct file *filp, struct dir_context *ctx)
d337f35e 20908+{
4bf69007
AM
20909+ struct vs_entry *p = nx_virtnet_stuff;
20910+ int size = sizeof(nx_virtnet_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20911+ int index;
4bf69007
AM
20912+ unsigned int nid_array[PROC_MAXVIDS];
20913+ char buf[PROC_NUMBUF];
20914+ unsigned int nr_nids, i;
d337f35e 20915+
cc23e853
AM
20916+ if (!dir_emit_dots(filp, ctx))
20917+ return 0;
20918+
20919+ index = ctx->pos - 2;
20920+ if (index < size) {
4bf69007 20921+ for (p += index; p->name; p++) {
c2e5f7c8 20922+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007 20923+ vs_proc_instantiate, 0, p))
cc23e853 20924+ return 0;
c2e5f7c8 20925+ ctx->pos++;
d337f35e
JR
20926+ }
20927+ }
cc23e853
AM
20928+
20929+ index = ctx->pos - size;
20930+ p = &nx_virtnet_stuff[size - 1];
20931+ nr_nids = get_nid_list(index, nid_array, PROC_MAXVIDS);
20932+ for (i = 0; i < nr_nids; i++) {
20933+ int n, nid = nid_array[i];
20934+ unsigned int j = PROC_NUMBUF;
20935+
20936+ n = nid;
20937+ do
20938+ buf[--j] = '0' + (n % 10);
20939+ while (n /= 10);
20940+
20941+ if (vx_proc_fill_cache(filp, ctx,
20942+ buf + j, PROC_NUMBUF - j,
20943+ vs_proc_instantiate, nid, p))
20944+ return 0;
20945+ ctx->pos++;
20946+ }
d337f35e
JR
20947+ return 0;
20948+}
20949+
4bf69007
AM
20950+static int proc_virtnet_getattr(struct vfsmount *mnt,
20951+ struct dentry *dentry, struct kstat *stat)
20952+{
20953+ struct inode *inode = dentry->d_inode;
d337f35e 20954+
4bf69007
AM
20955+ generic_fillattr(inode, stat);
20956+ stat->nlink = 2 + atomic_read(&nx_global_cactive);
20957+ return 0;
20958+}
d337f35e 20959+
4bf69007
AM
20960+static struct file_operations proc_virtnet_dir_operations = {
20961+ .read = generic_read_dir,
c2e5f7c8 20962+ .iterate = proc_virtnet_iterate,
d337f35e
JR
20963+};
20964+
4bf69007
AM
20965+static struct inode_operations proc_virtnet_dir_inode_operations = {
20966+ .getattr = proc_virtnet_getattr,
20967+ .lookup = proc_virtnet_lookup,
d337f35e
JR
20968+};
20969+
d337f35e
JR
20970+
20971+
4bf69007 20972+void proc_vx_init(void)
d337f35e 20973+{
4bf69007 20974+ struct proc_dir_entry *ent;
d337f35e 20975+
4bf69007
AM
20976+ ent = proc_mkdir("virtual", 0);
20977+ if (ent) {
20978+ ent->proc_fops = &proc_virtual_dir_operations;
20979+ ent->proc_iops = &proc_virtual_dir_inode_operations;
20980+ }
20981+ proc_virtual = ent;
d337f35e 20982+
4bf69007
AM
20983+ ent = proc_mkdir("virtnet", 0);
20984+ if (ent) {
20985+ ent->proc_fops = &proc_virtnet_dir_operations;
20986+ ent->proc_iops = &proc_virtnet_dir_inode_operations;
d337f35e 20987+ }
4bf69007 20988+ proc_virtnet = ent;
d337f35e
JR
20989+}
20990+
d337f35e 20991+
2380c486 20992+
2380c486 20993+
4bf69007 20994+/* per pid info */
2380c486 20995+
bb20add7
AM
20996+void render_cap_t(struct seq_file *, const char *,
20997+ struct vx_info *, kernel_cap_t *);
20998+
2380c486 20999+
bb20add7
AM
21000+int proc_pid_vx_info(
21001+ struct seq_file *m,
21002+ struct pid_namespace *ns,
21003+ struct pid *pid,
21004+ struct task_struct *p)
2380c486 21005+{
4bf69007 21006+ struct vx_info *vxi;
2380c486 21007+
bb20add7 21008+ seq_printf(m, "XID:\t%d\n", vx_task_xid(p));
2380c486 21009+
4bf69007
AM
21010+ vxi = task_get_vx_info(p);
21011+ if (!vxi)
bb20add7 21012+ return 0;
2380c486 21013+
bb20add7
AM
21014+ render_cap_t(m, "BCaps:\t", vxi, &vxi->vx_bcaps);
21015+ seq_printf(m, "CCaps:\t%016llx\n",
4bf69007 21016+ (unsigned long long)vxi->vx_ccaps);
bb20add7 21017+ seq_printf(m, "CFlags:\t%016llx\n",
4bf69007 21018+ (unsigned long long)vxi->vx_flags);
bb20add7 21019+ seq_printf(m, "CIPid:\t%d\n", vxi->vx_initpid);
4bf69007
AM
21020+
21021+ put_vx_info(vxi);
bb20add7 21022+ return 0;
2380c486
JR
21023+}
21024+
2380c486 21025+
bb20add7
AM
21026+int proc_pid_nx_info(
21027+ struct seq_file *m,
21028+ struct pid_namespace *ns,
21029+ struct pid *pid,
21030+ struct task_struct *p)
4bf69007
AM
21031+{
21032+ struct nx_info *nxi;
21033+ struct nx_addr_v4 *v4a;
21034+#ifdef CONFIG_IPV6
21035+ struct nx_addr_v6 *v6a;
21036+#endif
4bf69007 21037+ int i;
2380c486 21038+
bb20add7 21039+ seq_printf(m, "NID:\t%d\n", nx_task_nid(p));
2380c486 21040+
4bf69007
AM
21041+ nxi = task_get_nx_info(p);
21042+ if (!nxi)
bb20add7 21043+ return 0;
2380c486 21044+
bb20add7 21045+ seq_printf(m, "NCaps:\t%016llx\n",
4bf69007 21046+ (unsigned long long)nxi->nx_ncaps);
bb20add7 21047+ seq_printf(m, "NFlags:\t%016llx\n",
4bf69007
AM
21048+ (unsigned long long)nxi->nx_flags);
21049+
bb20add7 21050+ seq_printf(m, "V4Root[bcast]:\t" NIPQUAD_FMT "\n",
4bf69007 21051+ NIPQUAD(nxi->v4_bcast.s_addr));
bb20add7 21052+ seq_printf(m, "V4Root[lback]:\t" NIPQUAD_FMT "\n",
4bf69007
AM
21053+ NIPQUAD(nxi->v4_lback.s_addr));
21054+ if (!NX_IPV4(nxi))
21055+ goto skip_v4;
21056+ for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next)
bb20add7 21057+ seq_printf(m, "V4Root[%d]:\t" NXAV4_FMT "\n",
4bf69007
AM
21058+ i, NXAV4(v4a));
21059+skip_v4:
21060+#ifdef CONFIG_IPV6
21061+ if (!NX_IPV6(nxi))
21062+ goto skip_v6;
21063+ for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next)
bb20add7 21064+ seq_printf(m, "V6Root[%d]:\t" NXAV6_FMT "\n",
4bf69007
AM
21065+ i, NXAV6(v6a));
21066+skip_v6:
21067+#endif
21068+ put_nx_info(nxi);
bb20add7 21069+ return 0;
2380c486
JR
21070+}
21071+
cef7ea10
AM
21072diff -NurpP --minimal linux-4.9.82/kernel/vserver/sched.c linux-4.9.82-vs2.3.9.7/kernel/vserver/sched.c
21073--- linux-4.9.82/kernel/vserver/sched.c 1970-01-01 00:00:00.000000000 +0000
21074+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/sched.c 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
21075@@ -0,0 +1,83 @@
21076+/*
21077+ * linux/kernel/vserver/sched.c
21078+ *
21079+ * Virtual Server: Scheduler Support
21080+ *
cc23e853 21081+ * Copyright (C) 2004-2010 Herbert P?tzl
4bf69007
AM
21082+ *
21083+ * V0.01 adapted Sam Vilains version to 2.6.3
21084+ * V0.02 removed legacy interface
21085+ * V0.03 changed vcmds to vxi arg
21086+ * V0.04 removed older and legacy interfaces
21087+ * V0.05 removed scheduler code/commands
21088+ *
21089+ */
21090+
21091+#include <linux/vs_context.h>
21092+#include <linux/vs_sched.h>
21093+#include <linux/cpumask.h>
21094+#include <linux/vserver/sched_cmd.h>
2380c486 21095+
4bf69007
AM
21096+#include <asm/uaccess.h>
21097+
21098+
21099+void vx_update_sched_param(struct _vx_sched *sched,
21100+ struct _vx_sched_pc *sched_pc)
2380c486 21101+{
4bf69007 21102+ sched_pc->prio_bias = sched->prio_bias;
2380c486
JR
21103+}
21104+
4bf69007
AM
21105+static int do_set_prio_bias(struct vx_info *vxi, struct vcmd_prio_bias *data)
21106+{
21107+ int cpu;
2380c486 21108+
4bf69007
AM
21109+ if (data->prio_bias > MAX_PRIO_BIAS)
21110+ data->prio_bias = MAX_PRIO_BIAS;
21111+ if (data->prio_bias < MIN_PRIO_BIAS)
21112+ data->prio_bias = MIN_PRIO_BIAS;
2380c486 21113+
4bf69007 21114+ if (data->cpu_id != ~0) {
cc23e853 21115+ vxi->sched.update = *get_cpu_mask(data->cpu_id);
4bf69007
AM
21116+ cpumask_and(&vxi->sched.update, &vxi->sched.update,
21117+ cpu_online_mask);
21118+ } else
21119+ cpumask_copy(&vxi->sched.update, cpu_online_mask);
2380c486 21120+
cc23e853 21121+ for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)vxi->sched.update)
4bf69007
AM
21122+ vx_update_sched_param(&vxi->sched,
21123+ &vx_per_cpu(vxi, sched_pc, cpu));
21124+ return 0;
21125+}
2380c486 21126+
4bf69007
AM
21127+int vc_set_prio_bias(struct vx_info *vxi, void __user *data)
21128+{
21129+ struct vcmd_prio_bias vc_data;
d337f35e 21130+
4bf69007
AM
21131+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21132+ return -EFAULT;
d337f35e 21133+
4bf69007
AM
21134+ return do_set_prio_bias(vxi, &vc_data);
21135+}
d337f35e 21136+
4bf69007
AM
21137+int vc_get_prio_bias(struct vx_info *vxi, void __user *data)
21138+{
21139+ struct vcmd_prio_bias vc_data;
21140+ struct _vx_sched_pc *pcd;
21141+ int cpu;
d337f35e 21142+
4bf69007
AM
21143+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21144+ return -EFAULT;
2380c486 21145+
4bf69007 21146+ cpu = vc_data.cpu_id;
d337f35e 21147+
4bf69007
AM
21148+ if (!cpu_possible(cpu))
21149+ return -EINVAL;
d337f35e 21150+
4bf69007
AM
21151+ pcd = &vx_per_cpu(vxi, sched_pc, cpu);
21152+ vc_data.prio_bias = pcd->prio_bias;
d337f35e 21153+
4bf69007
AM
21154+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
21155+ return -EFAULT;
21156+ return 0;
21157+}
d337f35e 21158+
cef7ea10
AM
21159diff -NurpP --minimal linux-4.9.82/kernel/vserver/sched_init.h linux-4.9.82-vs2.3.9.7/kernel/vserver/sched_init.h
21160--- linux-4.9.82/kernel/vserver/sched_init.h 1970-01-01 00:00:00.000000000 +0000
21161+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/sched_init.h 2018-01-10 02:50:49.000000000 +0000
4bf69007 21162@@ -0,0 +1,27 @@
2380c486 21163+
4bf69007
AM
21164+static inline void vx_info_init_sched(struct _vx_sched *sched)
21165+{
21166+ /* scheduling; hard code starting values as constants */
21167+ sched->prio_bias = 0;
d337f35e
JR
21168+}
21169+
4bf69007
AM
21170+static inline
21171+void vx_info_init_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
e3afe727 21172+{
4bf69007
AM
21173+ sched_pc->prio_bias = 0;
21174+
21175+ sched_pc->user_ticks = 0;
21176+ sched_pc->sys_ticks = 0;
21177+ sched_pc->hold_ticks = 0;
e3afe727
AM
21178+}
21179+
4bf69007 21180+static inline void vx_info_exit_sched(struct _vx_sched *sched)
e3afe727 21181+{
4bf69007 21182+ return;
e3afe727
AM
21183+}
21184+
4bf69007
AM
21185+static inline
21186+void vx_info_exit_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
e3afe727 21187+{
4bf69007 21188+ return;
e3afe727 21189+}
cef7ea10
AM
21190diff -NurpP --minimal linux-4.9.82/kernel/vserver/sched_proc.h linux-4.9.82-vs2.3.9.7/kernel/vserver/sched_proc.h
21191--- linux-4.9.82/kernel/vserver/sched_proc.h 1970-01-01 00:00:00.000000000 +0000
21192+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/sched_proc.h 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
21193@@ -0,0 +1,32 @@
21194+#ifndef _VX_SCHED_PROC_H
21195+#define _VX_SCHED_PROC_H
e3afe727 21196+
4bf69007
AM
21197+
21198+static inline
21199+int vx_info_proc_sched(struct _vx_sched *sched, char *buffer)
e3afe727 21200+{
4bf69007
AM
21201+ int length = 0;
21202+
21203+ length += sprintf(buffer,
21204+ "PrioBias:\t%8d\n",
21205+ sched->prio_bias);
21206+ return length;
e3afe727
AM
21207+}
21208+
4bf69007
AM
21209+static inline
21210+int vx_info_proc_sched_pc(struct _vx_sched_pc *sched_pc,
21211+ char *buffer, int cpu)
e3afe727 21212+{
4bf69007 21213+ int length = 0;
e3afe727 21214+
4bf69007
AM
21215+ length += sprintf(buffer + length,
21216+ "cpu %d: %lld %lld %lld", cpu,
21217+ (unsigned long long)sched_pc->user_ticks,
21218+ (unsigned long long)sched_pc->sys_ticks,
21219+ (unsigned long long)sched_pc->hold_ticks);
21220+ length += sprintf(buffer + length,
21221+ " %d\n", sched_pc->prio_bias);
21222+ return length;
21223+}
93de0823 21224+
4bf69007 21225+#endif /* _VX_SCHED_PROC_H */
cef7ea10
AM
21226diff -NurpP --minimal linux-4.9.82/kernel/vserver/signal.c linux-4.9.82-vs2.3.9.7/kernel/vserver/signal.c
21227--- linux-4.9.82/kernel/vserver/signal.c 1970-01-01 00:00:00.000000000 +0000
21228+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/signal.c 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
21229@@ -0,0 +1,134 @@
21230+/*
21231+ * linux/kernel/vserver/signal.c
21232+ *
21233+ * Virtual Server: Signal Support
21234+ *
cc23e853 21235+ * Copyright (C) 2003-2007 Herbert P?tzl
4bf69007
AM
21236+ *
21237+ * V0.01 broken out from vcontext V0.05
21238+ * V0.02 changed vcmds to vxi arg
21239+ * V0.03 adjusted siginfo for kill
21240+ *
21241+ */
99a884b4 21242+
4bf69007 21243+#include <asm/uaccess.h>
93de0823 21244+
4bf69007
AM
21245+#include <linux/vs_context.h>
21246+#include <linux/vs_pid.h>
21247+#include <linux/vserver/signal_cmd.h>
d337f35e 21248+
d337f35e 21249+
4bf69007
AM
21250+int vx_info_kill(struct vx_info *vxi, int pid, int sig)
21251+{
21252+ int retval, count = 0;
21253+ struct task_struct *p;
21254+ struct siginfo *sip = SEND_SIG_PRIV;
d33d7b00 21255+
4bf69007
AM
21256+ retval = -ESRCH;
21257+ vxdprintk(VXD_CBIT(misc, 4),
21258+ "vx_info_kill(%p[#%d],%d,%d)*",
21259+ vxi, vxi->vx_id, pid, sig);
21260+ read_lock(&tasklist_lock);
21261+ switch (pid) {
21262+ case 0:
21263+ case -1:
21264+ for_each_process(p) {
21265+ int err = 0;
d337f35e 21266+
4bf69007
AM
21267+ if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 ||
21268+ (pid && vxi->vx_initpid == p->pid))
21269+ continue;
d337f35e 21270+
4bf69007
AM
21271+ err = group_send_sig_info(sig, sip, p);
21272+ ++count;
21273+ if (err != -EPERM)
21274+ retval = err;
21275+ }
21276+ break;
d337f35e 21277+
4bf69007
AM
21278+ case 1:
21279+ if (vxi->vx_initpid) {
21280+ pid = vxi->vx_initpid;
21281+ /* for now, only SIGINT to private init ... */
21282+ if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
21283+ /* ... as long as there are tasks left */
21284+ (atomic_read(&vxi->vx_tasks) > 1))
21285+ sig = SIGINT;
21286+ }
21287+ /* fallthrough */
21288+ default:
21289+ rcu_read_lock();
21290+ p = find_task_by_real_pid(pid);
21291+ rcu_read_unlock();
21292+ if (p) {
21293+ if (vx_task_xid(p) == vxi->vx_id)
21294+ retval = group_send_sig_info(sig, sip, p);
21295+ }
21296+ break;
21297+ }
21298+ read_unlock(&tasklist_lock);
21299+ vxdprintk(VXD_CBIT(misc, 4),
21300+ "vx_info_kill(%p[#%d],%d,%d,%ld) = %d",
21301+ vxi, vxi->vx_id, pid, sig, (long)sip, retval);
21302+ return retval;
21303+}
d337f35e 21304+
4bf69007 21305+int vc_ctx_kill(struct vx_info *vxi, void __user *data)
d337f35e 21306+{
4bf69007 21307+ struct vcmd_ctx_kill_v0 vc_data;
d337f35e 21308+
4bf69007
AM
21309+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21310+ return -EFAULT;
d337f35e 21311+
4bf69007
AM
21312+ /* special check to allow guest shutdown */
21313+ if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
21314+ /* forbid killall pid=0 when init is present */
21315+ (((vc_data.pid < 1) && vxi->vx_initpid) ||
21316+ (vc_data.pid > 1)))
21317+ return -EACCES;
21318+
21319+ return vx_info_kill(vxi, vc_data.pid, vc_data.sig);
d337f35e
JR
21320+}
21321+
4bf69007
AM
21322+
21323+static int __wait_exit(struct vx_info *vxi)
d337f35e 21324+{
4bf69007
AM
21325+ DECLARE_WAITQUEUE(wait, current);
21326+ int ret = 0;
d337f35e 21327+
4bf69007
AM
21328+ add_wait_queue(&vxi->vx_wait, &wait);
21329+ set_current_state(TASK_INTERRUPTIBLE);
d337f35e 21330+
4bf69007
AM
21331+wait:
21332+ if (vx_info_state(vxi,
21333+ VXS_SHUTDOWN | VXS_HASHED | VXS_HELPER) == VXS_SHUTDOWN)
21334+ goto out;
21335+ if (signal_pending(current)) {
21336+ ret = -ERESTARTSYS;
21337+ goto out;
21338+ }
21339+ schedule();
21340+ goto wait;
21341+
21342+out:
21343+ set_current_state(TASK_RUNNING);
21344+ remove_wait_queue(&vxi->vx_wait, &wait);
21345+ return ret;
d337f35e
JR
21346+}
21347+
4a036bed 21348+
7b17263b 21349+
4bf69007 21350+int vc_wait_exit(struct vx_info *vxi, void __user *data)
7b17263b 21351+{
4bf69007
AM
21352+ struct vcmd_wait_exit_v0 vc_data;
21353+ int ret;
7b17263b 21354+
4bf69007
AM
21355+ ret = __wait_exit(vxi);
21356+ vc_data.reboot_cmd = vxi->reboot_cmd;
21357+ vc_data.exit_code = vxi->exit_code;
21358+
21359+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
21360+ ret = -EFAULT;
21361+ return ret;
7b17263b 21362+}
2380c486 21363+
cef7ea10
AM
21364diff -NurpP --minimal linux-4.9.82/kernel/vserver/space.c linux-4.9.82-vs2.3.9.7/kernel/vserver/space.c
21365--- linux-4.9.82/kernel/vserver/space.c 1970-01-01 00:00:00.000000000 +0000
21366+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/space.c 2018-01-13 03:42:01.000000000 +0000
cc23e853 21367@@ -0,0 +1,437 @@
4bf69007
AM
21368+/*
21369+ * linux/kernel/vserver/space.c
21370+ *
21371+ * Virtual Server: Context Space Support
21372+ *
cc23e853 21373+ * Copyright (C) 2003-2010 Herbert P?tzl
4bf69007
AM
21374+ *
21375+ * V0.01 broken out from context.c 0.07
21376+ * V0.02 added task locking for namespace
21377+ * V0.03 broken out vx_enter_namespace
21378+ * V0.04 added *space support and commands
21379+ * V0.05 added credential support
21380+ *
21381+ */
21382+
21383+#include <linux/utsname.h>
21384+#include <linux/nsproxy.h>
21385+#include <linux/err.h>
21386+#include <linux/fs_struct.h>
21387+#include <linux/cred.h>
21388+#include <asm/uaccess.h>
d337f35e 21389+
d337f35e 21390+#include <linux/vs_context.h>
4bf69007
AM
21391+#include <linux/vserver/space.h>
21392+#include <linux/vserver/space_cmd.h>
2380c486 21393+
4bf69007
AM
21394+atomic_t vs_global_nsproxy = ATOMIC_INIT(0);
21395+atomic_t vs_global_fs = ATOMIC_INIT(0);
21396+atomic_t vs_global_mnt_ns = ATOMIC_INIT(0);
21397+atomic_t vs_global_uts_ns = ATOMIC_INIT(0);
cc23e853 21398+atomic_t vs_global_ipc_ns = ATOMIC_INIT(0);
4bf69007
AM
21399+atomic_t vs_global_user_ns = ATOMIC_INIT(0);
21400+atomic_t vs_global_pid_ns = ATOMIC_INIT(0);
d337f35e 21401+
2380c486 21402+
4bf69007 21403+/* namespace functions */
2380c486 21404+
4bf69007
AM
21405+#include <linux/mnt_namespace.h>
21406+#include <linux/user_namespace.h>
21407+#include <linux/pid_namespace.h>
21408+#include <linux/ipc_namespace.h>
21409+#include <net/net_namespace.h>
21410+#include "../fs/mount.h"
2380c486 21411+
2380c486 21412+
4bf69007
AM
21413+static const struct vcmd_space_mask_v1 space_mask_v0 = {
21414+ .mask = CLONE_FS |
21415+ CLONE_NEWNS |
21416+#ifdef CONFIG_UTS_NS
21417+ CLONE_NEWUTS |
21418+#endif
21419+#ifdef CONFIG_IPC_NS
21420+ CLONE_NEWIPC |
21421+#endif
21422+#ifdef CONFIG_USER_NS
21423+ CLONE_NEWUSER |
21424+#endif
21425+ 0
21426+};
2380c486 21427+
4bf69007
AM
21428+static const struct vcmd_space_mask_v1 space_mask = {
21429+ .mask = CLONE_FS |
21430+ CLONE_NEWNS |
21431+#ifdef CONFIG_UTS_NS
21432+ CLONE_NEWUTS |
21433+#endif
21434+#ifdef CONFIG_IPC_NS
21435+ CLONE_NEWIPC |
21436+#endif
21437+#ifdef CONFIG_USER_NS
21438+ CLONE_NEWUSER |
21439+#endif
21440+#ifdef CONFIG_PID_NS
21441+ CLONE_NEWPID |
21442+#endif
21443+#ifdef CONFIG_NET_NS
21444+ CLONE_NEWNET |
21445+#endif
21446+ 0
21447+};
2380c486 21448+
4bf69007
AM
21449+static const struct vcmd_space_mask_v1 default_space_mask = {
21450+ .mask = CLONE_FS |
21451+ CLONE_NEWNS |
21452+#ifdef CONFIG_UTS_NS
21453+ CLONE_NEWUTS |
21454+#endif
21455+#ifdef CONFIG_IPC_NS
21456+ CLONE_NEWIPC |
21457+#endif
21458+#ifdef CONFIG_USER_NS
bb20add7 21459+// CLONE_NEWUSER |
4bf69007
AM
21460+#endif
21461+#ifdef CONFIG_PID_NS
21462+// CLONE_NEWPID |
21463+#endif
21464+ 0
21465+};
2380c486 21466+
4bf69007
AM
21467+/*
21468+ * build a new nsproxy mix
21469+ * assumes that both proxies are 'const'
21470+ * does not touch nsproxy refcounts
21471+ * will hold a reference on the result.
21472+ */
7b17263b 21473+
4bf69007
AM
21474+struct nsproxy *vs_mix_nsproxy(struct nsproxy *old_nsproxy,
21475+ struct nsproxy *new_nsproxy, unsigned long mask)
21476+{
21477+ struct mnt_namespace *old_ns;
21478+ struct uts_namespace *old_uts;
21479+ struct ipc_namespace *old_ipc;
21480+#ifdef CONFIG_PID_NS
21481+ struct pid_namespace *old_pid;
21482+#endif
21483+#ifdef CONFIG_NET_NS
21484+ struct net *old_net;
21485+#endif
21486+ struct nsproxy *nsproxy;
d337f35e 21487+
4bf69007
AM
21488+ nsproxy = copy_nsproxy(old_nsproxy);
21489+ if (!nsproxy)
21490+ goto out;
bd0a9c15 21491+
4bf69007
AM
21492+ if (mask & CLONE_NEWNS) {
21493+ old_ns = nsproxy->mnt_ns;
21494+ nsproxy->mnt_ns = new_nsproxy->mnt_ns;
21495+ if (nsproxy->mnt_ns)
21496+ get_mnt_ns(nsproxy->mnt_ns);
21497+ } else
21498+ old_ns = NULL;
d337f35e 21499+
4bf69007
AM
21500+ if (mask & CLONE_NEWUTS) {
21501+ old_uts = nsproxy->uts_ns;
21502+ nsproxy->uts_ns = new_nsproxy->uts_ns;
21503+ if (nsproxy->uts_ns)
21504+ get_uts_ns(nsproxy->uts_ns);
21505+ } else
21506+ old_uts = NULL;
2380c486 21507+
4bf69007
AM
21508+ if (mask & CLONE_NEWIPC) {
21509+ old_ipc = nsproxy->ipc_ns;
21510+ nsproxy->ipc_ns = new_nsproxy->ipc_ns;
21511+ if (nsproxy->ipc_ns)
21512+ get_ipc_ns(nsproxy->ipc_ns);
21513+ } else
21514+ old_ipc = NULL;
ec22aa5c 21515+
4bf69007
AM
21516+#ifdef CONFIG_PID_NS
21517+ if (mask & CLONE_NEWPID) {
5f23d63e
AM
21518+ old_pid = nsproxy->pid_ns_for_children;
21519+ nsproxy->pid_ns_for_children = new_nsproxy->pid_ns_for_children;
21520+ if (nsproxy->pid_ns_for_children)
21521+ get_pid_ns(nsproxy->pid_ns_for_children);
4bf69007
AM
21522+ } else
21523+ old_pid = NULL;
21524+#endif
21525+#ifdef CONFIG_NET_NS
21526+ if (mask & CLONE_NEWNET) {
21527+ old_net = nsproxy->net_ns;
21528+ nsproxy->net_ns = new_nsproxy->net_ns;
21529+ if (nsproxy->net_ns)
21530+ get_net(nsproxy->net_ns);
21531+ } else
21532+ old_net = NULL;
21533+#endif
21534+ if (old_ns)
21535+ put_mnt_ns(old_ns);
21536+ if (old_uts)
21537+ put_uts_ns(old_uts);
21538+ if (old_ipc)
21539+ put_ipc_ns(old_ipc);
21540+#ifdef CONFIG_PID_NS
21541+ if (old_pid)
21542+ put_pid_ns(old_pid);
21543+#endif
21544+#ifdef CONFIG_NET_NS
21545+ if (old_net)
21546+ put_net(old_net);
21547+#endif
21548+out:
21549+ return nsproxy;
21550+}
2380c486 21551+
bd0a9c15 21552+
4bf69007
AM
21553+/*
21554+ * merge two nsproxy structs into a new one.
21555+ * will hold a reference on the result.
21556+ */
d337f35e 21557+
4bf69007
AM
21558+static inline
21559+struct nsproxy *__vs_merge_nsproxy(struct nsproxy *old,
21560+ struct nsproxy *proxy, unsigned long mask)
21561+{
21562+ struct nsproxy null_proxy = { .mnt_ns = NULL };
2380c486 21563+
4bf69007
AM
21564+ if (!proxy)
21565+ return NULL;
d337f35e 21566+
4bf69007
AM
21567+ if (mask) {
21568+ /* vs_mix_nsproxy returns with reference */
21569+ return vs_mix_nsproxy(old ? old : &null_proxy,
21570+ proxy, mask);
21571+ }
21572+ get_nsproxy(proxy);
21573+ return proxy;
21574+}
2380c486 21575+
ec22aa5c 21576+
4bf69007
AM
21577+int vx_enter_space(struct vx_info *vxi, unsigned long mask, unsigned index)
21578+{
21579+ struct nsproxy *proxy, *proxy_cur, *proxy_new;
21580+ struct fs_struct *fs_cur, *fs = NULL;
21581+ struct _vx_space *space;
21582+ int ret, kill = 0;
2380c486 21583+
4bf69007
AM
21584+ vxdprintk(VXD_CBIT(space, 8), "vx_enter_space(%p[#%u],0x%08lx,%d)",
21585+ vxi, vxi->vx_id, mask, index);
2380c486 21586+
4bf69007
AM
21587+ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
21588+ return -EACCES;
2380c486 21589+
4bf69007
AM
21590+ if (index >= VX_SPACES)
21591+ return -EINVAL;
2380c486 21592+
4bf69007
AM
21593+ space = &vxi->space[index];
21594+
21595+ if (!mask)
21596+ mask = space->vx_nsmask;
21597+
21598+ if ((mask & space->vx_nsmask) != mask)
21599+ return -EINVAL;
21600+
21601+ if (mask & CLONE_FS) {
21602+ fs = copy_fs_struct(space->vx_fs);
21603+ if (!fs)
21604+ return -ENOMEM;
2380c486 21605+ }
4bf69007
AM
21606+ proxy = space->vx_nsproxy;
21607+
21608+ vxdprintk(VXD_CBIT(space, 9),
21609+ "vx_enter_space(%p[#%u],0x%08lx,%d) -> (%p,%p)",
21610+ vxi, vxi->vx_id, mask, index, proxy, fs);
21611+
21612+ task_lock(current);
21613+ fs_cur = current->fs;
21614+
21615+ if (mask & CLONE_FS) {
21616+ spin_lock(&fs_cur->lock);
21617+ current->fs = fs;
21618+ kill = !--fs_cur->users;
21619+ spin_unlock(&fs_cur->lock);
ec22aa5c 21620+ }
ec22aa5c 21621+
4bf69007
AM
21622+ proxy_cur = current->nsproxy;
21623+ get_nsproxy(proxy_cur);
21624+ task_unlock(current);
21625+
21626+ if (kill)
21627+ free_fs_struct(fs_cur);
21628+
21629+ proxy_new = __vs_merge_nsproxy(proxy_cur, proxy, mask);
21630+ if (IS_ERR(proxy_new)) {
21631+ ret = PTR_ERR(proxy_new);
21632+ goto out_put;
eab5a9a6 21633+ }
4bf69007
AM
21634+
21635+ proxy_new = xchg(&current->nsproxy, proxy_new);
21636+
21637+ if (mask & CLONE_NEWUSER) {
21638+ struct cred *cred;
21639+
21640+ vxdprintk(VXD_CBIT(space, 10),
21641+ "vx_enter_space(%p[#%u],%p) cred (%p,%p)",
21642+ vxi, vxi->vx_id, space->vx_cred,
21643+ current->real_cred, current->cred);
21644+
21645+ if (space->vx_cred) {
21646+ cred = __prepare_creds(space->vx_cred);
21647+ if (cred)
21648+ commit_creds(cred);
21649+ }
d337f35e 21650+ }
4bf69007
AM
21651+
21652+ ret = 0;
21653+
21654+ if (proxy_new)
21655+ put_nsproxy(proxy_new);
21656+out_put:
21657+ if (proxy_cur)
21658+ put_nsproxy(proxy_cur);
21659+ return ret;
21660+}
21661+
21662+
21663+int vx_set_space(struct vx_info *vxi, unsigned long mask, unsigned index)
21664+{
21665+ struct nsproxy *proxy_vxi, *proxy_cur, *proxy_new;
21666+ struct fs_struct *fs_vxi, *fs = NULL;
21667+ struct _vx_space *space;
21668+ int ret, kill = 0;
21669+
21670+ vxdprintk(VXD_CBIT(space, 8), "vx_set_space(%p[#%u],0x%08lx,%d)",
21671+ vxi, vxi->vx_id, mask, index);
21672+
21673+ if ((mask & space_mask.mask) != mask)
21674+ return -EINVAL;
21675+
21676+ if (index >= VX_SPACES)
21677+ return -EINVAL;
21678+
21679+ space = &vxi->space[index];
21680+
21681+ proxy_vxi = space->vx_nsproxy;
21682+ fs_vxi = space->vx_fs;
21683+
21684+ if (mask & CLONE_FS) {
21685+ fs = copy_fs_struct(current->fs);
21686+ if (!fs)
21687+ return -ENOMEM;
2380c486 21688+ }
d337f35e 21689+
4bf69007 21690+ task_lock(current);
2ba6f0dd 21691+
4bf69007
AM
21692+ if (mask & CLONE_FS) {
21693+ spin_lock(&fs_vxi->lock);
21694+ space->vx_fs = fs;
21695+ kill = !--fs_vxi->users;
21696+ spin_unlock(&fs_vxi->lock);
21697+ }
2ba6f0dd 21698+
4bf69007
AM
21699+ proxy_cur = current->nsproxy;
21700+ get_nsproxy(proxy_cur);
21701+ task_unlock(current);
2ba6f0dd 21702+
4bf69007
AM
21703+ if (kill)
21704+ free_fs_struct(fs_vxi);
2ba6f0dd 21705+
4bf69007
AM
21706+ proxy_new = __vs_merge_nsproxy(proxy_vxi, proxy_cur, mask);
21707+ if (IS_ERR(proxy_new)) {
21708+ ret = PTR_ERR(proxy_new);
21709+ goto out_put;
21710+ }
2ba6f0dd 21711+
4bf69007
AM
21712+ proxy_new = xchg(&space->vx_nsproxy, proxy_new);
21713+ space->vx_nsmask |= mask;
2ba6f0dd 21714+
4bf69007
AM
21715+ if (mask & CLONE_NEWUSER) {
21716+ struct cred *cred;
2ba6f0dd 21717+
4bf69007
AM
21718+ vxdprintk(VXD_CBIT(space, 10),
21719+ "vx_set_space(%p[#%u],%p) cred (%p,%p)",
21720+ vxi, vxi->vx_id, space->vx_cred,
21721+ current->real_cred, current->cred);
2ba6f0dd 21722+
4bf69007
AM
21723+ cred = prepare_creds();
21724+ cred = (struct cred *)xchg(&space->vx_cred, cred);
21725+ if (cred)
21726+ abort_creds(cred);
21727+ }
2ba6f0dd 21728+
4bf69007 21729+ ret = 0;
2ba6f0dd 21730+
4bf69007
AM
21731+ if (proxy_new)
21732+ put_nsproxy(proxy_new);
21733+out_put:
21734+ if (proxy_cur)
21735+ put_nsproxy(proxy_cur);
21736+ return ret;
21737+}
2ba6f0dd
AM
21738+
21739+
4bf69007
AM
21740+int vc_enter_space_v1(struct vx_info *vxi, void __user *data)
21741+{
21742+ struct vcmd_space_mask_v1 vc_data = { .mask = 0 };
2ba6f0dd 21743+
4bf69007
AM
21744+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21745+ return -EFAULT;
2ba6f0dd 21746+
4bf69007
AM
21747+ return vx_enter_space(vxi, vc_data.mask, 0);
21748+}
2ba6f0dd 21749+
4bf69007
AM
21750+int vc_enter_space(struct vx_info *vxi, void __user *data)
21751+{
21752+ struct vcmd_space_mask_v2 vc_data = { .mask = 0 };
2ba6f0dd 21753+
4bf69007
AM
21754+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21755+ return -EFAULT;
2ba6f0dd 21756+
4bf69007
AM
21757+ if (vc_data.index >= VX_SPACES)
21758+ return -EINVAL;
2ba6f0dd 21759+
4bf69007
AM
21760+ return vx_enter_space(vxi, vc_data.mask, vc_data.index);
21761+}
2ba6f0dd 21762+
4bf69007
AM
21763+int vc_set_space_v1(struct vx_info *vxi, void __user *data)
21764+{
21765+ struct vcmd_space_mask_v1 vc_data = { .mask = 0 };
2ba6f0dd 21766+
4bf69007
AM
21767+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21768+ return -EFAULT;
2ba6f0dd 21769+
4bf69007
AM
21770+ return vx_set_space(vxi, vc_data.mask, 0);
21771+}
2ba6f0dd 21772+
4bf69007
AM
21773+int vc_set_space(struct vx_info *vxi, void __user *data)
21774+{
21775+ struct vcmd_space_mask_v2 vc_data = { .mask = 0 };
2ba6f0dd 21776+
4bf69007
AM
21777+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21778+ return -EFAULT;
2ba6f0dd 21779+
4bf69007
AM
21780+ if (vc_data.index >= VX_SPACES)
21781+ return -EINVAL;
2ba6f0dd 21782+
4bf69007
AM
21783+ return vx_set_space(vxi, vc_data.mask, vc_data.index);
21784+}
2ba6f0dd 21785+
4bf69007
AM
21786+int vc_get_space_mask(void __user *data, int type)
21787+{
21788+ const struct vcmd_space_mask_v1 *mask;
2ba6f0dd 21789+
4bf69007
AM
21790+ if (type == 0)
21791+ mask = &space_mask_v0;
21792+ else if (type == 1)
21793+ mask = &space_mask;
21794+ else
21795+ mask = &default_space_mask;
2ba6f0dd 21796+
4bf69007
AM
21797+ vxdprintk(VXD_CBIT(space, 10),
21798+ "vc_get_space_mask(%d) = %08llx", type, mask->mask);
2ba6f0dd 21799+
4bf69007
AM
21800+ if (copy_to_user(data, mask, sizeof(*mask)))
21801+ return -EFAULT;
21802+ return 0;
21803+}
2ba6f0dd 21804+
cef7ea10
AM
21805diff -NurpP --minimal linux-4.9.82/kernel/vserver/switch.c linux-4.9.82-vs2.3.9.7/kernel/vserver/switch.c
21806--- linux-4.9.82/kernel/vserver/switch.c 1970-01-01 00:00:00.000000000 +0000
21807+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/switch.c 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
21808@@ -0,0 +1,556 @@
21809+/*
21810+ * linux/kernel/vserver/switch.c
21811+ *
21812+ * Virtual Server: Syscall Switch
21813+ *
cc23e853 21814+ * Copyright (C) 2003-2011 Herbert P?tzl
4bf69007
AM
21815+ *
21816+ * V0.01 syscall switch
21817+ * V0.02 added signal to context
21818+ * V0.03 added rlimit functions
21819+ * V0.04 added iattr, task/xid functions
21820+ * V0.05 added debug/history stuff
21821+ * V0.06 added compat32 layer
21822+ * V0.07 vcmd args and perms
21823+ * V0.08 added status commands
21824+ * V0.09 added tag commands
21825+ * V0.10 added oom bias
21826+ * V0.11 added device commands
21827+ * V0.12 added warn mask
21828+ *
21829+ */
2ba6f0dd 21830+
4bf69007
AM
21831+#include <linux/vs_context.h>
21832+#include <linux/vs_network.h>
21833+#include <linux/vserver/switch.h>
2ba6f0dd 21834+
4bf69007 21835+#include "vci_config.h"
2ba6f0dd 21836+
2ba6f0dd 21837+
4bf69007
AM
21838+static inline
21839+int vc_get_version(uint32_t id)
21840+{
21841+ return VCI_VERSION;
21842+}
2ba6f0dd 21843+
4bf69007
AM
21844+static inline
21845+int vc_get_vci(uint32_t id)
21846+{
21847+ return vci_kernel_config();
21848+}
2ba6f0dd 21849+
4bf69007
AM
21850+#include <linux/vserver/context_cmd.h>
21851+#include <linux/vserver/cvirt_cmd.h>
21852+#include <linux/vserver/cacct_cmd.h>
21853+#include <linux/vserver/limit_cmd.h>
21854+#include <linux/vserver/network_cmd.h>
21855+#include <linux/vserver/sched_cmd.h>
21856+#include <linux/vserver/debug_cmd.h>
21857+#include <linux/vserver/inode_cmd.h>
21858+#include <linux/vserver/dlimit_cmd.h>
21859+#include <linux/vserver/signal_cmd.h>
21860+#include <linux/vserver/space_cmd.h>
21861+#include <linux/vserver/tag_cmd.h>
21862+#include <linux/vserver/device_cmd.h>
2ba6f0dd 21863+
4bf69007
AM
21864+#include <linux/vserver/inode.h>
21865+#include <linux/vserver/dlimit.h>
2ba6f0dd 21866+
2ba6f0dd 21867+
4bf69007
AM
21868+#ifdef CONFIG_COMPAT
21869+#define __COMPAT(name, id, data, compat) \
21870+ (compat) ? name ## _x32(id, data) : name(id, data)
21871+#define __COMPAT_NO_ID(name, data, compat) \
21872+ (compat) ? name ## _x32(data) : name(data)
21873+#else
21874+#define __COMPAT(name, id, data, compat) \
21875+ name(id, data)
21876+#define __COMPAT_NO_ID(name, data, compat) \
21877+ name(data)
21878+#endif
2ba6f0dd 21879+
2ba6f0dd 21880+
4bf69007
AM
21881+static inline
21882+long do_vcmd(uint32_t cmd, uint32_t id,
21883+ struct vx_info *vxi, struct nx_info *nxi,
21884+ void __user *data, int compat)
21885+{
21886+ switch (cmd) {
2ba6f0dd 21887+
4bf69007
AM
21888+ case VCMD_get_version:
21889+ return vc_get_version(id);
21890+ case VCMD_get_vci:
21891+ return vc_get_vci(id);
2ba6f0dd 21892+
4bf69007
AM
21893+ case VCMD_task_xid:
21894+ return vc_task_xid(id);
21895+ case VCMD_vx_info:
21896+ return vc_vx_info(vxi, data);
2ba6f0dd 21897+
4bf69007
AM
21898+ case VCMD_task_nid:
21899+ return vc_task_nid(id);
21900+ case VCMD_nx_info:
21901+ return vc_nx_info(nxi, data);
2ba6f0dd 21902+
4bf69007
AM
21903+ case VCMD_task_tag:
21904+ return vc_task_tag(id);
2ba6f0dd 21905+
4bf69007
AM
21906+ case VCMD_set_space_v1:
21907+ return vc_set_space_v1(vxi, data);
21908+ /* this is version 2 */
21909+ case VCMD_set_space:
21910+ return vc_set_space(vxi, data);
2ba6f0dd 21911+
4bf69007
AM
21912+ case VCMD_get_space_mask_v0:
21913+ return vc_get_space_mask(data, 0);
21914+ /* this is version 1 */
21915+ case VCMD_get_space_mask:
21916+ return vc_get_space_mask(data, 1);
2ba6f0dd 21917+
4bf69007
AM
21918+ case VCMD_get_space_default:
21919+ return vc_get_space_mask(data, -1);
2ba6f0dd 21920+
4bf69007
AM
21921+ case VCMD_set_umask:
21922+ return vc_set_umask(vxi, data);
2ba6f0dd 21923+
4bf69007
AM
21924+ case VCMD_get_umask:
21925+ return vc_get_umask(vxi, data);
2ba6f0dd 21926+
4bf69007
AM
21927+ case VCMD_set_wmask:
21928+ return vc_set_wmask(vxi, data);
2ba6f0dd 21929+
4bf69007
AM
21930+ case VCMD_get_wmask:
21931+ return vc_get_wmask(vxi, data);
21932+#ifdef CONFIG_IA32_EMULATION
21933+ case VCMD_get_rlimit:
21934+ return __COMPAT(vc_get_rlimit, vxi, data, compat);
21935+ case VCMD_set_rlimit:
21936+ return __COMPAT(vc_set_rlimit, vxi, data, compat);
21937+#else
21938+ case VCMD_get_rlimit:
21939+ return vc_get_rlimit(vxi, data);
21940+ case VCMD_set_rlimit:
21941+ return vc_set_rlimit(vxi, data);
21942+#endif
21943+ case VCMD_get_rlimit_mask:
21944+ return vc_get_rlimit_mask(id, data);
21945+ case VCMD_reset_hits:
21946+ return vc_reset_hits(vxi, data);
21947+ case VCMD_reset_minmax:
21948+ return vc_reset_minmax(vxi, data);
2ba6f0dd 21949+
4bf69007
AM
21950+ case VCMD_get_vhi_name:
21951+ return vc_get_vhi_name(vxi, data);
21952+ case VCMD_set_vhi_name:
21953+ return vc_set_vhi_name(vxi, data);
2ba6f0dd 21954+
4bf69007
AM
21955+ case VCMD_ctx_stat:
21956+ return vc_ctx_stat(vxi, data);
21957+ case VCMD_virt_stat:
21958+ return vc_virt_stat(vxi, data);
21959+ case VCMD_sock_stat:
21960+ return vc_sock_stat(vxi, data);
21961+ case VCMD_rlimit_stat:
21962+ return vc_rlimit_stat(vxi, data);
2ba6f0dd 21963+
4bf69007
AM
21964+ case VCMD_set_cflags:
21965+ return vc_set_cflags(vxi, data);
21966+ case VCMD_get_cflags:
21967+ return vc_get_cflags(vxi, data);
2ba6f0dd 21968+
4bf69007
AM
21969+ /* this is version 1 */
21970+ case VCMD_set_ccaps:
21971+ return vc_set_ccaps(vxi, data);
21972+ /* this is version 1 */
21973+ case VCMD_get_ccaps:
21974+ return vc_get_ccaps(vxi, data);
21975+ case VCMD_set_bcaps:
21976+ return vc_set_bcaps(vxi, data);
21977+ case VCMD_get_bcaps:
21978+ return vc_get_bcaps(vxi, data);
2ba6f0dd 21979+
4bf69007
AM
21980+ case VCMD_set_badness:
21981+ return vc_set_badness(vxi, data);
21982+ case VCMD_get_badness:
21983+ return vc_get_badness(vxi, data);
2ba6f0dd 21984+
4bf69007
AM
21985+ case VCMD_set_nflags:
21986+ return vc_set_nflags(nxi, data);
21987+ case VCMD_get_nflags:
21988+ return vc_get_nflags(nxi, data);
2ba6f0dd 21989+
4bf69007
AM
21990+ case VCMD_set_ncaps:
21991+ return vc_set_ncaps(nxi, data);
21992+ case VCMD_get_ncaps:
21993+ return vc_get_ncaps(nxi, data);
2ba6f0dd 21994+
4bf69007
AM
21995+ case VCMD_set_prio_bias:
21996+ return vc_set_prio_bias(vxi, data);
21997+ case VCMD_get_prio_bias:
21998+ return vc_get_prio_bias(vxi, data);
21999+ case VCMD_add_dlimit:
22000+ return __COMPAT(vc_add_dlimit, id, data, compat);
22001+ case VCMD_rem_dlimit:
22002+ return __COMPAT(vc_rem_dlimit, id, data, compat);
22003+ case VCMD_set_dlimit:
22004+ return __COMPAT(vc_set_dlimit, id, data, compat);
22005+ case VCMD_get_dlimit:
22006+ return __COMPAT(vc_get_dlimit, id, data, compat);
2ba6f0dd 22007+
4bf69007
AM
22008+ case VCMD_ctx_kill:
22009+ return vc_ctx_kill(vxi, data);
2ba6f0dd 22010+
4bf69007
AM
22011+ case VCMD_wait_exit:
22012+ return vc_wait_exit(vxi, data);
2ba6f0dd 22013+
4bf69007
AM
22014+ case VCMD_get_iattr:
22015+ return __COMPAT_NO_ID(vc_get_iattr, data, compat);
22016+ case VCMD_set_iattr:
22017+ return __COMPAT_NO_ID(vc_set_iattr, data, compat);
2ba6f0dd 22018+
4bf69007
AM
22019+ case VCMD_fget_iattr:
22020+ return vc_fget_iattr(id, data);
22021+ case VCMD_fset_iattr:
22022+ return vc_fset_iattr(id, data);
2ba6f0dd 22023+
4bf69007
AM
22024+ case VCMD_enter_space_v0:
22025+ return vc_enter_space_v1(vxi, NULL);
22026+ case VCMD_enter_space_v1:
22027+ return vc_enter_space_v1(vxi, data);
22028+ /* this is version 2 */
22029+ case VCMD_enter_space:
22030+ return vc_enter_space(vxi, data);
2ba6f0dd 22031+
4bf69007
AM
22032+ case VCMD_ctx_create_v0:
22033+ return vc_ctx_create(id, NULL);
22034+ case VCMD_ctx_create:
22035+ return vc_ctx_create(id, data);
22036+ case VCMD_ctx_migrate_v0:
22037+ return vc_ctx_migrate(vxi, NULL);
22038+ case VCMD_ctx_migrate:
22039+ return vc_ctx_migrate(vxi, data);
2ba6f0dd 22040+
4bf69007
AM
22041+ case VCMD_net_create_v0:
22042+ return vc_net_create(id, NULL);
22043+ case VCMD_net_create:
22044+ return vc_net_create(id, data);
22045+ case VCMD_net_migrate:
22046+ return vc_net_migrate(nxi, data);
2ba6f0dd 22047+
4bf69007
AM
22048+ case VCMD_tag_migrate:
22049+ return vc_tag_migrate(id);
2ba6f0dd 22050+
4bf69007
AM
22051+ case VCMD_net_add:
22052+ return vc_net_add(nxi, data);
22053+ case VCMD_net_remove:
22054+ return vc_net_remove(nxi, data);
2ba6f0dd 22055+
4bf69007
AM
22056+ case VCMD_net_add_ipv4_v1:
22057+ return vc_net_add_ipv4_v1(nxi, data);
22058+ /* this is version 2 */
22059+ case VCMD_net_add_ipv4:
22060+ return vc_net_add_ipv4(nxi, data);
2ba6f0dd 22061+
4bf69007
AM
22062+ case VCMD_net_rem_ipv4_v1:
22063+ return vc_net_rem_ipv4_v1(nxi, data);
22064+ /* this is version 2 */
22065+ case VCMD_net_rem_ipv4:
22066+ return vc_net_rem_ipv4(nxi, data);
22067+#ifdef CONFIG_IPV6
22068+ case VCMD_net_add_ipv6:
22069+ return vc_net_add_ipv6(nxi, data);
22070+ case VCMD_net_remove_ipv6:
22071+ return vc_net_remove_ipv6(nxi, data);
22072+#endif
22073+/* case VCMD_add_match_ipv4:
22074+ return vc_add_match_ipv4(nxi, data);
22075+ case VCMD_get_match_ipv4:
22076+ return vc_get_match_ipv4(nxi, data);
22077+#ifdef CONFIG_IPV6
22078+ case VCMD_add_match_ipv6:
22079+ return vc_add_match_ipv6(nxi, data);
22080+ case VCMD_get_match_ipv6:
22081+ return vc_get_match_ipv6(nxi, data);
22082+#endif */
2ba6f0dd 22083+
4bf69007
AM
22084+#ifdef CONFIG_VSERVER_DEVICE
22085+ case VCMD_set_mapping:
22086+ return __COMPAT(vc_set_mapping, vxi, data, compat);
22087+ case VCMD_unset_mapping:
22088+ return __COMPAT(vc_unset_mapping, vxi, data, compat);
22089+#endif
22090+#ifdef CONFIG_VSERVER_HISTORY
22091+ case VCMD_dump_history:
22092+ return vc_dump_history(id);
22093+ case VCMD_read_history:
22094+ return __COMPAT(vc_read_history, id, data, compat);
22095+#endif
22096+ default:
22097+ vxwprintk_task(1, "unimplemented VCMD_%02d_%d[%d]",
22098+ VC_CATEGORY(cmd), VC_COMMAND(cmd), VC_VERSION(cmd));
22099+ }
22100+ return -ENOSYS;
22101+}
2ba6f0dd 22102+
2ba6f0dd 22103+
4bf69007
AM
22104+#define __VCMD(vcmd, _perm, _args, _flags) \
22105+ case VCMD_ ## vcmd: perm = _perm; \
22106+ args = _args; flags = _flags; break
2ba6f0dd 22107+
2ba6f0dd 22108+
4bf69007
AM
22109+#define VCA_NONE 0x00
22110+#define VCA_VXI 0x01
22111+#define VCA_NXI 0x02
2ba6f0dd 22112+
4bf69007
AM
22113+#define VCF_NONE 0x00
22114+#define VCF_INFO 0x01
22115+#define VCF_ADMIN 0x02
22116+#define VCF_ARES 0x06 /* includes admin */
22117+#define VCF_SETUP 0x08
2ba6f0dd 22118+
4bf69007 22119+#define VCF_ZIDOK 0x10 /* zero id okay */
2ba6f0dd 22120+
2ba6f0dd
AM
22121+
22122+static inline
4bf69007 22123+long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat)
2ba6f0dd 22124+{
4bf69007
AM
22125+ long ret;
22126+ int permit = -1, state = 0;
22127+ int perm = -1, args = 0, flags = 0;
22128+ struct vx_info *vxi = NULL;
22129+ struct nx_info *nxi = NULL;
2ba6f0dd 22130+
4bf69007
AM
22131+ switch (cmd) {
22132+ /* unpriviledged commands */
22133+ __VCMD(get_version, 0, VCA_NONE, 0);
22134+ __VCMD(get_vci, 0, VCA_NONE, 0);
22135+ __VCMD(get_rlimit_mask, 0, VCA_NONE, 0);
22136+ __VCMD(get_space_mask_v0,0, VCA_NONE, 0);
22137+ __VCMD(get_space_mask, 0, VCA_NONE, 0);
22138+ __VCMD(get_space_default,0, VCA_NONE, 0);
2ba6f0dd 22139+
4bf69007
AM
22140+ /* info commands */
22141+ __VCMD(task_xid, 2, VCA_NONE, 0);
22142+ __VCMD(reset_hits, 2, VCA_VXI, 0);
22143+ __VCMD(reset_minmax, 2, VCA_VXI, 0);
22144+ __VCMD(vx_info, 3, VCA_VXI, VCF_INFO);
22145+ __VCMD(get_bcaps, 3, VCA_VXI, VCF_INFO);
22146+ __VCMD(get_ccaps, 3, VCA_VXI, VCF_INFO);
22147+ __VCMD(get_cflags, 3, VCA_VXI, VCF_INFO);
22148+ __VCMD(get_umask, 3, VCA_VXI, VCF_INFO);
22149+ __VCMD(get_wmask, 3, VCA_VXI, VCF_INFO);
22150+ __VCMD(get_badness, 3, VCA_VXI, VCF_INFO);
22151+ __VCMD(get_vhi_name, 3, VCA_VXI, VCF_INFO);
22152+ __VCMD(get_rlimit, 3, VCA_VXI, VCF_INFO);
2ba6f0dd 22153+
4bf69007
AM
22154+ __VCMD(ctx_stat, 3, VCA_VXI, VCF_INFO);
22155+ __VCMD(virt_stat, 3, VCA_VXI, VCF_INFO);
22156+ __VCMD(sock_stat, 3, VCA_VXI, VCF_INFO);
22157+ __VCMD(rlimit_stat, 3, VCA_VXI, VCF_INFO);
2ba6f0dd 22158+
4bf69007
AM
22159+ __VCMD(task_nid, 2, VCA_NONE, 0);
22160+ __VCMD(nx_info, 3, VCA_NXI, VCF_INFO);
22161+ __VCMD(get_ncaps, 3, VCA_NXI, VCF_INFO);
22162+ __VCMD(get_nflags, 3, VCA_NXI, VCF_INFO);
2ba6f0dd 22163+
4bf69007 22164+ __VCMD(task_tag, 2, VCA_NONE, 0);
2ba6f0dd 22165+
4bf69007
AM
22166+ __VCMD(get_iattr, 2, VCA_NONE, 0);
22167+ __VCMD(fget_iattr, 2, VCA_NONE, 0);
22168+ __VCMD(get_dlimit, 3, VCA_NONE, VCF_INFO);
22169+ __VCMD(get_prio_bias, 3, VCA_VXI, VCF_INFO);
2ba6f0dd 22170+
4bf69007
AM
22171+ /* lower admin commands */
22172+ __VCMD(wait_exit, 4, VCA_VXI, VCF_INFO);
22173+ __VCMD(ctx_create_v0, 5, VCA_NONE, 0);
22174+ __VCMD(ctx_create, 5, VCA_NONE, 0);
22175+ __VCMD(ctx_migrate_v0, 5, VCA_VXI, VCF_ADMIN);
22176+ __VCMD(ctx_migrate, 5, VCA_VXI, VCF_ADMIN);
22177+ __VCMD(enter_space_v0, 5, VCA_VXI, VCF_ADMIN);
22178+ __VCMD(enter_space_v1, 5, VCA_VXI, VCF_ADMIN);
22179+ __VCMD(enter_space, 5, VCA_VXI, VCF_ADMIN);
2ba6f0dd 22180+
4bf69007
AM
22181+ __VCMD(net_create_v0, 5, VCA_NONE, 0);
22182+ __VCMD(net_create, 5, VCA_NONE, 0);
22183+ __VCMD(net_migrate, 5, VCA_NXI, VCF_ADMIN);
2ba6f0dd 22184+
4bf69007 22185+ __VCMD(tag_migrate, 5, VCA_NONE, VCF_ADMIN);
2ba6f0dd 22186+
4bf69007
AM
22187+ /* higher admin commands */
22188+ __VCMD(ctx_kill, 6, VCA_VXI, VCF_ARES);
22189+ __VCMD(set_space_v1, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22190+ __VCMD(set_space, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
2ba6f0dd 22191+
4bf69007
AM
22192+ __VCMD(set_ccaps, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22193+ __VCMD(set_bcaps, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22194+ __VCMD(set_cflags, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22195+ __VCMD(set_umask, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22196+ __VCMD(set_wmask, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22197+ __VCMD(set_badness, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
2ba6f0dd 22198+
4bf69007
AM
22199+ __VCMD(set_vhi_name, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22200+ __VCMD(set_rlimit, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22201+ __VCMD(set_prio_bias, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
2ba6f0dd 22202+
4bf69007
AM
22203+ __VCMD(set_ncaps, 7, VCA_NXI, VCF_ARES | VCF_SETUP);
22204+ __VCMD(set_nflags, 7, VCA_NXI, VCF_ARES | VCF_SETUP);
22205+ __VCMD(net_add, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22206+ __VCMD(net_remove, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22207+ __VCMD(net_add_ipv4_v1, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22208+ __VCMD(net_rem_ipv4_v1, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22209+ __VCMD(net_add_ipv4, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22210+ __VCMD(net_rem_ipv4, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22211+#ifdef CONFIG_IPV6
22212+ __VCMD(net_add_ipv6, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22213+ __VCMD(net_remove_ipv6, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22214+#endif
22215+ __VCMD(set_iattr, 7, VCA_NONE, 0);
22216+ __VCMD(fset_iattr, 7, VCA_NONE, 0);
22217+ __VCMD(set_dlimit, 7, VCA_NONE, VCF_ARES);
22218+ __VCMD(add_dlimit, 8, VCA_NONE, VCF_ARES);
22219+ __VCMD(rem_dlimit, 8, VCA_NONE, VCF_ARES);
2ba6f0dd 22220+
4bf69007
AM
22221+#ifdef CONFIG_VSERVER_DEVICE
22222+ __VCMD(set_mapping, 8, VCA_VXI, VCF_ARES|VCF_ZIDOK);
22223+ __VCMD(unset_mapping, 8, VCA_VXI, VCF_ARES|VCF_ZIDOK);
22224+#endif
22225+ /* debug level admin commands */
22226+#ifdef CONFIG_VSERVER_HISTORY
22227+ __VCMD(dump_history, 9, VCA_NONE, 0);
22228+ __VCMD(read_history, 9, VCA_NONE, 0);
22229+#endif
2ba6f0dd 22230+
4bf69007
AM
22231+ default:
22232+ perm = -1;
22233+ }
2ba6f0dd 22234+
4bf69007
AM
22235+ vxdprintk(VXD_CBIT(switch, 0),
22236+ "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]",
22237+ VC_CATEGORY(cmd), VC_COMMAND(cmd),
22238+ VC_VERSION(cmd), id, data, compat,
22239+ perm, args, flags);
2ba6f0dd 22240+
4bf69007
AM
22241+ ret = -ENOSYS;
22242+ if (perm < 0)
22243+ goto out;
2ba6f0dd 22244+
4bf69007
AM
22245+ state = 1;
22246+ if (!capable(CAP_CONTEXT))
22247+ goto out;
2ba6f0dd 22248+
4bf69007
AM
22249+ state = 2;
22250+ /* moved here from the individual commands */
22251+ ret = -EPERM;
22252+ if ((perm > 1) && !capable(CAP_SYS_ADMIN))
22253+ goto out;
2ba6f0dd 22254+
4bf69007
AM
22255+ state = 3;
22256+ /* vcmd involves resource management */
22257+ ret = -EPERM;
22258+ if ((flags & VCF_ARES) && !capable(CAP_SYS_RESOURCE))
22259+ goto out;
2ba6f0dd 22260+
4bf69007
AM
22261+ state = 4;
22262+ /* various legacy exceptions */
22263+ switch (cmd) {
22264+ /* will go away when spectator is a cap */
22265+ case VCMD_ctx_migrate_v0:
22266+ case VCMD_ctx_migrate:
22267+ if (id == 1) {
22268+ current->xid = 1;
22269+ ret = 1;
22270+ goto out;
22271+ }
22272+ break;
2ba6f0dd 22273+
4bf69007
AM
22274+ /* will go away when spectator is a cap */
22275+ case VCMD_net_migrate:
22276+ if (id == 1) {
22277+ current->nid = 1;
22278+ ret = 1;
22279+ goto out;
22280+ }
22281+ break;
22282+ }
2ba6f0dd 22283+
4bf69007
AM
22284+ /* vcmds are fine by default */
22285+ permit = 1;
2ba6f0dd 22286+
4bf69007
AM
22287+ /* admin type vcmds require admin ... */
22288+ if (flags & VCF_ADMIN)
22289+ permit = vx_check(0, VS_ADMIN) ? 1 : 0;
2ba6f0dd 22290+
4bf69007
AM
22291+ /* ... but setup type vcmds override that */
22292+ if (!permit && (flags & VCF_SETUP))
22293+ permit = vx_flags(VXF_STATE_SETUP, 0) ? 2 : 0;
2ba6f0dd 22294+
4bf69007
AM
22295+ state = 5;
22296+ ret = -EPERM;
22297+ if (!permit)
22298+ goto out;
2ba6f0dd 22299+
4bf69007
AM
22300+ state = 6;
22301+ if (!id && (flags & VCF_ZIDOK))
22302+ goto skip_id;
2ba6f0dd 22303+
4bf69007
AM
22304+ ret = -ESRCH;
22305+ if (args & VCA_VXI) {
22306+ vxi = lookup_vx_info(id);
22307+ if (!vxi)
22308+ goto out;
2ba6f0dd 22309+
4bf69007
AM
22310+ if ((flags & VCF_ADMIN) &&
22311+ /* special case kill for shutdown */
22312+ (cmd != VCMD_ctx_kill) &&
22313+ /* can context be administrated? */
22314+ !vx_info_flags(vxi, VXF_STATE_ADMIN, 0)) {
22315+ ret = -EACCES;
22316+ goto out_vxi;
22317+ }
22318+ }
22319+ state = 7;
22320+ if (args & VCA_NXI) {
22321+ nxi = lookup_nx_info(id);
22322+ if (!nxi)
22323+ goto out_vxi;
2ba6f0dd 22324+
4bf69007
AM
22325+ if ((flags & VCF_ADMIN) &&
22326+ /* can context be administrated? */
22327+ !nx_info_flags(nxi, NXF_STATE_ADMIN, 0)) {
22328+ ret = -EACCES;
22329+ goto out_nxi;
22330+ }
22331+ }
22332+skip_id:
22333+ state = 8;
22334+ ret = do_vcmd(cmd, id, vxi, nxi, data, compat);
2ba6f0dd 22335+
4bf69007
AM
22336+out_nxi:
22337+ if ((args & VCA_NXI) && nxi)
22338+ put_nx_info(nxi);
22339+out_vxi:
22340+ if ((args & VCA_VXI) && vxi)
22341+ put_vx_info(vxi);
22342+out:
22343+ vxdprintk(VXD_CBIT(switch, 1),
22344+ "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]",
22345+ VC_CATEGORY(cmd), VC_COMMAND(cmd),
22346+ VC_VERSION(cmd), ret, ret, state, permit);
22347+ return ret;
22348+}
2ba6f0dd 22349+
4bf69007
AM
22350+asmlinkage long
22351+sys_vserver(uint32_t cmd, uint32_t id, void __user *data)
22352+{
22353+ return do_vserver(cmd, id, data, 0);
22354+}
2ba6f0dd 22355+
4bf69007 22356+#ifdef CONFIG_COMPAT
2ba6f0dd 22357+
4bf69007
AM
22358+asmlinkage long
22359+sys32_vserver(uint32_t cmd, uint32_t id, void __user *data)
22360+{
22361+ return do_vserver(cmd, id, data, 1);
22362+}
2ba6f0dd 22363+
4bf69007 22364+#endif /* CONFIG_COMPAT */
cef7ea10
AM
22365diff -NurpP --minimal linux-4.9.82/kernel/vserver/sysctl.c linux-4.9.82-vs2.3.9.7/kernel/vserver/sysctl.c
22366--- linux-4.9.82/kernel/vserver/sysctl.c 1970-01-01 00:00:00.000000000 +0000
22367+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/sysctl.c 2018-01-13 05:37:59.000000000 +0000
cc23e853 22368@@ -0,0 +1,249 @@
4bf69007
AM
22369+/*
22370+ * kernel/vserver/sysctl.c
22371+ *
22372+ * Virtual Context Support
22373+ *
cc23e853 22374+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
22375+ *
22376+ * V0.01 basic structure
22377+ *
22378+ */
2ba6f0dd 22379+
4bf69007
AM
22380+#include <linux/module.h>
22381+#include <linux/ctype.h>
22382+#include <linux/sysctl.h>
22383+#include <linux/parser.h>
cc23e853
AM
22384+#include <linux/utsname.h>
22385+
4bf69007 22386+#include <asm/uaccess.h>
cc23e853 22387+#include <asm/sections.h>
2ba6f0dd 22388+
4bf69007
AM
22389+enum {
22390+ CTL_DEBUG_ERROR = 0,
22391+ CTL_DEBUG_SWITCH = 1,
22392+ CTL_DEBUG_XID,
22393+ CTL_DEBUG_NID,
22394+ CTL_DEBUG_TAG,
22395+ CTL_DEBUG_NET,
22396+ CTL_DEBUG_LIMIT,
22397+ CTL_DEBUG_CRES,
22398+ CTL_DEBUG_DLIM,
22399+ CTL_DEBUG_QUOTA,
22400+ CTL_DEBUG_CVIRT,
22401+ CTL_DEBUG_SPACE,
22402+ CTL_DEBUG_PERM,
22403+ CTL_DEBUG_MISC,
2ba6f0dd
AM
22404+};
22405+
2ba6f0dd 22406+
4bf69007
AM
22407+unsigned int vs_debug_switch = 0;
22408+unsigned int vs_debug_xid = 0;
22409+unsigned int vs_debug_nid = 0;
22410+unsigned int vs_debug_tag = 0;
22411+unsigned int vs_debug_net = 0;
22412+unsigned int vs_debug_limit = 0;
22413+unsigned int vs_debug_cres = 0;
22414+unsigned int vs_debug_dlim = 0;
22415+unsigned int vs_debug_quota = 0;
22416+unsigned int vs_debug_cvirt = 0;
22417+unsigned int vs_debug_space = 0;
22418+unsigned int vs_debug_perm = 0;
22419+unsigned int vs_debug_misc = 0;
2ba6f0dd 22420+
2ba6f0dd 22421+
4bf69007 22422+static struct ctl_table_header *vserver_table_header;
bb20add7 22423+static struct ctl_table vserver_root_table[];
4bf69007 22424+
2ba6f0dd 22425+
4bf69007
AM
22426+void vserver_register_sysctl(void)
22427+{
22428+ if (!vserver_table_header) {
22429+ vserver_table_header = register_sysctl_table(vserver_root_table);
22430+ }
2ba6f0dd 22431+
4bf69007 22432+}
2ba6f0dd 22433+
4bf69007
AM
22434+void vserver_unregister_sysctl(void)
22435+{
22436+ if (vserver_table_header) {
22437+ unregister_sysctl_table(vserver_table_header);
22438+ vserver_table_header = NULL;
22439+ }
22440+}
2ba6f0dd 22441+
bb20add7 22442+static int proc_dodebug(struct ctl_table *table, int write,
4bf69007
AM
22443+ void __user *buffer, size_t *lenp, loff_t *ppos)
22444+{
22445+ char tmpbuf[20], *p, c;
22446+ unsigned int value;
22447+ size_t left, len;
2ba6f0dd 22448+
4bf69007
AM
22449+ if ((*ppos && !write) || !*lenp) {
22450+ *lenp = 0;
22451+ return 0;
22452+ }
2ba6f0dd 22453+
4bf69007 22454+ left = *lenp;
2ba6f0dd 22455+
4bf69007
AM
22456+ if (write) {
22457+ if (!access_ok(VERIFY_READ, buffer, left))
22458+ return -EFAULT;
22459+ p = (char *)buffer;
22460+ while (left && __get_user(c, p) >= 0 && isspace(c))
22461+ left--, p++;
22462+ if (!left)
22463+ goto done;
2ba6f0dd 22464+
4bf69007
AM
22465+ if (left > sizeof(tmpbuf) - 1)
22466+ return -EINVAL;
22467+ if (copy_from_user(tmpbuf, p, left))
22468+ return -EFAULT;
22469+ tmpbuf[left] = '\0';
2ba6f0dd 22470+
4bf69007
AM
22471+ for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--)
22472+ value = 10 * value + (*p - '0');
22473+ if (*p && !isspace(*p))
22474+ return -EINVAL;
22475+ while (left && isspace(*p))
22476+ left--, p++;
22477+ *(unsigned int *)table->data = value;
22478+ } else {
22479+ if (!access_ok(VERIFY_WRITE, buffer, left))
22480+ return -EFAULT;
22481+ len = sprintf(tmpbuf, "%d", *(unsigned int *)table->data);
22482+ if (len > left)
22483+ len = left;
22484+ if (__copy_to_user(buffer, tmpbuf, len))
22485+ return -EFAULT;
22486+ if ((left -= len) > 0) {
22487+ if (put_user('\n', (char *)buffer + len))
22488+ return -EFAULT;
22489+ left--;
22490+ }
22491+ }
2ba6f0dd 22492+
4bf69007
AM
22493+done:
22494+ *lenp -= left;
22495+ *ppos += *lenp;
22496+ return 0;
22497+}
2ba6f0dd 22498+
4bf69007 22499+static int zero;
2ba6f0dd 22500+
4bf69007
AM
22501+#define CTL_ENTRY(ctl, name) \
22502+ { \
22503+ .procname = #name, \
22504+ .data = &vs_ ## name, \
22505+ .maxlen = sizeof(int), \
22506+ .mode = 0644, \
22507+ .proc_handler = &proc_dodebug, \
22508+ .extra1 = &zero, \
22509+ .extra2 = &zero, \
22510+ }
2ba6f0dd 22511+
bb20add7 22512+static struct ctl_table vserver_debug_table[] = {
4bf69007
AM
22513+ CTL_ENTRY(CTL_DEBUG_SWITCH, debug_switch),
22514+ CTL_ENTRY(CTL_DEBUG_XID, debug_xid),
22515+ CTL_ENTRY(CTL_DEBUG_NID, debug_nid),
22516+ CTL_ENTRY(CTL_DEBUG_TAG, debug_tag),
22517+ CTL_ENTRY(CTL_DEBUG_NET, debug_net),
22518+ CTL_ENTRY(CTL_DEBUG_LIMIT, debug_limit),
22519+ CTL_ENTRY(CTL_DEBUG_CRES, debug_cres),
22520+ CTL_ENTRY(CTL_DEBUG_DLIM, debug_dlim),
22521+ CTL_ENTRY(CTL_DEBUG_QUOTA, debug_quota),
22522+ CTL_ENTRY(CTL_DEBUG_CVIRT, debug_cvirt),
22523+ CTL_ENTRY(CTL_DEBUG_SPACE, debug_space),
22524+ CTL_ENTRY(CTL_DEBUG_PERM, debug_perm),
22525+ CTL_ENTRY(CTL_DEBUG_MISC, debug_misc),
22526+ { 0 }
22527+};
2ba6f0dd 22528+
bb20add7 22529+static struct ctl_table vserver_root_table[] = {
4bf69007
AM
22530+ {
22531+ .procname = "vserver",
22532+ .mode = 0555,
22533+ .child = vserver_debug_table
22534+ },
22535+ { 0 }
22536+};
2ba6f0dd 22537+
2ba6f0dd 22538+
4bf69007
AM
22539+static match_table_t tokens = {
22540+ { CTL_DEBUG_SWITCH, "switch=%x" },
22541+ { CTL_DEBUG_XID, "xid=%x" },
22542+ { CTL_DEBUG_NID, "nid=%x" },
22543+ { CTL_DEBUG_TAG, "tag=%x" },
22544+ { CTL_DEBUG_NET, "net=%x" },
22545+ { CTL_DEBUG_LIMIT, "limit=%x" },
22546+ { CTL_DEBUG_CRES, "cres=%x" },
22547+ { CTL_DEBUG_DLIM, "dlim=%x" },
22548+ { CTL_DEBUG_QUOTA, "quota=%x" },
22549+ { CTL_DEBUG_CVIRT, "cvirt=%x" },
22550+ { CTL_DEBUG_SPACE, "space=%x" },
22551+ { CTL_DEBUG_PERM, "perm=%x" },
22552+ { CTL_DEBUG_MISC, "misc=%x" },
22553+ { CTL_DEBUG_ERROR, NULL }
22554+};
2ba6f0dd 22555+
4bf69007
AM
22556+#define HANDLE_CASE(id, name, val) \
22557+ case CTL_DEBUG_ ## id: \
22558+ vs_debug_ ## name = val; \
22559+ printk("vs_debug_" #name "=0x%x\n", val); \
22560+ break
2ba6f0dd 22561+
2ba6f0dd 22562+
4bf69007
AM
22563+static int __init vs_debug_setup(char *str)
22564+{
22565+ char *p;
22566+ int token;
2ba6f0dd 22567+
4bf69007
AM
22568+ printk("vs_debug_setup(%s)\n", str);
22569+ while ((p = strsep(&str, ",")) != NULL) {
22570+ substring_t args[MAX_OPT_ARGS];
22571+ unsigned int value;
2ba6f0dd 22572+
4bf69007
AM
22573+ if (!*p)
22574+ continue;
2ba6f0dd 22575+
4bf69007
AM
22576+ token = match_token(p, tokens, args);
22577+ value = (token > 0) ? simple_strtoul(args[0].from, NULL, 0) : 0;
2ba6f0dd 22578+
4bf69007
AM
22579+ switch (token) {
22580+ HANDLE_CASE(SWITCH, switch, value);
22581+ HANDLE_CASE(XID, xid, value);
22582+ HANDLE_CASE(NID, nid, value);
22583+ HANDLE_CASE(TAG, tag, value);
22584+ HANDLE_CASE(NET, net, value);
22585+ HANDLE_CASE(LIMIT, limit, value);
22586+ HANDLE_CASE(CRES, cres, value);
22587+ HANDLE_CASE(DLIM, dlim, value);
22588+ HANDLE_CASE(QUOTA, quota, value);
22589+ HANDLE_CASE(CVIRT, cvirt, value);
22590+ HANDLE_CASE(SPACE, space, value);
22591+ HANDLE_CASE(PERM, perm, value);
22592+ HANDLE_CASE(MISC, misc, value);
22593+ default:
22594+ return -EINVAL;
22595+ break;
22596+ }
22597+ }
22598+ return 1;
22599+}
2ba6f0dd 22600+
4bf69007 22601+__setup("vsdebug=", vs_debug_setup);
2ba6f0dd 22602+
2ba6f0dd 22603+
2ba6f0dd 22604+
4bf69007
AM
22605+EXPORT_SYMBOL_GPL(vs_debug_switch);
22606+EXPORT_SYMBOL_GPL(vs_debug_xid);
22607+EXPORT_SYMBOL_GPL(vs_debug_nid);
22608+EXPORT_SYMBOL_GPL(vs_debug_net);
22609+EXPORT_SYMBOL_GPL(vs_debug_limit);
22610+EXPORT_SYMBOL_GPL(vs_debug_cres);
22611+EXPORT_SYMBOL_GPL(vs_debug_dlim);
22612+EXPORT_SYMBOL_GPL(vs_debug_quota);
22613+EXPORT_SYMBOL_GPL(vs_debug_cvirt);
22614+EXPORT_SYMBOL_GPL(vs_debug_space);
22615+EXPORT_SYMBOL_GPL(vs_debug_perm);
22616+EXPORT_SYMBOL_GPL(vs_debug_misc);
2ba6f0dd 22617+
cef7ea10
AM
22618diff -NurpP --minimal linux-4.9.82/kernel/vserver/tag.c linux-4.9.82-vs2.3.9.7/kernel/vserver/tag.c
22619--- linux-4.9.82/kernel/vserver/tag.c 1970-01-01 00:00:00.000000000 +0000
22620+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/tag.c 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
22621@@ -0,0 +1,63 @@
22622+/*
22623+ * linux/kernel/vserver/tag.c
22624+ *
22625+ * Virtual Server: Shallow Tag Space
22626+ *
cc23e853 22627+ * Copyright (C) 2007 Herbert P?tzl
4bf69007
AM
22628+ *
22629+ * V0.01 basic implementation
22630+ *
22631+ */
2ba6f0dd 22632+
4bf69007
AM
22633+#include <linux/sched.h>
22634+#include <linux/vserver/debug.h>
22635+#include <linux/vs_pid.h>
22636+#include <linux/vs_tag.h>
2ba6f0dd 22637+
4bf69007 22638+#include <linux/vserver/tag_cmd.h>
2ba6f0dd 22639+
2ba6f0dd 22640+
61333608 22641+int dx_migrate_task(struct task_struct *p, vtag_t tag)
4bf69007
AM
22642+{
22643+ if (!p)
22644+ BUG();
2ba6f0dd 22645+
4bf69007
AM
22646+ vxdprintk(VXD_CBIT(tag, 5),
22647+ "dx_migrate_task(%p[#%d],#%d)", p, p->tag, tag);
2ba6f0dd 22648+
4bf69007
AM
22649+ task_lock(p);
22650+ p->tag = tag;
22651+ task_unlock(p);
2ba6f0dd 22652+
4bf69007
AM
22653+ vxdprintk(VXD_CBIT(tag, 5),
22654+ "moved task %p into [#%d]", p, tag);
22655+ return 0;
22656+}
2ba6f0dd 22657+
4bf69007 22658+/* vserver syscall commands below here */
2ba6f0dd 22659+
4bf69007 22660+/* taks xid and vx_info functions */
2ba6f0dd 22661+
2ba6f0dd 22662+
4bf69007
AM
22663+int vc_task_tag(uint32_t id)
22664+{
61333608 22665+ vtag_t tag;
2ba6f0dd 22666+
4bf69007
AM
22667+ if (id) {
22668+ struct task_struct *tsk;
22669+ rcu_read_lock();
22670+ tsk = find_task_by_real_pid(id);
22671+ tag = (tsk) ? tsk->tag : -ESRCH;
22672+ rcu_read_unlock();
22673+ } else
22674+ tag = dx_current_tag();
22675+ return tag;
22676+}
2ba6f0dd 22677+
2ba6f0dd 22678+
4bf69007
AM
22679+int vc_tag_migrate(uint32_t tag)
22680+{
22681+ return dx_migrate_task(current, tag & 0xFFFF);
22682+}
2ba6f0dd 22683+
2ba6f0dd 22684+
cef7ea10
AM
22685diff -NurpP --minimal linux-4.9.82/kernel/vserver/vci_config.h linux-4.9.82-vs2.3.9.7/kernel/vserver/vci_config.h
22686--- linux-4.9.82/kernel/vserver/vci_config.h 1970-01-01 00:00:00.000000000 +0000
22687+++ linux-4.9.82-vs2.3.9.7/kernel/vserver/vci_config.h 2018-01-10 02:50:49.000000000 +0000
4bf69007 22688@@ -0,0 +1,80 @@
2ba6f0dd 22689+
4bf69007 22690+/* interface version */
2ba6f0dd 22691+
4bf69007 22692+#define VCI_VERSION 0x00020308
2ba6f0dd 22693+
2ba6f0dd 22694+
4bf69007
AM
22695+enum {
22696+ VCI_KCBIT_NO_DYNAMIC = 0,
2ba6f0dd 22697+
4bf69007
AM
22698+ VCI_KCBIT_PROC_SECURE = 4,
22699+ /* VCI_KCBIT_HARDCPU = 5, */
22700+ /* VCI_KCBIT_IDLELIMIT = 6, */
22701+ /* VCI_KCBIT_IDLETIME = 7, */
2ba6f0dd 22702+
4bf69007
AM
22703+ VCI_KCBIT_COWBL = 8,
22704+ VCI_KCBIT_FULLCOWBL = 9,
22705+ VCI_KCBIT_SPACES = 10,
22706+ VCI_KCBIT_NETV2 = 11,
22707+ VCI_KCBIT_MEMCG = 12,
22708+ VCI_KCBIT_MEMCG_SWAP = 13,
2ba6f0dd 22709+
4bf69007
AM
22710+ VCI_KCBIT_DEBUG = 16,
22711+ VCI_KCBIT_HISTORY = 20,
22712+ VCI_KCBIT_TAGGED = 24,
22713+ VCI_KCBIT_PPTAG = 28,
2ba6f0dd 22714+
4bf69007 22715+ VCI_KCBIT_MORE = 31,
2ba6f0dd
AM
22716+};
22717+
2ba6f0dd 22718+
4bf69007
AM
22719+static inline uint32_t vci_kernel_config(void)
22720+{
22721+ return
22722+ (1 << VCI_KCBIT_NO_DYNAMIC) |
2ba6f0dd 22723+
4bf69007
AM
22724+ /* configured features */
22725+#ifdef CONFIG_VSERVER_PROC_SECURE
22726+ (1 << VCI_KCBIT_PROC_SECURE) |
22727+#endif
22728+#ifdef CONFIG_VSERVER_COWBL
22729+ (1 << VCI_KCBIT_COWBL) |
22730+ (1 << VCI_KCBIT_FULLCOWBL) |
22731+#endif
22732+ (1 << VCI_KCBIT_SPACES) |
22733+ (1 << VCI_KCBIT_NETV2) |
22734+#ifdef CONFIG_MEMCG
22735+ (1 << VCI_KCBIT_MEMCG) |
22736+#endif
22737+#ifdef CONFIG_MEMCG_SWAP
22738+ (1 << VCI_KCBIT_MEMCG_SWAP) |
22739+#endif
2ba6f0dd 22740+
4bf69007
AM
22741+ /* debug options */
22742+#ifdef CONFIG_VSERVER_DEBUG
22743+ (1 << VCI_KCBIT_DEBUG) |
22744+#endif
22745+#ifdef CONFIG_VSERVER_HISTORY
22746+ (1 << VCI_KCBIT_HISTORY) |
22747+#endif
2ba6f0dd 22748+
4bf69007
AM
22749+ /* inode context tagging */
22750+#if defined(CONFIG_TAGGING_NONE)
22751+ (0 << VCI_KCBIT_TAGGED) |
22752+#elif defined(CONFIG_TAGGING_UID16)
22753+ (1 << VCI_KCBIT_TAGGED) |
22754+#elif defined(CONFIG_TAGGING_GID16)
22755+ (2 << VCI_KCBIT_TAGGED) |
22756+#elif defined(CONFIG_TAGGING_ID24)
22757+ (3 << VCI_KCBIT_TAGGED) |
22758+#elif defined(CONFIG_TAGGING_INTERN)
22759+ (4 << VCI_KCBIT_TAGGED) |
22760+#elif defined(CONFIG_TAGGING_RUNTIME)
22761+ (5 << VCI_KCBIT_TAGGED) |
22762+#else
22763+ (7 << VCI_KCBIT_TAGGED) |
22764+#endif
22765+ (1 << VCI_KCBIT_PPTAG) |
22766+ 0;
22767+}
2ba6f0dd 22768+
cef7ea10
AM
22769diff -NurpP --minimal linux-4.9.82/mm/memcontrol.c linux-4.9.82-vs2.3.9.7/mm/memcontrol.c
22770--- linux-4.9.82/mm/memcontrol.c 2018-02-22 21:18:58.000000000 +0000
22771+++ linux-4.9.82-vs2.3.9.7/mm/memcontrol.c 2018-02-10 15:15:43.000000000 +0000
369dbd59 22772@@ -2825,6 +2825,41 @@ static u64 mem_cgroup_read_u64(struct cg
cc23e853 22773 }
4bf69007
AM
22774 }
22775
369dbd59
AM
22776+unsigned long mem_cgroup_mem_usage_pages(struct mem_cgroup *memcg)
22777+{
22778+ return mem_cgroup_usage(memcg, false);
22779+}
22780+
22781+unsigned long mem_cgroup_mem_limit_pages(struct mem_cgroup *memcg)
4bf69007 22782+{
369dbd59 22783+ return memcg->memory.limit;
4bf69007 22784+}
2ba6f0dd 22785+
369dbd59 22786+unsigned long mem_cgroup_memsw_usage_pages(struct mem_cgroup *memcg)
4bf69007 22787+{
369dbd59 22788+ return mem_cgroup_usage(memcg, true);
4bf69007 22789+}
2ba6f0dd 22790+
369dbd59 22791+unsigned long mem_cgroup_memsw_limit_pages(struct mem_cgroup *memcg)
4bf69007 22792+{
369dbd59 22793+ return memcg->memsw.limit;
4bf69007 22794+}
2ba6f0dd 22795+
369dbd59 22796+void dump_mem_cgroup(struct mem_cgroup *memcg)
4bf69007 22797+{
369dbd59
AM
22798+ printk(KERN_INFO "memcg: %p/%d:\n"
22799+ "\tmemory:\t%lu/%lu %lu/%lu\n"
22800+ "\tmemsw:\t%lu/%lu %lu/%lu\n"
22801+ "\tkmem:\t%lu/%lu %lu/%lu\n",
22802+ memcg, memcg->id.id,
22803+ page_counter_read(&memcg->memory), memcg->memory.limit,
22804+ memcg->memory.watermark, memcg->memory.failcnt,
22805+ page_counter_read(&memcg->memsw), memcg->memsw.limit,
22806+ memcg->memsw.watermark, memcg->memsw.failcnt,
22807+ page_counter_read(&memcg->kmem), memcg->kmem.limit,
22808+ memcg->kmem.watermark, memcg->kmem.failcnt);
4bf69007 22809+}
2ba6f0dd 22810+
cc23e853
AM
22811 #ifndef CONFIG_SLOB
22812 static int memcg_online_kmem(struct mem_cgroup *memcg)
22813 {
cef7ea10
AM
22814diff -NurpP --minimal linux-4.9.82/mm/oom_kill.c linux-4.9.82-vs2.3.9.7/mm/oom_kill.c
22815--- linux-4.9.82/mm/oom_kill.c 2018-02-22 21:18:58.000000000 +0000
22816+++ linux-4.9.82-vs2.3.9.7/mm/oom_kill.c 2018-01-10 08:54:40.000000000 +0000
cc23e853
AM
22817@@ -38,6 +38,8 @@
22818 #include <linux/kthread.h>
22819 #include <linux/init.h>
22820 #include <linux/mmu_notifier.h>
4bf69007
AM
22821+#include <linux/reboot.h>
22822+#include <linux/vs_context.h>
22823
cc23e853
AM
22824 #include <asm/tlb.h>
22825 #include "internal.h"
22826@@ -142,11 +144,18 @@ static inline bool is_memcg_oom(struct o
4bf69007 22827 static bool oom_unkillable_task(struct task_struct *p,
cc23e853 22828 struct mem_cgroup *memcg, const nodemask_t *nodemask)
4bf69007
AM
22829 {
22830- if (is_global_init(p))
22831+ unsigned xid = vx_current_xid();
2ba6f0dd 22832+
4bf69007
AM
22833+ /* skip the init task, global and per guest */
22834+ if (task_is_init(p))
22835 return true;
22836 if (p->flags & PF_KTHREAD)
22837 return true;
22838
22839+ /* skip other guest and host processes if oom in guest */
22840+ if (xid && vx_task_xid(p) != xid)
22841+ return true;
2ba6f0dd 22842+
4bf69007
AM
22843 /* When mem_cgroup_out_of_memory() and p is not member of the group */
22844 if (memcg && !task_in_mem_cgroup(p, memcg))
22845 return true;
cc23e853
AM
22846@@ -851,8 +860,8 @@ static void oom_kill_process(struct oom_
22847 if (__ratelimit(&oom_rs))
22848 dump_header(oc, p);
4bf69007 22849
cc23e853 22850- pr_err("%s: Kill process %d (%s) score %u or sacrifice child\n",
4bf69007
AM
22851- message, task_pid_nr(p), p->comm, points);
22852+ pr_err("%s: Kill process %d:#%u (%s) score %d or sacrifice child\n",
22853+ message, task_pid_nr(p), p->xid, p->comm, points);
4bf69007
AM
22854
22855 /*
cc23e853
AM
22856 * If any of p's children has a different mm and is eligible for kill,
22857@@ -902,8 +911,8 @@ static void oom_kill_process(struct oom_
22858 */
22859 do_send_sig_info(SIGKILL, SEND_SIG_FORCED, victim, true);
22860 mark_oom_victim(victim);
22861- pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n",
4bf69007 22862- task_pid_nr(victim), victim->comm, K(victim->mm->total_vm),
cc23e853 22863+ pr_err("Killed process %d:%u (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n",
4bf69007
AM
22864+ task_pid_nr(victim), victim->xid, victim->comm, K(victim->mm->total_vm),
22865 K(get_mm_counter(victim->mm, MM_ANONPAGES)),
cc23e853
AM
22866 K(get_mm_counter(victim->mm, MM_FILEPAGES)),
22867 K(get_mm_counter(victim->mm, MM_SHMEMPAGES)));
22868@@ -950,6 +959,8 @@ static void oom_kill_process(struct oom_
4bf69007 22869 }
cc23e853 22870 #undef K
4bf69007
AM
22871
22872+long vs_oom_action(unsigned int);
2ba6f0dd 22873+
4bf69007 22874 /*
cc23e853
AM
22875 * Determines whether the kernel must panic because of the panic_on_oom sysctl.
22876 */
22877@@ -1055,7 +1066,12 @@ bool out_of_memory(struct oom_control *o
4bf69007 22878 /* Found nothing?!?! Either we hang forever, or we panic. */
cc23e853
AM
22879 if (!oc->chosen && !is_sysrq_oom(oc) && !is_memcg_oom(oc)) {
22880 dump_header(oc, NULL);
4bf69007 22881- panic("Out of memory and no killable processes...\n");
2ba6f0dd 22882+
4bf69007
AM
22883+ /* avoid panic for guest OOM */
22884+ if (vx_current_xid())
22885+ vs_oom_action(LINUX_REBOOT_CMD_OOM);
22886+ else
22887+ panic("Out of memory and no killable processes...\n");
22888 }
cc23e853
AM
22889 if (oc->chosen && oc->chosen != (void *)-1UL) {
22890 oom_kill_process(oc, !is_memcg_oom(oc) ? "Out of memory" :
cef7ea10
AM
22891diff -NurpP --minimal linux-4.9.82/mm/page_alloc.c linux-4.9.82-vs2.3.9.7/mm/page_alloc.c
22892--- linux-4.9.82/mm/page_alloc.c 2018-02-22 21:18:58.000000000 +0000
22893+++ linux-4.9.82-vs2.3.9.7/mm/page_alloc.c 2018-02-10 15:15:43.000000000 +0000
cc23e853
AM
22894@@ -64,6 +64,8 @@
22895 #include <linux/page_owner.h>
22896 #include <linux/kthread.h>
22897 #include <linux/memcontrol.h>
4bf69007
AM
22898+#include <linux/vs_base.h>
22899+#include <linux/vs_limit.h>
22900
c2e5f7c8 22901 #include <asm/sections.h>
4bf69007 22902 #include <asm/tlbflush.h>
5ba7a31c 22903@@ -4199,6 +4201,9 @@ void si_meminfo(struct sysinfo *val)
4bf69007
AM
22904 val->totalhigh = totalhigh_pages;
22905 val->freehigh = nr_free_highpages();
22906 val->mem_unit = PAGE_SIZE;
2ba6f0dd 22907+
4bf69007
AM
22908+ if (vx_flags(VXF_VIRT_MEM, 0))
22909+ vx_vsi_meminfo(val);
22910 }
22911
22912 EXPORT_SYMBOL(si_meminfo);
5ba7a31c 22913@@ -4233,6 +4238,9 @@ void si_meminfo_node(struct sysinfo *val
cc23e853 22914 val->freehigh = free_highpages;
4bf69007
AM
22915 #endif
22916 val->mem_unit = PAGE_SIZE;
2ba6f0dd 22917+
4bf69007
AM
22918+ if (vx_flags(VXF_VIRT_MEM, 0))
22919+ vx_vsi_meminfo(val);
22920 }
22921 #endif
22922
cef7ea10
AM
22923diff -NurpP --minimal linux-4.9.82/mm/pgtable-generic.c linux-4.9.82-vs2.3.9.7/mm/pgtable-generic.c
22924--- linux-4.9.82/mm/pgtable-generic.c 2016-12-11 19:17:54.000000000 +0000
22925+++ linux-4.9.82-vs2.3.9.7/mm/pgtable-generic.c 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
22926@@ -6,6 +6,8 @@
22927 * Copyright (C) 2010 Linus Torvalds
22928 */
22929
22930+#include <linux/mm.h>
2ba6f0dd 22931+
4bf69007
AM
22932 #include <linux/pagemap.h>
22933 #include <asm/tlb.h>
22934 #include <asm-generic/pgtable.h>
cef7ea10
AM
22935diff -NurpP --minimal linux-4.9.82/mm/shmem.c linux-4.9.82-vs2.3.9.7/mm/shmem.c
22936--- linux-4.9.82/mm/shmem.c 2018-02-22 21:18:58.000000000 +0000
22937+++ linux-4.9.82-vs2.3.9.7/mm/shmem.c 2018-01-10 08:36:49.000000000 +0000
cc23e853 22938@@ -2785,7 +2785,7 @@ static int shmem_statfs(struct dentry *d
4bf69007
AM
22939 {
22940 struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
22941
22942- buf->f_type = TMPFS_MAGIC;
22943+ buf->f_type = TMPFS_SUPER_MAGIC;
cc23e853 22944 buf->f_bsize = PAGE_SIZE;
4bf69007
AM
22945 buf->f_namelen = NAME_MAX;
22946 if (sbinfo->max_blocks) {
cc23e853 22947@@ -3606,7 +3606,7 @@ int shmem_fill_super(struct super_block
4bf69007 22948 sb->s_maxbytes = MAX_LFS_FILESIZE;
cc23e853
AM
22949 sb->s_blocksize = PAGE_SIZE;
22950 sb->s_blocksize_bits = PAGE_SHIFT;
4bf69007
AM
22951- sb->s_magic = TMPFS_MAGIC;
22952+ sb->s_magic = TMPFS_SUPER_MAGIC;
22953 sb->s_op = &shmem_ops;
22954 sb->s_time_gran = 1;
22955 #ifdef CONFIG_TMPFS_XATTR
cef7ea10
AM
22956diff -NurpP --minimal linux-4.9.82/mm/slab.c linux-4.9.82-vs2.3.9.7/mm/slab.c
22957--- linux-4.9.82/mm/slab.c 2018-02-22 21:18:58.000000000 +0000
22958+++ linux-4.9.82-vs2.3.9.7/mm/slab.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 22959@@ -307,6 +307,8 @@ static void kmem_cache_node_init(struct
4bf69007
AM
22960 #define STATS_INC_FREEMISS(x) do { } while (0)
22961 #endif
22962
22963+#include "slab_vs.h"
2ba6f0dd 22964+
4bf69007
AM
22965 #if DEBUG
22966
22967 /*
cc23e853 22968@@ -3341,6 +3343,7 @@ slab_alloc_node(struct kmem_cache *cache
4bf69007
AM
22969 /* ___cache_alloc_node can fall back to other nodes */
22970 ptr = ____cache_alloc_node(cachep, flags, nodeid);
22971 out:
22972+ vx_slab_alloc(cachep, flags);
22973 local_irq_restore(save_flags);
22974 ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller);
cc23e853
AM
22975
22976@@ -3522,6 +3525,7 @@ void ___cache_free(struct kmem_cache *ca
4bf69007
AM
22977 check_irq_off();
22978 kmemleak_free_recursive(objp, cachep->flags);
22979 objp = cache_free_debugcheck(cachep, objp, caller);
22980+ vx_slab_free(cachep);
22981
22982 kmemcheck_slab_free(cachep, objp, cachep->object_size);
22983
cef7ea10
AM
22984diff -NurpP --minimal linux-4.9.82/mm/slab_vs.h linux-4.9.82-vs2.3.9.7/mm/slab_vs.h
22985--- linux-4.9.82/mm/slab_vs.h 1970-01-01 00:00:00.000000000 +0000
22986+++ linux-4.9.82-vs2.3.9.7/mm/slab_vs.h 2018-01-10 02:50:49.000000000 +0000
4bf69007 22987@@ -0,0 +1,29 @@
2ba6f0dd 22988+
4bf69007 22989+#include <linux/vserver/context.h>
2ba6f0dd 22990+
4bf69007 22991+#include <linux/vs_context.h>
2ba6f0dd 22992+
4bf69007
AM
22993+static inline
22994+void vx_slab_alloc(struct kmem_cache *cachep, gfp_t flags)
22995+{
22996+ int what = gfp_zone(cachep->allocflags);
22997+ struct vx_info *vxi = current_vx_info();
2ba6f0dd 22998+
4bf69007
AM
22999+ if (!vxi)
23000+ return;
2ba6f0dd 23001+
4bf69007
AM
23002+ atomic_add(cachep->size, &vxi->cacct.slab[what]);
23003+}
2ba6f0dd 23004+
4bf69007
AM
23005+static inline
23006+void vx_slab_free(struct kmem_cache *cachep)
23007+{
23008+ int what = gfp_zone(cachep->allocflags);
23009+ struct vx_info *vxi = current_vx_info();
2ba6f0dd 23010+
4bf69007
AM
23011+ if (!vxi)
23012+ return;
2ba6f0dd 23013+
4bf69007
AM
23014+ atomic_sub(cachep->size, &vxi->cacct.slab[what]);
23015+}
2ba6f0dd 23016+
cef7ea10
AM
23017diff -NurpP --minimal linux-4.9.82/mm/swapfile.c linux-4.9.82-vs2.3.9.7/mm/swapfile.c
23018--- linux-4.9.82/mm/swapfile.c 2018-02-22 21:18:58.000000000 +0000
23019+++ linux-4.9.82-vs2.3.9.7/mm/swapfile.c 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
23020@@ -39,6 +39,7 @@
23021 #include <asm/tlbflush.h>
23022 #include <linux/swapops.h>
cc23e853 23023 #include <linux/swap_cgroup.h>
4bf69007
AM
23024+#include <linux/vs_base.h>
23025
23026 static bool swap_count_continued(struct swap_info_struct *, pgoff_t,
23027 unsigned char);
cc23e853 23028@@ -2083,6 +2084,16 @@ static int swap_show(struct seq_file *sw
4bf69007
AM
23029
23030 if (si == SEQ_START_TOKEN) {
23031 seq_puts(swap,"Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
23032+ if (vx_flags(VXF_VIRT_MEM, 0)) {
cc23e853 23033+ struct sysinfo si = { 0 };
2ba6f0dd 23034+
4bf69007
AM
23035+ vx_vsi_swapinfo(&si);
23036+ if (si.totalswap < (1 << 10))
23037+ return 0;
23038+ seq_printf(swap, "%s\t\t\t\t\t%s\t%lu\t%lu\t%d\n",
23039+ "hdv0", "partition", si.totalswap >> 10,
23040+ (si.totalswap - si.freeswap) >> 10, -1);
23041+ }
23042 return 0;
23043 }
23044
cc23e853 23045@@ -2612,6 +2623,8 @@ void si_swapinfo(struct sysinfo *val)
b00e13aa 23046 val->freeswap = atomic_long_read(&nr_swap_pages) + nr_to_be_unused;
4bf69007
AM
23047 val->totalswap = total_swap_pages + nr_to_be_unused;
23048 spin_unlock(&swap_lock);
23049+ if (vx_flags(VXF_VIRT_MEM, 0))
23050+ vx_vsi_swapinfo(val);
23051 }
23052
23053 /*
cef7ea10
AM
23054diff -NurpP --minimal linux-4.9.82/net/bridge/br_multicast.c linux-4.9.82-vs2.3.9.7/net/bridge/br_multicast.c
23055--- linux-4.9.82/net/bridge/br_multicast.c 2016-12-11 19:17:54.000000000 +0000
23056+++ linux-4.9.82-vs2.3.9.7/net/bridge/br_multicast.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 23057@@ -465,7 +465,7 @@ static struct sk_buff *br_ip6_multicast_
4bf69007
AM
23058 ip6h->hop_limit = 1;
23059 ipv6_addr_set(&ip6h->daddr, htonl(0xff020000), 0, 0, htonl(1));
23060 if (ipv6_dev_get_saddr(dev_net(br->dev), br->dev, &ip6h->daddr, 0,
23061- &ip6h->saddr)) {
23062+ &ip6h->saddr, NULL)) {
23063 kfree_skb(skb);
cc23e853 23064 br->has_ipv6_addr = 0;
4bf69007 23065 return NULL;
cef7ea10
AM
23066diff -NurpP --minimal linux-4.9.82/net/core/dev.c linux-4.9.82-vs2.3.9.7/net/core/dev.c
23067--- linux-4.9.82/net/core/dev.c 2018-02-22 21:19:01.000000000 +0000
23068+++ linux-4.9.82-vs2.3.9.7/net/core/dev.c 2018-02-10 15:15:43.000000000 +0000
cc23e853 23069@@ -126,6 +126,7 @@
4bf69007
AM
23070 #include <linux/in.h>
23071 #include <linux/jhash.h>
23072 #include <linux/random.h>
23073+#include <linux/vs_inet.h>
23074 #include <trace/events/napi.h>
23075 #include <trace/events/net.h>
23076 #include <trace/events/skb.h>
cc23e853 23077@@ -730,7 +731,8 @@ struct net_device *__dev_get_by_name(str
4bf69007
AM
23078 struct hlist_head *head = dev_name_hash(net, name);
23079
b00e13aa 23080 hlist_for_each_entry(dev, head, name_hlist)
4bf69007
AM
23081- if (!strncmp(dev->name, name, IFNAMSIZ))
23082+ if (!strncmp(dev->name, name, IFNAMSIZ) &&
23083+ nx_dev_visible(current_nx_info(), dev))
23084 return dev;
23085
23086 return NULL;
cc23e853 23087@@ -755,7 +757,8 @@ struct net_device *dev_get_by_name_rcu(s
4bf69007
AM
23088 struct hlist_head *head = dev_name_hash(net, name);
23089
b00e13aa 23090 hlist_for_each_entry_rcu(dev, head, name_hlist)
4bf69007
AM
23091- if (!strncmp(dev->name, name, IFNAMSIZ))
23092+ if (!strncmp(dev->name, name, IFNAMSIZ) &&
23093+ nx_dev_visible(current_nx_info(), dev))
23094 return dev;
23095
23096 return NULL;
cc23e853 23097@@ -805,7 +808,8 @@ struct net_device *__dev_get_by_index(st
4bf69007
AM
23098 struct hlist_head *head = dev_index_hash(net, ifindex);
23099
b00e13aa 23100 hlist_for_each_entry(dev, head, index_hlist)
4bf69007
AM
23101- if (dev->ifindex == ifindex)
23102+ if ((dev->ifindex == ifindex) &&
23103+ nx_dev_visible(current_nx_info(), dev))
23104 return dev;
23105
23106 return NULL;
cc23e853 23107@@ -823,7 +827,7 @@ EXPORT_SYMBOL(__dev_get_by_index);
4bf69007
AM
23108 * about locking. The caller must hold RCU lock.
23109 */
23110
23111-struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex)
23112+struct net_device *dev_get_by_index_real_rcu(struct net *net, int ifindex)
23113 {
4bf69007 23114 struct net_device *dev;
b00e13aa 23115 struct hlist_head *head = dev_index_hash(net, ifindex);
cc23e853 23116@@ -834,6 +838,16 @@ struct net_device *dev_get_by_index_rcu(
4bf69007
AM
23117
23118 return NULL;
23119 }
23120+EXPORT_SYMBOL(dev_get_by_index_real_rcu);
2ba6f0dd 23121+
4bf69007
AM
23122+struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex)
23123+{
23124+ struct net_device *dev = dev_get_by_index_real_rcu(net, ifindex);
2ba6f0dd 23125+
4bf69007
AM
23126+ if (nx_dev_visible(current_nx_info(), dev))
23127+ return dev;
23128+ return NULL;
23129+}
23130 EXPORT_SYMBOL(dev_get_by_index_rcu);
23131
23132
cc23e853 23133@@ -916,7 +930,8 @@ struct net_device *dev_getbyhwaddr_rcu(s
4bf69007
AM
23134
23135 for_each_netdev_rcu(net, dev)
23136 if (dev->type == type &&
23137- !memcmp(dev->dev_addr, ha, dev->addr_len))
23138+ !memcmp(dev->dev_addr, ha, dev->addr_len) &&
23139+ nx_dev_visible(current_nx_info(), dev))
23140 return dev;
23141
23142 return NULL;
cc23e853 23143@@ -928,9 +943,11 @@ struct net_device *__dev_getfirstbyhwtyp
4bf69007
AM
23144 struct net_device *dev;
23145
23146 ASSERT_RTNL();
23147- for_each_netdev(net, dev)
23148- if (dev->type == type)
23149+ for_each_netdev(net, dev) {
23150+ if ((dev->type == type) &&
23151+ nx_dev_visible(current_nx_info(), dev))
23152 return dev;
23153+ }
23154
23155 return NULL;
23156 }
cc23e853 23157@@ -942,7 +959,8 @@ struct net_device *dev_getfirstbyhwtype(
b00e13aa
AM
23158
23159 rcu_read_lock();
23160 for_each_netdev_rcu(net, dev)
23161- if (dev->type == type) {
23162+ if ((dev->type == type) &&
23163+ nx_dev_visible(current_nx_info(), dev)) {
23164 dev_hold(dev);
23165 ret = dev;
23166 break;
cc23e853 23167@@ -972,7 +990,8 @@ struct net_device *__dev_get_by_flags(st
b00e13aa
AM
23168
23169 ret = NULL;
bb20add7 23170 for_each_netdev(net, dev) {
b00e13aa
AM
23171- if (((dev->flags ^ if_flags) & mask) == 0) {
23172+ if ((((dev->flags ^ if_flags) & mask) == 0) &&
23173+ nx_dev_visible(current_nx_info(), dev)) {
23174 ret = dev;
23175 break;
23176 }
cc23e853 23177@@ -1050,6 +1069,8 @@ static int __dev_alloc_name(struct net *
4bf69007
AM
23178 continue;
23179 if (i < 0 || i >= max_netdevices)
23180 continue;
23181+ if (!nx_dev_visible(current_nx_info(), d))
23182+ continue;
23183
23184 /* avoid cases where sscanf is not exact inverse of printf */
23185 snprintf(buf, IFNAMSIZ, name, i);
cef7ea10
AM
23186diff -NurpP --minimal linux-4.9.82/net/core/net-procfs.c linux-4.9.82-vs2.3.9.7/net/core/net-procfs.c
23187--- linux-4.9.82/net/core/net-procfs.c 2016-12-11 19:17:54.000000000 +0000
23188+++ linux-4.9.82-vs2.3.9.7/net/core/net-procfs.c 2018-01-10 02:50:49.000000000 +0000
8ce283e1
AM
23189@@ -1,6 +1,7 @@
23190 #include <linux/netdevice.h>
23191 #include <linux/proc_fs.h>
23192 #include <linux/seq_file.h>
23193+#include <linux/vs_inet.h>
23194 #include <net/wext.h>
23195
23196 #define BUCKET_SPACE (32 - NETDEV_HASHBITS - 1)
23197@@ -77,8 +78,13 @@ static void dev_seq_stop(struct seq_file
23198 static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
23199 {
23200 struct rtnl_link_stats64 temp;
23201- const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp);
23202+ const struct rtnl_link_stats64 *stats;
23203+
23204+ /* device visible inside network context? */
23205+ if (!nx_dev_visible(current_nx_info(), dev))
23206+ return;
23207
23208+ stats = dev_get_stats(dev, &temp);
23209 seq_printf(seq, "%6s: %7llu %7llu %4llu %4llu %4llu %5llu %10llu %9llu "
23210 "%8llu %7llu %4llu %4llu %4llu %5llu %7llu %10llu\n",
23211 dev->name, stats->rx_bytes, stats->rx_packets,
cef7ea10
AM
23212diff -NurpP --minimal linux-4.9.82/net/core/rtnetlink.c linux-4.9.82-vs2.3.9.7/net/core/rtnetlink.c
23213--- linux-4.9.82/net/core/rtnetlink.c 2018-02-22 21:19:01.000000000 +0000
23214+++ linux-4.9.82-vs2.3.9.7/net/core/rtnetlink.c 2018-01-10 02:50:49.000000000 +0000
cc23e853
AM
23215@@ -1615,6 +1615,8 @@ static int rtnl_dump_ifinfo(struct sk_bu
23216 goto cont;
4bf69007
AM
23217 if (idx < s_idx)
23218 goto cont;
23219+ if (!nx_dev_visible(skb->sk->sk_nx_info, dev))
23220+ continue;
7ed51edd
JR
23221 err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
23222 NETLINK_CB(cb->skb).portid,
23223 cb->nlh->nlmsg_seq, 0,
cc23e853
AM
23224@@ -2811,6 +2813,9 @@ void rtmsg_ifinfo(int type, struct net_d
23225 {
23226 struct sk_buff *skb;
4bf69007
AM
23227
23228+ if (!nx_dev_visible(current_nx_info(), dev))
23229+ return;
2ba6f0dd 23230+
cc23e853
AM
23231 if (dev->reg_state != NETREG_REGISTERED)
23232 return;
23233
cef7ea10
AM
23234diff -NurpP --minimal linux-4.9.82/net/core/sock.c linux-4.9.82-vs2.3.9.7/net/core/sock.c
23235--- linux-4.9.82/net/core/sock.c 2018-02-22 21:19:01.000000000 +0000
23236+++ linux-4.9.82-vs2.3.9.7/net/core/sock.c 2018-01-13 00:48:01.000000000 +0000
cc23e853 23237@@ -135,6 +135,10 @@
4bf69007
AM
23238
23239 #include <linux/filter.h>
cc23e853 23240 #include <net/sock_reuseport.h>
4bf69007
AM
23241+#include <linux/vs_socket.h>
23242+#include <linux/vs_limit.h>
23243+#include <linux/vs_context.h>
23244+#include <linux/vs_network.h>
23245
23246 #include <trace/events/sock.h>
23247
cc23e853 23248@@ -1339,6 +1343,8 @@ static struct sock *sk_prot_alloc(struct
4bf69007
AM
23249 goto out_free_sec;
23250 sk_tx_queue_clear(sk);
23251 }
23252+ sock_vx_init(sk);
23253+ sock_nx_init(sk);
23254
23255 return sk;
23256
cc23e853 23257@@ -1444,6 +1450,11 @@ static void __sk_destruct(struct rcu_hea
4bf69007 23258 put_pid(sk->sk_peer_pid);
cc23e853
AM
23259 if (likely(sk->sk_net_refcnt))
23260 put_net(sock_net(sk));
4bf69007
AM
23261+ vx_sock_dec(sk);
23262+ clr_vx_info(&sk->sk_vx_info);
23263+ sk->sk_xid = -1;
23264+ clr_nx_info(&sk->sk_nx_info);
23265+ sk->sk_nid = -1;
23266 sk_prot_free(sk->sk_prot_creator, sk);
23267 }
23268
cc23e853 23269@@ -1498,6 +1509,8 @@ struct sock *sk_clone_lock(const struct
4bf69007 23270 /* SANITY */
cc23e853
AM
23271 if (likely(newsk->sk_net_refcnt))
23272 get_net(sock_net(newsk));
4bf69007
AM
23273+ sock_vx_init(newsk);
23274+ sock_nx_init(newsk);
23275 sk_node_init(&newsk->sk_node);
23276 sock_lock_init(newsk);
23277 bh_lock_sock(newsk);
cc23e853 23278@@ -1568,6 +1581,12 @@ struct sock *sk_clone_lock(const struct
4bf69007
AM
23279 smp_wmb();
23280 atomic_set(&newsk->sk_refcnt, 2);
23281
23282+ set_vx_info(&newsk->sk_vx_info, sk->sk_vx_info);
23283+ newsk->sk_xid = sk->sk_xid;
23284+ vx_sock_inc(newsk);
23285+ set_nx_info(&newsk->sk_nx_info, sk->sk_nx_info);
23286+ newsk->sk_nid = sk->sk_nid;
2ba6f0dd 23287+
4bf69007
AM
23288 /*
23289 * Increment the counter in the same struct proto as the master
23290 * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that
cc23e853 23291@@ -2468,6 +2487,12 @@ void sock_init_data(struct socket *sock,
4bf69007
AM
23292
23293 sk->sk_stamp = ktime_set(-1L, 0);
23294
23295+ set_vx_info(&sk->sk_vx_info, current_vx_info());
23296+ sk->sk_xid = vx_current_xid();
23297+ vx_sock_inc(sk);
23298+ set_nx_info(&sk->sk_nx_info, current_nx_info());
23299+ sk->sk_nid = nx_current_nid();
2ba6f0dd 23300+
c2e5f7c8
JR
23301 #ifdef CONFIG_NET_RX_BUSY_POLL
23302 sk->sk_napi_id = 0;
23303 sk->sk_ll_usec = sysctl_net_busy_read;
cef7ea10
AM
23304diff -NurpP --minimal linux-4.9.82/net/ipv4/af_inet.c linux-4.9.82-vs2.3.9.7/net/ipv4/af_inet.c
23305--- linux-4.9.82/net/ipv4/af_inet.c 2018-02-22 21:19:01.000000000 +0000
23306+++ linux-4.9.82-vs2.3.9.7/net/ipv4/af_inet.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 23307@@ -303,10 +303,15 @@ lookup_protocol:
4bf69007
AM
23308 }
23309
23310 err = -EPERM;
23311+ if ((protocol == IPPROTO_ICMP) &&
23312+ nx_capable(CAP_NET_RAW, NXC_RAW_ICMP))
23313+ goto override;
cc23e853 23314+
b00e13aa
AM
23315 if (sock->type == SOCK_RAW && !kern &&
23316 !ns_capable(net->user_ns, CAP_NET_RAW))
4bf69007 23317 goto out_rcu_unlock;
cc23e853 23318
a4a22af8
AM
23319+override:
23320 sock->ops = answer->ops;
23321 answer_prot = answer->prot;
bb20add7 23322 answer_flags = answer->flags;
cc23e853 23323@@ -424,6 +429,7 @@ int inet_bind(struct socket *sock, struc
4bf69007
AM
23324 struct sock *sk = sock->sk;
23325 struct inet_sock *inet = inet_sk(sk);
b00e13aa 23326 struct net *net = sock_net(sk);
cc23e853 23327+ struct nx_v4_sock_addr nsa;
4bf69007
AM
23328 unsigned short snum;
23329 int chk_addr_ret;
cc23e853
AM
23330 u32 tb_id = RT_TABLE_LOCAL;
23331@@ -449,7 +455,11 @@ int inet_bind(struct socket *sock, struc
4bf69007
AM
23332 }
23333
cc23e853
AM
23334 tb_id = l3mdev_fib_table_by_index(net, sk->sk_bound_dev_if) ? : tb_id;
23335- chk_addr_ret = inet_addr_type_table(net, addr->sin_addr.s_addr, tb_id);
4bf69007
AM
23336+ err = v4_map_sock_addr(inet, addr, &nsa);
23337+ if (err)
23338+ goto out;
2ba6f0dd 23339+
cc23e853 23340+ chk_addr_ret = inet_addr_type_table(net, nsa.saddr, tb_id);
4bf69007
AM
23341
23342 /* Not specified by any standard per-se, however it breaks too
23343 * many applications when removed. It is unfortunate since
cc23e853 23344@@ -461,7 +471,7 @@ int inet_bind(struct socket *sock, struc
4bf69007 23345 err = -EADDRNOTAVAIL;
bb20add7 23346 if (!net->ipv4.sysctl_ip_nonlocal_bind &&
4bf69007
AM
23347 !(inet->freebind || inet->transparent) &&
23348- addr->sin_addr.s_addr != htonl(INADDR_ANY) &&
23349+ nsa.saddr != htonl(INADDR_ANY) &&
23350 chk_addr_ret != RTN_LOCAL &&
23351 chk_addr_ret != RTN_MULTICAST &&
23352 chk_addr_ret != RTN_BROADCAST)
cc23e853 23353@@ -487,7 +497,7 @@ int inet_bind(struct socket *sock, struc
4bf69007
AM
23354 if (sk->sk_state != TCP_CLOSE || inet->inet_num)
23355 goto out_release_sock;
23356
23357- inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
23358+ v4_set_sock_addr(inet, &nsa);
23359 if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
23360 inet->inet_saddr = 0; /* Use device */
23361
cc23e853 23362@@ -706,11 +716,13 @@ int inet_getname(struct socket *sock, st
4bf69007
AM
23363 peer == 1))
23364 return -ENOTCONN;
23365 sin->sin_port = inet->inet_dport;
23366- sin->sin_addr.s_addr = inet->inet_daddr;
23367+ sin->sin_addr.s_addr =
23368+ nx_map_sock_lback(sk->sk_nx_info, inet->inet_daddr);
23369 } else {
23370 __be32 addr = inet->inet_rcv_saddr;
23371 if (!addr)
23372 addr = inet->inet_saddr;
23373+ addr = nx_map_sock_lback(sk->sk_nx_info, addr);
23374 sin->sin_port = inet->inet_sport;
23375 sin->sin_addr.s_addr = addr;
23376 }
cc23e853
AM
23377@@ -894,6 +906,7 @@ static int inet_compat_ioctl(struct sock
23378 return err;
23379 }
23380 #endif
23381+#include <linux/vs_limit.h>
23382
23383 const struct proto_ops inet_stream_ops = {
23384 .family = PF_INET,
cef7ea10
AM
23385diff -NurpP --minimal linux-4.9.82/net/ipv4/arp.c linux-4.9.82-vs2.3.9.7/net/ipv4/arp.c
23386--- linux-4.9.82/net/ipv4/arp.c 2018-02-22 21:19:01.000000000 +0000
23387+++ linux-4.9.82-vs2.3.9.7/net/ipv4/arp.c 2018-02-10 15:15:43.000000000 +0000
5ba7a31c 23388@@ -1308,6 +1308,7 @@ static void arp_format_neigh_entry(struc
4bf69007
AM
23389 struct net_device *dev = n->dev;
23390 int hatype = dev->type;
23391
23392+ /* FIXME: check for network context */
23393 read_lock(&n->lock);
23394 /* Convert hardware address to XX:XX:XX:XX ... form. */
23395 #if IS_ENABLED(CONFIG_AX25)
5ba7a31c 23396@@ -1339,6 +1340,7 @@ static void arp_format_pneigh_entry(stru
4bf69007
AM
23397 int hatype = dev ? dev->type : 0;
23398 char tbuf[16];
23399
23400+ /* FIXME: check for network context */
23401 sprintf(tbuf, "%pI4", n->key);
23402 seq_printf(seq, "%-16s 0x%-10x0x%-10x%s * %s\n",
23403 tbuf, hatype, ATF_PUBL | ATF_PERM, "00:00:00:00:00:00",
cef7ea10
AM
23404diff -NurpP --minimal linux-4.9.82/net/ipv4/devinet.c linux-4.9.82-vs2.3.9.7/net/ipv4/devinet.c
23405--- linux-4.9.82/net/ipv4/devinet.c 2018-02-22 21:19:01.000000000 +0000
23406+++ linux-4.9.82-vs2.3.9.7/net/ipv4/devinet.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 23407@@ -538,6 +538,7 @@ struct in_device *inetdev_by_index(struc
4bf69007
AM
23408 }
23409 EXPORT_SYMBOL(inetdev_by_index);
23410
2ba6f0dd 23411+
4bf69007
AM
23412 /* Called only from RTNL semaphored context. No locks. */
23413
23414 struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
cc23e853 23415@@ -992,6 +993,8 @@ int devinet_ioctl(struct net *net, unsig
4bf69007
AM
23416
23417 in_dev = __in_dev_get_rtnl(dev);
23418 if (in_dev) {
23419+ struct nx_info *nxi = current_nx_info();
2ba6f0dd 23420+
4bf69007
AM
23421 if (tryaddrmatch) {
23422 /* Matthias Andree */
23423 /* compare label and address (4.4BSD style) */
cc23e853 23424@@ -1000,6 +1003,8 @@ int devinet_ioctl(struct net *net, unsig
4bf69007
AM
23425 This is checked above. */
23426 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
23427 ifap = &ifa->ifa_next) {
23428+ if (!nx_v4_ifa_visible(nxi, ifa))
23429+ continue;
23430 if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
23431 sin_orig.sin_addr.s_addr ==
23432 ifa->ifa_local) {
cc23e853 23433@@ -1012,9 +1017,12 @@ int devinet_ioctl(struct net *net, unsig
4bf69007
AM
23434 comparing just the label */
23435 if (!ifa) {
23436 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
23437- ifap = &ifa->ifa_next)
23438+ ifap = &ifa->ifa_next) {
23439+ if (!nx_v4_ifa_visible(nxi, ifa))
23440+ continue;
23441 if (!strcmp(ifr.ifr_name, ifa->ifa_label))
23442 break;
23443+ }
23444 }
23445 }
23446
cc23e853 23447@@ -1168,6 +1176,8 @@ static int inet_gifconf(struct net_devic
4bf69007
AM
23448 goto out;
23449
23450 for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
23451+ if (!nx_v4_ifa_visible(current_nx_info(), ifa))
23452+ continue;
23453 if (!buf) {
23454 done += sizeof(ifr);
23455 continue;
cc23e853 23456@@ -1595,6 +1605,7 @@ static int inet_dump_ifaddr(struct sk_bu
4bf69007
AM
23457 struct net_device *dev;
23458 struct in_device *in_dev;
23459 struct in_ifaddr *ifa;
23460+ struct sock *sk = skb->sk;
23461 struct hlist_head *head;
4bf69007 23462
b00e13aa 23463 s_h = cb->args[0];
cc23e853 23464@@ -1618,6 +1629,8 @@ static int inet_dump_ifaddr(struct sk_bu
4bf69007
AM
23465
23466 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
23467 ifa = ifa->ifa_next, ip_idx++) {
23468+ if (sk && !nx_v4_ifa_visible(sk->sk_nx_info, ifa))
23469+ continue;
23470 if (ip_idx < s_ip_idx)
23471 continue;
23472 if (inet_fill_ifaddr(skb, ifa,
cef7ea10
AM
23473diff -NurpP --minimal linux-4.9.82/net/ipv4/fib_trie.c linux-4.9.82-vs2.3.9.7/net/ipv4/fib_trie.c
23474--- linux-4.9.82/net/ipv4/fib_trie.c 2018-02-22 21:19:01.000000000 +0000
23475+++ linux-4.9.82-vs2.3.9.7/net/ipv4/fib_trie.c 2018-01-10 02:50:49.000000000 +0000
cc23e853
AM
23476@@ -2617,6 +2617,7 @@ static int fib_route_seq_show(struct seq
23477
23478 seq_setwidth(seq, 127);
23479
23480+ /* FIXME: check for network context? */
23481 if (fi)
23482 seq_printf(seq,
23483 "%s\t%08X\t%08X\t%04X\t%d\t%u\t"
cef7ea10
AM
23484diff -NurpP --minimal linux-4.9.82/net/ipv4/inet_connection_sock.c linux-4.9.82-vs2.3.9.7/net/ipv4/inet_connection_sock.c
23485--- linux-4.9.82/net/ipv4/inet_connection_sock.c 2018-02-22 21:19:01.000000000 +0000
23486+++ linux-4.9.82-vs2.3.9.7/net/ipv4/inet_connection_sock.c 2018-01-13 20:20:30.000000000 +0000
cc23e853
AM
23487@@ -16,6 +16,7 @@
23488 #include <linux/module.h>
23489 #include <linux/jhash.h>
23490
23491+#include <net/addrconf.h>
23492 #include <net/inet_connection_sock.h>
23493 #include <net/inet_hashtables.h>
23494 #include <net/inet_timewait_sock.h>
23495@@ -44,6 +45,7 @@ void inet_get_local_port_range(struct ne
4bf69007
AM
23496 }
23497 EXPORT_SYMBOL(inet_get_local_port_range);
23498
2ba6f0dd 23499+
4bf69007
AM
23500 int inet_csk_bind_conflict(const struct sock *sk,
23501 const struct inet_bind_bucket *tb, bool relax)
23502 {
cc23e853
AM
23503@@ -72,15 +74,13 @@ int inet_csk_bind_conflict(const struct
23504 (sk2->sk_state != TCP_TIME_WAIT &&
b00e13aa 23505 !uid_eq(uid, sock_i_uid(sk2))))) {
c2e5f7c8
JR
23506
23507- if (!sk2->sk_rcv_saddr || !sk->sk_rcv_saddr ||
23508- sk2->sk_rcv_saddr == sk->sk_rcv_saddr)
cc23e853 23509+ if (ipv4_rcv_saddr_equal(sk, sk2, true))
4bf69007
AM
23510 break;
23511 }
23512 if (!relax && reuse && sk2->sk_reuse &&
b00e13aa 23513 sk2->sk_state != TCP_LISTEN) {
c2e5f7c8
JR
23514
23515- if (!sk2->sk_rcv_saddr || !sk->sk_rcv_saddr ||
23516- sk2->sk_rcv_saddr == sk->sk_rcv_saddr)
cc23e853 23517+ if (ipv4_rcv_saddr_equal(sk, sk2, true))
b00e13aa
AM
23518 break;
23519 }
23520 }
cef7ea10
AM
23521diff -NurpP --minimal linux-4.9.82/net/ipv4/inet_diag.c linux-4.9.82-vs2.3.9.7/net/ipv4/inet_diag.c
23522--- linux-4.9.82/net/ipv4/inet_diag.c 2016-12-11 19:17:54.000000000 +0000
23523+++ linux-4.9.82-vs2.3.9.7/net/ipv4/inet_diag.c 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
23524@@ -31,6 +31,8 @@
23525
23526 #include <linux/inet.h>
23527 #include <linux/stddef.h>
23528+#include <linux/vs_network.h>
23529+#include <linux/vs_inet.h>
23530
23531 #include <linux/inet_diag.h>
23532 #include <linux/sock_diag.h>
cc23e853 23533@@ -879,6 +881,8 @@ void inet_diag_dump_icsk(struct inet_has
4bf69007
AM
23534 if (!net_eq(sock_net(sk), net))
23535 continue;
23536
23537+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23538+ continue;
23539 if (num < s_num) {
23540 num++;
23541 continue;
cc23e853 23542@@ -941,6 +945,8 @@ skip_listen_ht:
4bf69007
AM
23543
23544 if (!net_eq(sock_net(sk), net))
23545 continue;
23546+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23547+ continue;
23548 if (num < s_num)
23549 goto next_normal;
c2e5f7c8 23550 state = (sk->sk_state == TCP_TIME_WAIT) ?
cef7ea10
AM
23551diff -NurpP --minimal linux-4.9.82/net/ipv4/inet_hashtables.c linux-4.9.82-vs2.3.9.7/net/ipv4/inet_hashtables.c
23552--- linux-4.9.82/net/ipv4/inet_hashtables.c 2018-02-22 21:19:01.000000000 +0000
23553+++ linux-4.9.82-vs2.3.9.7/net/ipv4/inet_hashtables.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 23554@@ -24,6 +24,7 @@
4bf69007
AM
23555 #include <net/inet_connection_sock.h>
23556 #include <net/inet_hashtables.h>
23557 #include <net/secure_seq.h>
23558+#include <net/route.h>
23559 #include <net/ip.h>
cc23e853
AM
23560 #include <net/tcp.h>
23561 #include <net/sock_reuseport.h>
23562@@ -186,6 +187,11 @@ static inline int compute_score(struct s
4bf69007
AM
23563 if (rcv_saddr != daddr)
23564 return -1;
b00e13aa 23565 score += 4;
4bf69007
AM
23566+ } else {
23567+ /* block non nx_info ips */
23568+ if (!v4_addr_in_nx_info(sk->sk_nx_info,
23569+ daddr, NXA_MASK_BIND))
23570+ return -1;
23571 }
cc23e853 23572 if (sk->sk_bound_dev_if || exact_dif) {
4bf69007 23573 if (sk->sk_bound_dev_if != dif)
cc23e853
AM
23574@@ -300,6 +306,7 @@ begin:
23575 goto found;
4bf69007
AM
23576 }
23577 }
2ba6f0dd 23578+
4bf69007
AM
23579 /*
23580 * if the nulls value we got at the end of this lookup is
23581 * not the expected one, we must restart lookup.
cef7ea10
AM
23582diff -NurpP --minimal linux-4.9.82/net/ipv4/netfilter.c linux-4.9.82-vs2.3.9.7/net/ipv4/netfilter.c
23583--- linux-4.9.82/net/ipv4/netfilter.c 2018-02-22 21:19:02.000000000 +0000
23584+++ linux-4.9.82-vs2.3.9.7/net/ipv4/netfilter.c 2018-01-10 02:50:49.000000000 +0000
09be7631 23585@@ -11,7 +11,7 @@
4bf69007
AM
23586 #include <linux/skbuff.h>
23587 #include <linux/gfp.h>
23588 #include <linux/export.h>
23589-#include <net/route.h>
23590+// #include <net/route.h>
23591 #include <net/xfrm.h>
23592 #include <net/ip.h>
23593 #include <net/netfilter/nf_queue.h>
cef7ea10
AM
23594diff -NurpP --minimal linux-4.9.82/net/ipv4/raw.c linux-4.9.82-vs2.3.9.7/net/ipv4/raw.c
23595--- linux-4.9.82/net/ipv4/raw.c 2018-02-22 21:19:02.000000000 +0000
23596+++ linux-4.9.82-vs2.3.9.7/net/ipv4/raw.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 23597@@ -128,7 +128,7 @@ static struct sock *__raw_v4_lookup(stru
4bf69007
AM
23598
23599 if (net_eq(sock_net(sk), net) && inet->inet_num == num &&
23600 !(inet->inet_daddr && inet->inet_daddr != raddr) &&
23601- !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
23602+ v4_sock_addr_match(sk->sk_nx_info, inet, laddr) &&
23603 !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
23604 goto found; /* gotcha */
23605 }
cc23e853
AM
23606@@ -418,6 +418,12 @@ static int raw_send_hdrinc(struct sock *
23607 skb_transport_header(skb))->type);
23608 }
4bf69007
AM
23609
23610+ err = -EPERM;
23611+ if (!nx_check(0, VS_ADMIN) && !capable(CAP_NET_RAW) &&
23612+ sk->sk_nx_info &&
23613+ !v4_addr_in_nx_info(sk->sk_nx_info, iph->saddr, NXA_MASK_BIND))
23614+ goto error_free;
2ba6f0dd 23615+
cc23e853
AM
23616 err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT,
23617 net, sk, skb, NULL, rt->dst.dev,
23618 dst_output);
23619@@ -623,6 +629,16 @@ static int raw_sendmsg(struct sock *sk,
4bf69007
AM
23620 goto done;
23621 }
23622
23623+ if (sk->sk_nx_info) {
23624+ rt = ip_v4_find_src(sock_net(sk), sk->sk_nx_info, &fl4);
23625+ if (IS_ERR(rt)) {
23626+ err = PTR_ERR(rt);
23627+ rt = NULL;
23628+ goto done;
23629+ }
23630+ ip_rt_put(rt);
23631+ }
2ba6f0dd 23632+
4bf69007 23633 security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
cc23e853 23634 rt = ip_route_output_flow(net, &fl4, sk);
4bf69007 23635 if (IS_ERR(rt)) {
cc23e853 23636@@ -701,17 +717,19 @@ static int raw_bind(struct sock *sk, str
4bf69007
AM
23637 {
23638 struct inet_sock *inet = inet_sk(sk);
23639 struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
23640+ struct nx_v4_sock_addr nsa = { 0 };
23641 int ret = -EINVAL;
23642 int chk_addr_ret;
23643
23644 if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
23645 goto out;
23646- chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr);
23647+ v4_map_sock_addr(inet, addr, &nsa);
23648+ chk_addr_ret = inet_addr_type(sock_net(sk), nsa.saddr);
23649 ret = -EADDRNOTAVAIL;
23650- if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
23651+ if (nsa.saddr && chk_addr_ret != RTN_LOCAL &&
23652 chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
23653 goto out;
23654- inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
23655+ v4_set_sock_addr(inet, &nsa);
23656 if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
23657 inet->inet_saddr = 0; /* Use device */
23658 sk_dst_reset(sk);
cc23e853 23659@@ -760,7 +778,8 @@ static int raw_recvmsg(struct sock *sk,
4bf69007
AM
23660 /* Copy the address. */
23661 if (sin) {
23662 sin->sin_family = AF_INET;
23663- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
23664+ sin->sin_addr.s_addr =
23665+ nx_map_sock_lback(sk->sk_nx_info, ip_hdr(skb)->saddr);
23666 sin->sin_port = 0;
23667 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
c2e5f7c8 23668 *addr_len = sizeof(*sin);
cc23e853 23669@@ -956,7 +975,8 @@ static struct sock *raw_get_first(struct
b00e13aa
AM
23670 for (state->bucket = 0; state->bucket < RAW_HTABLE_SIZE;
23671 ++state->bucket) {
23672 sk_for_each(sk, &state->h->ht[state->bucket])
4bf69007
AM
23673- if (sock_net(sk) == seq_file_net(seq))
23674+ if ((sock_net(sk) == seq_file_net(seq)) &&
b00e13aa 23675+ nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
4bf69007
AM
23676 goto found;
23677 }
23678 sk = NULL;
cc23e853 23679@@ -972,7 +992,8 @@ static struct sock *raw_get_next(struct
4bf69007
AM
23680 sk = sk_next(sk);
23681 try_again:
23682 ;
23683- } while (sk && sock_net(sk) != seq_file_net(seq));
23684+ } while (sk && ((sock_net(sk) != seq_file_net(seq)) ||
23685+ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
23686
23687 if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
23688 sk = sk_head(&state->h->ht[state->bucket]);
cef7ea10
AM
23689diff -NurpP --minimal linux-4.9.82/net/ipv4/route.c linux-4.9.82-vs2.3.9.7/net/ipv4/route.c
23690--- linux-4.9.82/net/ipv4/route.c 2018-02-22 21:19:02.000000000 +0000
23691+++ linux-4.9.82-vs2.3.9.7/net/ipv4/route.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 23692@@ -2238,7 +2238,7 @@ struct rtable *__ip_route_output_key_has
4bf69007
AM
23693
23694
23695 if (fl4->flowi4_oif) {
23696- dev_out = dev_get_by_index_rcu(net, fl4->flowi4_oif);
23697+ dev_out = dev_get_by_index_real_rcu(net, fl4->flowi4_oif);
23698 rth = ERR_PTR(-ENODEV);
cc23e853 23699 if (!dev_out)
4bf69007 23700 goto out;
cef7ea10
AM
23701diff -NurpP --minimal linux-4.9.82/net/ipv4/tcp.c linux-4.9.82-vs2.3.9.7/net/ipv4/tcp.c
23702--- linux-4.9.82/net/ipv4/tcp.c 2018-02-22 21:19:02.000000000 +0000
23703+++ linux-4.9.82-vs2.3.9.7/net/ipv4/tcp.c 2018-02-22 21:31:40.000000000 +0000
cc23e853
AM
23704@@ -269,6 +269,7 @@
23705 #include <linux/err.h>
4bf69007
AM
23706 #include <linux/time.h>
23707 #include <linux/slab.h>
23708+#include <linux/in.h>
23709
23710 #include <net/icmp.h>
23711 #include <net/inet_common.h>
cef7ea10
AM
23712diff -NurpP --minimal linux-4.9.82/net/ipv4/tcp_ipv4.c linux-4.9.82-vs2.3.9.7/net/ipv4/tcp_ipv4.c
23713--- linux-4.9.82/net/ipv4/tcp_ipv4.c 2018-02-22 21:19:02.000000000 +0000
23714+++ linux-4.9.82-vs2.3.9.7/net/ipv4/tcp_ipv4.c 2018-02-09 17:48:59.000000000 +0000
5ba7a31c
AM
23715@@ -1927,8 +1927,12 @@ get_head:
23716 sk = sk_next(sk);
23717 get_sk:
23718 sk_for_each_from(sk) {
23719+ vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)",
23720+ sk, sk->sk_nid, nx_current_nid());
23721 if (!net_eq(sock_net(sk), net))
23722 continue;
23723+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23724+ continue;
23725 if (sk->sk_family == st->family)
23726 return sk;
23727 }
23728@@ -1982,6 +1986,11 @@ static void *established_get_first(struc
4bf69007
AM
23729
23730 spin_lock_bh(lock);
23731 sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
23732+ vxdprintk(VXD_CBIT(net, 6),
23733+ "sk,egf: %p [#%d] (from %d)",
23734+ sk, sk->sk_nid, nx_current_nid());
23735+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23736+ continue;
23737 if (sk->sk_family != st->family ||
23738 !net_eq(sock_net(sk), net)) {
23739 continue;
5ba7a31c 23740@@ -2008,6 +2017,11 @@ static void *established_get_next(struct
c2e5f7c8 23741 sk = sk_nulls_next(sk);
4bf69007
AM
23742
23743 sk_nulls_for_each_from(sk, node) {
23744+ vxdprintk(VXD_CBIT(net, 6),
23745+ "sk,egn: %p [#%d] (from %d)",
23746+ sk, sk->sk_nid, nx_current_nid());
23747+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23748+ continue;
23749 if (sk->sk_family == st->family && net_eq(sock_net(sk), net))
c2e5f7c8 23750 return sk;
4bf69007 23751 }
5ba7a31c 23752@@ -2199,9 +2213,9 @@ static void get_openreq4(const struct re
4bf69007 23753 seq_printf(f, "%4d: %08X:%04X %08X:%04X"
c2e5f7c8 23754 " %02X %08X:%08X %02X:%08lX %08X %5u %8d %u %d %pK",
4bf69007 23755 i,
c2e5f7c8
JR
23756- ireq->ir_loc_addr,
23757+ nx_map_sock_lback(current_nx_info(), ireq->ir_loc_addr),
cc23e853 23758 ireq->ir_num,
c2e5f7c8
JR
23759- ireq->ir_rmt_addr,
23760+ nx_map_sock_lback(current_nx_info(), ireq->ir_rmt_addr),
23761 ntohs(ireq->ir_rmt_port),
4bf69007
AM
23762 TCP_SYN_RECV,
23763 0, 0, /* could print option size, but that is af dependent. */
5ba7a31c 23764@@ -2224,8 +2238,8 @@ static void get_tcp4_sock(struct sock *s
4bf69007
AM
23765 const struct inet_connection_sock *icsk = inet_csk(sk);
23766 const struct inet_sock *inet = inet_sk(sk);
cc23e853 23767 const struct fastopen_queue *fastopenq = &icsk->icsk_accept_queue.fastopenq;
4bf69007
AM
23768- __be32 dest = inet->inet_daddr;
23769- __be32 src = inet->inet_rcv_saddr;
23770+ __be32 dest = nx_map_sock_lback(current_nx_info(), inet->inet_daddr);
23771+ __be32 src = nx_map_sock_lback(current_nx_info(), inet->inet_rcv_saddr);
23772 __u16 destp = ntohs(inet->inet_dport);
23773 __u16 srcp = ntohs(inet->inet_sport);
23774 int rx_queue;
5ba7a31c 23775@@ -2284,8 +2298,8 @@ static void get_timewait4_sock(const str
cc23e853 23776 __be32 dest, src;
4bf69007 23777 __u16 destp, srcp;
4bf69007
AM
23778
23779- dest = tw->tw_daddr;
23780- src = tw->tw_rcv_saddr;
23781+ dest = nx_map_sock_lback(current_nx_info(), tw->tw_daddr);
23782+ src = nx_map_sock_lback(current_nx_info(), tw->tw_rcv_saddr);
23783 destp = ntohs(tw->tw_dport);
23784 srcp = ntohs(tw->tw_sport);
23785
cef7ea10
AM
23786diff -NurpP --minimal linux-4.9.82/net/ipv4/tcp_minisocks.c linux-4.9.82-vs2.3.9.7/net/ipv4/tcp_minisocks.c
23787--- linux-4.9.82/net/ipv4/tcp_minisocks.c 2018-02-22 21:19:02.000000000 +0000
23788+++ linux-4.9.82-vs2.3.9.7/net/ipv4/tcp_minisocks.c 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
23789@@ -23,6 +23,9 @@
23790 #include <linux/slab.h>
23791 #include <linux/sysctl.h>
23792 #include <linux/workqueue.h>
23793+#include <linux/vs_limit.h>
23794+#include <linux/vs_socket.h>
23795+#include <linux/vs_context.h>
23796 #include <net/tcp.h>
23797 #include <net/inet_common.h>
23798 #include <net/xfrm.h>
cc23e853 23799@@ -285,6 +288,11 @@ void tcp_time_wait(struct sock *sk, int
b00e13aa 23800 tcptw->tw_ts_offset = tp->tsoffset;
cc23e853 23801 tcptw->tw_last_oow_ack_time = 0;
4bf69007
AM
23802
23803+ tw->tw_xid = sk->sk_xid;
23804+ tw->tw_vx_info = NULL;
23805+ tw->tw_nid = sk->sk_nid;
23806+ tw->tw_nx_info = NULL;
2ba6f0dd 23807+
4bf69007
AM
23808 #if IS_ENABLED(CONFIG_IPV6)
23809 if (tw->tw_family == PF_INET6) {
23810 struct ipv6_pinfo *np = inet6_sk(sk);
cef7ea10
AM
23811diff -NurpP --minimal linux-4.9.82/net/ipv4/udp.c linux-4.9.82-vs2.3.9.7/net/ipv4/udp.c
23812--- linux-4.9.82/net/ipv4/udp.c 2018-02-22 21:19:02.000000000 +0000
23813+++ linux-4.9.82-vs2.3.9.7/net/ipv4/udp.c 2018-01-13 20:43:44.000000000 +0000
cc23e853
AM
23814@@ -361,13 +361,27 @@ int ipv4_rcv_saddr_equal(const struct so
23815 bool match_wildcard)
23816 {
23817 struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
23818+ __be32 sk1_rcv_saddr = inet1->inet_rcv_saddr,
23819+ sk2_rcv_saddr = inet2->inet_rcv_saddr;
23820
23821- if (!ipv6_only_sock(sk2)) {
23822- if (inet1->inet_rcv_saddr == inet2->inet_rcv_saddr)
23823- return 1;
23824- if (!inet1->inet_rcv_saddr || !inet2->inet_rcv_saddr)
23825- return match_wildcard;
23826- }
23827+ if (ipv6_only_sock(sk2))
23828+ return 0;
23829+
23830+ if (sk1_rcv_saddr && sk2_rcv_saddr && sk1_rcv_saddr == sk2_rcv_saddr)
23831+ return 1;
23832+
23833+ if (match_wildcard) {
23834+ if (!sk2_rcv_saddr && !sk1_rcv_saddr)
23835+ return nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
23836+
23837+ if (!sk2_rcv_saddr && sk1_rcv_saddr)
23838+ return v4_addr_in_nx_info(sk2->sk_nx_info,
23839+ sk1_rcv_saddr, NXA_MASK_BIND);
23840+
23841+ if (!sk1_rcv_saddr && sk2_rcv_saddr)
23842+ return v4_addr_in_nx_info(sk1->sk_nx_info,
23843+ sk2_rcv_saddr, NXA_MASK_BIND);
23844+ }
23845 return 0;
4bf69007 23846 }
4bf69007 23847
cc23e853
AM
23848@@ -408,6 +422,11 @@ static int compute_score(struct sock *sk
23849 if (inet->inet_rcv_saddr != daddr)
23850 return -1;
23851 score += 4;
4bf69007
AM
23852+ } else {
23853+ /* block non nx_info ips */
23854+ if (!v4_addr_in_nx_info(sk->sk_nx_info,
23855+ daddr, NXA_MASK_BIND))
23856+ return -1;
cc23e853
AM
23857 }
23858
23859 if (inet->inet_daddr) {
23860@@ -483,6 +502,7 @@ static struct sock *udp4_lib_lookup2(str
4bf69007
AM
23861 return result;
23862 }
23863
2ba6f0dd 23864+
4bf69007
AM
23865 /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
23866 * harder than this. -DaveM
23867 */
cc23e853 23868@@ -603,7 +623,7 @@ static inline bool __udp_is_mcast_sock(s
c2e5f7c8
JR
23869 udp_sk(sk)->udp_port_hash != hnum ||
23870 (inet->inet_daddr && inet->inet_daddr != rmt_addr) ||
23871 (inet->inet_dport != rmt_port && inet->inet_dport) ||
23872- (inet->inet_rcv_saddr && inet->inet_rcv_saddr != loc_addr) ||
23873+ !v4_sock_addr_match(sk->sk_nx_info, inet, loc_addr) ||
23874 ipv6_only_sock(sk) ||
23875 (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
23876 return false;
cc23e853
AM
23877@@ -1018,6 +1038,16 @@ int udp_sendmsg(struct sock *sk, struct
23878 flow_flags,
4bf69007
AM
23879 faddr, saddr, dport, inet->inet_sport);
23880
23881+ if (sk->sk_nx_info) {
23882+ rt = ip_v4_find_src(net, sk->sk_nx_info, fl4);
23883+ if (IS_ERR(rt)) {
23884+ err = PTR_ERR(rt);
23885+ rt = NULL;
23886+ goto out;
23887+ }
23888+ ip_rt_put(rt);
23889+ }
2ba6f0dd 23890+
4bf69007
AM
23891 security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
23892 rt = ip_route_output_flow(net, fl4, sk);
23893 if (IS_ERR(rt)) {
cc23e853 23894@@ -1314,7 +1344,8 @@ try_again:
4bf69007
AM
23895 if (sin) {
23896 sin->sin_family = AF_INET;
23897 sin->sin_port = udp_hdr(skb)->source;
23898- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
23899+ sin->sin_addr.s_addr = nx_map_sock_lback(
23900+ skb->sk->sk_nx_info, ip_hdr(skb)->saddr);
23901 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
c2e5f7c8 23902 *addr_len = sizeof(*sin);
4bf69007 23903 }
cc23e853
AM
23904@@ -2260,6 +2291,8 @@ static struct sock *udp_get_first(struct
23905 sk_for_each(sk, &hslot->head) {
4bf69007
AM
23906 if (!net_eq(sock_net(sk), net))
23907 continue;
23908+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23909+ continue;
23910 if (sk->sk_family == state->family)
23911 goto found;
23912 }
cc23e853 23913@@ -2277,7 +2310,9 @@ static struct sock *udp_get_next(struct
4bf69007
AM
23914
23915 do {
cc23e853 23916 sk = sk_next(sk);
4bf69007
AM
23917- } while (sk && (!net_eq(sock_net(sk), net) || sk->sk_family != state->family));
23918+ } while (sk && (!net_eq(sock_net(sk), net) ||
23919+ sk->sk_family != state->family ||
23920+ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
23921
23922 if (!sk) {
23923 if (state->bucket <= state->udp_table->mask)
cc23e853 23924@@ -2373,8 +2408,8 @@ static void udp4_format_sock(struct sock
c2e5f7c8 23925 int bucket)
4bf69007
AM
23926 {
23927 struct inet_sock *inet = inet_sk(sp);
23928- __be32 dest = inet->inet_daddr;
23929- __be32 src = inet->inet_rcv_saddr;
23930+ __be32 dest = nx_map_sock_lback(current_nx_info(), inet->inet_daddr);
23931+ __be32 src = nx_map_sock_lback(current_nx_info(), inet->inet_rcv_saddr);
23932 __u16 destp = ntohs(inet->inet_dport);
23933 __u16 srcp = ntohs(inet->inet_sport);
23934
cef7ea10
AM
23935diff -NurpP --minimal linux-4.9.82/net/ipv6/addrconf.c linux-4.9.82-vs2.3.9.7/net/ipv6/addrconf.c
23936--- linux-4.9.82/net/ipv6/addrconf.c 2018-02-22 21:19:02.000000000 +0000
23937+++ linux-4.9.82-vs2.3.9.7/net/ipv6/addrconf.c 2018-01-13 22:09:44.000000000 +0000
cc23e853 23938@@ -92,6 +92,7 @@
4bf69007
AM
23939 #include <linux/proc_fs.h>
23940 #include <linux/seq_file.h>
23941 #include <linux/export.h>
23942+#include <linux/vs_network.h>
4bf69007
AM
23943
23944 /* Set to 3 to get tracing... */
23945 #define ACONF_DEBUG 2
cc23e853
AM
23946@@ -1494,7 +1495,8 @@ static int __ipv6_dev_get_saddr(struct n
23947 struct ipv6_saddr_dst *dst,
23948 struct inet6_dev *idev,
23949 struct ipv6_saddr_score *scores,
23950- int hiscore_idx)
23951+ int hiscore_idx,
23952+ struct nx_info *nxi)
23953 {
23954 struct ipv6_saddr_score *score = &scores[1 - hiscore_idx], *hiscore = &scores[hiscore_idx];
23955
23956@@ -1524,6 +1526,8 @@ static int __ipv6_dev_get_saddr(struct n
23957 idev->dev->name);
23958 continue;
23959 }
23960+ if (!v6_addr_in_nx_info(nxi, &score->ifa->addr, -1))
23961+ continue;
23962
23963 score->rule = -1;
23964 bitmap_zero(score->scorebits, IPV6_SADDR_RULE_MAX);
23965@@ -1574,26 +1578,27 @@ static int ipv6_get_saddr_master(struct
23966 const struct net_device *master,
23967 struct ipv6_saddr_dst *dst,
23968 struct ipv6_saddr_score *scores,
23969- int hiscore_idx)
23970+ int hiscore_idx,
23971+ struct nx_info *nxi)
23972 {
23973 struct inet6_dev *idev;
23974
23975 idev = __in6_dev_get(dst_dev);
23976 if (idev)
23977- hiscore_idx = __ipv6_dev_get_saddr(net, dst, idev,
23978- scores, hiscore_idx);
23979+ hiscore_idx = __ipv6_dev_get_saddr(net, dst,
23980+ idev, scores, hiscore_idx, nxi);
23981
23982 idev = __in6_dev_get(master);
23983 if (idev)
23984- hiscore_idx = __ipv6_dev_get_saddr(net, dst, idev,
23985- scores, hiscore_idx);
23986+ hiscore_idx = __ipv6_dev_get_saddr(net, dst,
23987+ idev, scores, hiscore_idx, nxi);
23988
23989 return hiscore_idx;
23990 }
4bf69007
AM
23991
23992 int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
23993 const struct in6_addr *daddr, unsigned int prefs,
23994- struct in6_addr *saddr)
23995+ struct in6_addr *saddr, struct nx_info *nxi)
23996 {
cc23e853
AM
23997 struct ipv6_saddr_score scores[2], *hiscore;
23998 struct ipv6_saddr_dst dst;
23999@@ -1642,7 +1647,8 @@ int ipv6_dev_get_saddr(struct net *net,
24000
24001 if (use_oif_addr) {
24002 if (idev)
24003- hiscore_idx = __ipv6_dev_get_saddr(net, &dst, idev, scores, hiscore_idx);
24004+ hiscore_idx = __ipv6_dev_get_saddr(net,
24005+ &dst, idev, scores, hiscore_idx, nxi);
24006 } else {
24007 const struct net_device *master;
24008 int master_idx = 0;
24009@@ -1656,8 +1662,8 @@ int ipv6_dev_get_saddr(struct net *net,
24010 master_idx = master->ifindex;
24011
24012 hiscore_idx = ipv6_get_saddr_master(net, dst_dev,
24013- master, &dst,
24014- scores, hiscore_idx);
24015+ master, &dst, scores,
24016+ hiscore_idx, nxi);
24017
24018 if (scores[hiscore_idx].ifa)
24019 goto out;
24020@@ -1672,7 +1678,8 @@ int ipv6_dev_get_saddr(struct net *net,
24021 idev = __in6_dev_get(dev);
24022 if (!idev)
4bf69007 24023 continue;
cc23e853
AM
24024- hiscore_idx = __ipv6_dev_get_saddr(net, &dst, idev, scores, hiscore_idx);
24025+ hiscore_idx = __ipv6_dev_get_saddr(net,
24026+ &dst, idev, scores, hiscore_idx, nxi);
24027 }
24028 }
4bf69007 24029
cc23e853 24030@@ -4128,7 +4135,10 @@ static void if6_seq_stop(struct seq_file
4bf69007
AM
24031 static int if6_seq_show(struct seq_file *seq, void *v)
24032 {
24033 struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
24034- seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
2ba6f0dd 24035+
4bf69007
AM
24036+ if (nx_check(0, VS_ADMIN|VS_WATCH) ||
24037+ v6_addr_in_nx_info(current_nx_info(), &ifp->addr, -1))
24038+ seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
24039 &ifp->addr,
24040 ifp->idev->dev->ifindex,
24041 ifp->prefix_len,
cc23e853 24042@@ -4712,6 +4722,11 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
24043 struct ifacaddr6 *ifaca;
24044 int err = 1;
24045 int ip_idx = *p_ip_idx;
24046+ struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
2ba6f0dd 24047+
4bf69007
AM
24048+ /* disable ipv6 on non v6 guests */
24049+ if (nxi && !nx_info_has_v6(nxi))
24050+ return skb->len;
24051
24052 read_lock_bh(&idev->lock);
24053 switch (type) {
cc23e853 24054@@ -4722,6 +4737,8 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
24055 list_for_each_entry(ifa, &idev->addr_list, if_list) {
24056 if (++ip_idx < s_ip_idx)
24057 continue;
cc23e853
AM
24058+ if (!v6_addr_in_nx_info(nxi, &ifa->addr, -1))
24059+ continue;
4bf69007
AM
24060 err = inet6_fill_ifaddr(skb, ifa,
24061 NETLINK_CB(cb->skb).portid,
24062 cb->nlh->nlmsg_seq,
cc23e853 24063@@ -4739,6 +4756,8 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
24064 ifmca = ifmca->next, ip_idx++) {
24065 if (ip_idx < s_ip_idx)
24066 continue;
cc23e853
AM
24067+ if (!v6_addr_in_nx_info(nxi, &ifmca->mca_addr, -1))
24068+ continue;
4bf69007
AM
24069 err = inet6_fill_ifmcaddr(skb, ifmca,
24070 NETLINK_CB(cb->skb).portid,
24071 cb->nlh->nlmsg_seq,
cc23e853 24072@@ -4754,6 +4773,8 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
24073 ifaca = ifaca->aca_next, ip_idx++) {
24074 if (ip_idx < s_ip_idx)
24075 continue;
cc23e853
AM
24076+ if (!v6_addr_in_nx_info(nxi, &ifaca->aca_addr, -1))
24077+ continue;
4bf69007
AM
24078 err = inet6_fill_ifacaddr(skb, ifaca,
24079 NETLINK_CB(cb->skb).portid,
24080 cb->nlh->nlmsg_seq,
cc23e853 24081@@ -4782,6 +4803,10 @@ static int inet6_dump_addr(struct sk_buf
4bf69007
AM
24082 struct inet6_dev *idev;
24083 struct hlist_head *head;
b00e13aa 24084
4bf69007
AM
24085+ /* FIXME: maybe disable ipv6 on non v6 guests?
24086+ if (skb->sk && skb->sk->sk_vx_info)
24087+ return skb->len; */
b00e13aa
AM
24088+
24089 s_h = cb->args[0];
24090 s_idx = idx = cb->args[1];
24091 s_ip_idx = ip_idx = cb->args[2];
cc23e853 24092@@ -5300,6 +5325,7 @@ static int inet6_dump_ifinfo(struct sk_b
b00e13aa
AM
24093 struct net_device *dev;
24094 struct inet6_dev *idev;
24095 struct hlist_head *head;
24096+ struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
4bf69007
AM
24097
24098 s_h = cb->args[0];
24099 s_idx = cb->args[1];
cc23e853 24100@@ -5311,6 +5337,8 @@ static int inet6_dump_ifinfo(struct sk_b
b00e13aa 24101 hlist_for_each_entry_rcu(dev, head, index_hlist) {
4bf69007
AM
24102 if (idx < s_idx)
24103 goto cont;
24104+ if (!v6_dev_in_nx_info(dev, nxi))
24105+ goto cont;
24106 idev = __in6_dev_get(dev);
24107 if (!idev)
24108 goto cont;
cef7ea10
AM
24109diff -NurpP --minimal linux-4.9.82/net/ipv6/af_inet6.c linux-4.9.82-vs2.3.9.7/net/ipv6/af_inet6.c
24110--- linux-4.9.82/net/ipv6/af_inet6.c 2018-02-22 21:19:02.000000000 +0000
24111+++ linux-4.9.82-vs2.3.9.7/net/ipv6/af_inet6.c 2018-02-22 21:31:40.000000000 +0000
cc23e853 24112@@ -43,6 +43,7 @@
4bf69007
AM
24113 #include <linux/netdevice.h>
24114 #include <linux/icmpv6.h>
24115 #include <linux/netfilter_ipv6.h>
24116+#include <linux/vs_inet.h>
4bf69007
AM
24117
24118 #include <net/ip.h>
24119 #include <net/ipv6.h>
cc23e853 24120@@ -167,10 +168,13 @@ lookup_protocol:
4bf69007
AM
24121 }
24122
24123 err = -EPERM;
24124+ if ((protocol == IPPROTO_ICMPV6) &&
24125+ nx_capable(CAP_NET_RAW, NXC_RAW_ICMP))
24126+ goto override;
b00e13aa
AM
24127 if (sock->type == SOCK_RAW && !kern &&
24128 !ns_capable(net->user_ns, CAP_NET_RAW))
4bf69007
AM
24129 goto out_rcu_unlock;
24130-
24131+override:
24132 sock->ops = answer->ops;
24133 answer_prot = answer->prot;
bb20add7 24134 answer_flags = answer->flags;
cc23e853 24135@@ -272,6 +276,7 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24136 struct inet_sock *inet = inet_sk(sk);
24137 struct ipv6_pinfo *np = inet6_sk(sk);
24138 struct net *net = sock_net(sk);
24139+ struct nx_v6_sock_addr nsa;
24140 __be32 v4addr = 0;
24141 unsigned short snum;
cef7ea10
AM
24142 bool saved_ipv6only;
24143@@ -288,6 +293,10 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24144 if (addr->sin6_family != AF_INET6)
24145 return -EAFNOSUPPORT;
24146
24147+ err = v6_map_sock_addr(inet, addr, &nsa);
24148+ if (err)
24149+ return err;
2ba6f0dd 24150+
4bf69007
AM
24151 addr_type = ipv6_addr_type(&addr->sin6_addr);
24152 if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM)
24153 return -EINVAL;
cef7ea10 24154@@ -328,6 +337,10 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24155 err = -EADDRNOTAVAIL;
24156 goto out;
24157 }
24158+ if (!v4_addr_in_nx_info(sk->sk_nx_info, v4addr, NXA_MASK_BIND)) {
24159+ err = -EADDRNOTAVAIL;
24160+ goto out;
24161+ }
24162 } else {
24163 if (addr_type != IPV6_ADDR_ANY) {
24164 struct net_device *dev = NULL;
cef7ea10 24165@@ -354,6 +367,11 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24166 }
24167 }
24168
24169+ if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) {
24170+ err = -EADDRNOTAVAIL;
24171+ goto out_unlock;
24172+ }
2ba6f0dd 24173+
4bf69007
AM
24174 /* ipv4 addr of the socket is invalid. Only the
24175 * unspecified and mapped address have a v4 equivalent.
24176 */
cef7ea10 24177@@ -371,6 +389,9 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24178 }
24179 }
24180
24181+ /* what's that for? */
24182+ v6_set_sock_addr(inet, &nsa);
2ba6f0dd 24183+
4bf69007
AM
24184 inet->inet_rcv_saddr = v4addr;
24185 inet->inet_saddr = v4addr;
24186
cef7ea10 24187@@ -477,9 +498,11 @@ int inet6_getname(struct socket *sock, s
4bf69007
AM
24188 return -ENOTCONN;
24189 sin->sin6_port = inet->inet_dport;
c2e5f7c8 24190 sin->sin6_addr = sk->sk_v6_daddr;
4bf69007
AM
24191+ /* FIXME: remap lback? */
24192 if (np->sndflow)
24193 sin->sin6_flowinfo = np->flow_label;
24194 } else {
24195+ /* FIXME: remap lback? */
c2e5f7c8 24196 if (ipv6_addr_any(&sk->sk_v6_rcv_saddr))
4bf69007
AM
24197 sin->sin6_addr = np->saddr;
24198 else
cef7ea10
AM
24199diff -NurpP --minimal linux-4.9.82/net/ipv6/datagram.c linux-4.9.82-vs2.3.9.7/net/ipv6/datagram.c
24200--- linux-4.9.82/net/ipv6/datagram.c 2018-02-22 21:19:02.000000000 +0000
24201+++ linux-4.9.82-vs2.3.9.7/net/ipv6/datagram.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 24202@@ -777,7 +777,7 @@ int ip6_datagram_send_ctl(struct net *ne
4bf69007
AM
24203
24204 rcu_read_lock();
24205 if (fl6->flowi6_oif) {
24206- dev = dev_get_by_index_rcu(net, fl6->flowi6_oif);
24207+ dev = dev_get_by_index_real_rcu(net, fl6->flowi6_oif);
24208 if (!dev) {
24209 rcu_read_unlock();
24210 return -ENODEV;
cef7ea10
AM
24211diff -NurpP --minimal linux-4.9.82/net/ipv6/fib6_rules.c linux-4.9.82-vs2.3.9.7/net/ipv6/fib6_rules.c
24212--- linux-4.9.82/net/ipv6/fib6_rules.c 2018-02-22 21:19:02.000000000 +0000
24213+++ linux-4.9.82-vs2.3.9.7/net/ipv6/fib6_rules.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 24214@@ -102,7 +102,7 @@ static int fib6_rule_action(struct fib_r
4bf69007
AM
24215 ip6_dst_idev(&rt->dst)->dev,
24216 &flp6->daddr,
24217 rt6_flags2srcprefs(flags),
24218- &saddr))
24219+ &saddr, NULL))
24220 goto again;
24221 if (!ipv6_prefix_equal(&saddr, &r->src.addr,
24222 r->src.plen))
cef7ea10
AM
24223diff -NurpP --minimal linux-4.9.82/net/ipv6/inet6_hashtables.c linux-4.9.82-vs2.3.9.7/net/ipv6/inet6_hashtables.c
24224--- linux-4.9.82/net/ipv6/inet6_hashtables.c 2016-12-11 19:17:54.000000000 +0000
24225+++ linux-4.9.82-vs2.3.9.7/net/ipv6/inet6_hashtables.c 2018-01-13 00:26:28.000000000 +0000
4bf69007
AM
24226@@ -16,6 +16,7 @@
24227
24228 #include <linux/module.h>
24229 #include <linux/random.h>
24230+#include <linux/vs_inet6.h>
24231
cc23e853 24232 #include <net/addrconf.h>
4bf69007 24233 #include <net/inet_connection_sock.h>
cc23e853 24234@@ -108,6 +109,9 @@ static inline int compute_score(struct s
c2e5f7c8 24235 if (!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr))
4bf69007
AM
24236 return -1;
24237 score++;
24238+ } else {
24239+ if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1))
24240+ return -1;
24241 }
cc23e853 24242 if (sk->sk_bound_dev_if || exact_dif) {
4bf69007 24243 if (sk->sk_bound_dev_if != dif)
cc23e853
AM
24244@@ -282,39 +286,71 @@ EXPORT_SYMBOL_GPL(inet6_hash);
24245 * IPV6_ADDR_ANY only equals to IPV6_ADDR_ANY,
24246 * and 0.0.0.0 equals to 0.0.0.0 only
24247 */
24248-int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2,
24249+int ipv6_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2,
24250 bool match_wildcard)
24251 {
24252+ const struct in6_addr *sk1_rcv_saddr6 = inet6_rcv_saddr(sk1);
24253 const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
24254+ __be32 sk1_rcv_saddr = sk1->sk_rcv_saddr;
24255+ __be32 sk2_rcv_saddr = sk2->sk_rcv_saddr;
24256+ int sk1_ipv6only = inet_v6_ipv6only(sk1);
24257 int sk2_ipv6only = inet_v6_ipv6only(sk2);
24258- int addr_type = ipv6_addr_type(&sk->sk_v6_rcv_saddr);
24259+ int addr_type1 = ipv6_addr_type(sk1_rcv_saddr6);
24260 int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED;
24261
24262+
24263+ /* if one is mapped and the other is ipv6only exit early */
24264+ if (addr_type1 == IPV6_ADDR_MAPPED && sk2_ipv6only)
24265+ return 0;
24266+
24267+ if (addr_type2 == IPV6_ADDR_MAPPED && sk1_ipv6only)
24268+ return 0;
24269+
24270 /* if both are mapped, treat as IPv4 */
24271- if (addr_type == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED) {
24272- if (!sk2_ipv6only) {
24273- if (sk->sk_rcv_saddr == sk2->sk_rcv_saddr)
24274- return 1;
24275- if (!sk->sk_rcv_saddr || !sk2->sk_rcv_saddr)
24276- return match_wildcard;
24277- }
24278+ if (addr_type1 == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED) {
24279+ if (sk1_rcv_saddr == sk2_rcv_saddr)
24280+ return 1;
24281+ if ((!sk1_rcv_saddr || !sk2_rcv_saddr) && match_wildcard)
24282+ goto vs_v4;
24283 return 0;
24284 }
24285
24286- if (addr_type == IPV6_ADDR_ANY && addr_type2 == IPV6_ADDR_ANY)
24287- return 1;
24288+ /* if both are wildcards, check for overlap */
24289+ if (addr_type1 == IPV6_ADDR_ANY && addr_type2 == IPV6_ADDR_ANY)
24290+ return nx_v6_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
24291
24292- if (addr_type2 == IPV6_ADDR_ANY && match_wildcard &&
24293- !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED))
24294+ /* if both are valid ipv6 addresses, mapped handled above */
24295+ if (addr_type1 != IPV6_ADDR_ANY && addr_type2 != IPV6_ADDR_ANY &&
24296+ sk2_rcv_saddr6 && ipv6_addr_equal(sk1_rcv_saddr6, sk2_rcv_saddr6))
24297 return 1;
24298
24299- if (addr_type == IPV6_ADDR_ANY && match_wildcard &&
24300- !(ipv6_only_sock(sk) && addr_type2 == IPV6_ADDR_MAPPED))
24301- return 1;
24302+ if (addr_type1 == IPV6_ADDR_ANY && match_wildcard) {
24303+ /* ipv6only case handled above */
24304+ if (addr_type2 == IPV6_ADDR_MAPPED)
24305+ return v4_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr, -1);
24306+ else
24307+ return v6_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr6, -1);
24308+ }
24309
24310- if (sk2_rcv_saddr6 &&
24311- ipv6_addr_equal(&sk->sk_v6_rcv_saddr, sk2_rcv_saddr6))
24312- return 1;
24313+ if (addr_type2 == IPV6_ADDR_ANY && match_wildcard) {
24314+ /* ipv6only case handled above */
24315+ if (addr_type1 == IPV6_ADDR_MAPPED)
24316+ return v4_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr, -1);
24317+ else
24318+ return v6_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr6, -1);
24319+ }
24320+
24321+ return 0;
24322+
24323+vs_v4:
24324+ if (!sk1_rcv_saddr && !sk2_rcv_saddr)
24325+ return nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
24326+
24327+ if (!sk2_rcv_saddr)
24328+ return v4_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr, -1);
24329+
24330+ if (!sk1_rcv_saddr)
24331+ return v4_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr, -1);
24332
24333 return 0;
24334 }
cef7ea10
AM
24335diff -NurpP --minimal linux-4.9.82/net/ipv6/ip6_fib.c linux-4.9.82-vs2.3.9.7/net/ipv6/ip6_fib.c
24336--- linux-4.9.82/net/ipv6/ip6_fib.c 2018-02-22 21:19:02.000000000 +0000
24337+++ linux-4.9.82-vs2.3.9.7/net/ipv6/ip6_fib.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 24338@@ -1976,6 +1976,7 @@ static int ipv6_route_seq_show(struct se
c2e5f7c8
JR
24339 struct rt6_info *rt = v;
24340 struct ipv6_route_iter *iter = seq->private;
24341
24342+ /* FIXME: check for network context? */
24343 seq_printf(seq, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen);
24344
24345 #ifdef CONFIG_IPV6_SUBTREES
cef7ea10
AM
24346diff -NurpP --minimal linux-4.9.82/net/ipv6/ip6_output.c linux-4.9.82-vs2.3.9.7/net/ipv6/ip6_output.c
24347--- linux-4.9.82/net/ipv6/ip6_output.c 2018-02-22 21:19:02.000000000 +0000
24348+++ linux-4.9.82-vs2.3.9.7/net/ipv6/ip6_output.c 2018-02-10 15:15:43.000000000 +0000
cc23e853
AM
24349@@ -956,7 +956,8 @@ static int ip6_dst_lookup_tail(struct ne
24350 rt = (*dst)->error ? NULL : (struct rt6_info *)*dst;
4bf69007
AM
24351 err = ip6_route_get_saddr(net, rt, &fl6->daddr,
24352 sk ? inet6_sk(sk)->srcprefs : 0,
24353- &fl6->saddr);
24354+ &fl6->saddr,
24355+ sk ? sk->sk_nx_info : NULL);
24356 if (err)
24357 goto out_err_release;
cc23e853 24358
cef7ea10
AM
24359diff -NurpP --minimal linux-4.9.82/net/ipv6/ip6_tunnel.c linux-4.9.82-vs2.3.9.7/net/ipv6/ip6_tunnel.c
24360--- linux-4.9.82/net/ipv6/ip6_tunnel.c 2018-02-22 21:19:02.000000000 +0000
24361+++ linux-4.9.82-vs2.3.9.7/net/ipv6/ip6_tunnel.c 2018-01-25 00:21:32.000000000 +0000
369dbd59 24362@@ -1109,7 +1109,7 @@ route_lookup:
cc23e853
AM
24363 }
24364 if (t->parms.collect_md &&
24365 ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev,
24366- &fl6->daddr, 0, &fl6->saddr))
24367+ &fl6->daddr, 0, &fl6->saddr, NULL))
24368 goto tx_err_link_failure;
24369 ndst = dst;
4bf69007 24370 }
cef7ea10
AM
24371diff -NurpP --minimal linux-4.9.82/net/ipv6/ndisc.c linux-4.9.82-vs2.3.9.7/net/ipv6/ndisc.c
24372--- linux-4.9.82/net/ipv6/ndisc.c 2016-12-11 19:17:54.000000000 +0000
24373+++ linux-4.9.82-vs2.3.9.7/net/ipv6/ndisc.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 24374@@ -512,7 +512,7 @@ void ndisc_send_na(struct net_device *de
4bf69007
AM
24375 } else {
24376 if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
24377 inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
24378- &tmpaddr))
24379+ &tmpaddr, NULL))
24380 return;
24381 src_addr = &tmpaddr;
24382 }
cef7ea10
AM
24383diff -NurpP --minimal linux-4.9.82/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c linux-4.9.82-vs2.3.9.7/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c
24384--- linux-4.9.82/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c 2016-12-11 19:17:54.000000000 +0000
24385+++ linux-4.9.82-vs2.3.9.7/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 24386@@ -39,7 +39,7 @@ nf_nat_masquerade_ipv6(struct sk_buff *s
4bf69007
AM
24387 ctinfo == IP_CT_RELATED_REPLY));
24388
cc23e853 24389 if (ipv6_dev_get_saddr(nf_ct_net(ct), out,
4bf69007
AM
24390- &ipv6_hdr(skb)->daddr, 0, &src) < 0)
24391+ &ipv6_hdr(skb)->daddr, 0, &src, NULL) < 0)
24392 return NF_DROP;
24393
bb20add7 24394 nfct_nat(ct)->masq_index = out->ifindex;
cef7ea10
AM
24395diff -NurpP --minimal linux-4.9.82/net/ipv6/raw.c linux-4.9.82-vs2.3.9.7/net/ipv6/raw.c
24396--- linux-4.9.82/net/ipv6/raw.c 2018-02-22 21:19:02.000000000 +0000
24397+++ linux-4.9.82-vs2.3.9.7/net/ipv6/raw.c 2018-01-13 22:10:35.000000000 +0000
cc23e853 24398@@ -291,6 +291,13 @@ static int rawv6_bind(struct sock *sk, s
4bf69007
AM
24399 goto out_unlock;
24400 }
24401
24402+ if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) {
24403+ err = -EADDRNOTAVAIL;
24404+ if (dev)
24405+ dev_put(dev);
24406+ goto out;
24407+ }
2ba6f0dd 24408+
4bf69007
AM
24409 /* ipv4 addr of the socket is invalid. Only the
24410 * unspecified and mapped address have a v4 equivalent.
24411 */
cef7ea10
AM
24412diff -NurpP --minimal linux-4.9.82/net/ipv6/route.c linux-4.9.82-vs2.3.9.7/net/ipv6/route.c
24413--- linux-4.9.82/net/ipv6/route.c 2018-02-22 21:19:02.000000000 +0000
24414+++ linux-4.9.82-vs2.3.9.7/net/ipv6/route.c 2018-01-13 22:10:45.000000000 +0000
cc23e853 24415@@ -3288,7 +3288,8 @@ static int rt6_fill_node(struct net *net
4bf69007
AM
24416 goto nla_put_failure;
24417 } else if (dst) {
24418 struct in6_addr saddr_buf;
24419- if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf) == 0 &&
24420+ if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf,
24421+ (skb->sk ? skb->sk->sk_nx_info : NULL)) == 0 &&
cc23e853 24422 nla_put_in6_addr(skb, RTA_PREFSRC, &saddr_buf))
4bf69007
AM
24423 goto nla_put_failure;
24424 }
cef7ea10
AM
24425diff -NurpP --minimal linux-4.9.82/net/ipv6/tcp_ipv6.c linux-4.9.82-vs2.3.9.7/net/ipv6/tcp_ipv6.c
24426--- linux-4.9.82/net/ipv6/tcp_ipv6.c 2018-02-22 21:19:02.000000000 +0000
24427+++ linux-4.9.82-vs2.3.9.7/net/ipv6/tcp_ipv6.c 2018-01-13 22:10:53.000000000 +0000
cc23e853 24428@@ -149,11 +149,18 @@ static int tcp_v6_connect(struct sock *s
4bf69007
AM
24429 */
24430
cc23e853
AM
24431 if (ipv6_addr_any(&usin->sin6_addr)) {
24432- if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr))
24433- ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK),
24434- &usin->sin6_addr);
24435- else
24436- usin->sin6_addr = in6addr_loopback;
4bf69007 24437+ struct nx_info *nxi = sk->sk_nx_info;
2ba6f0dd 24438+
4bf69007
AM
24439+ if (nxi && nx_info_has_v6(nxi))
24440+ /* FIXME: remap lback? */
24441+ usin->sin6_addr = nxi->v6.ip;
cc23e853
AM
24442+ else {
24443+ if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr))
24444+ ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK),
24445+ &usin->sin6_addr);
24446+ else
24447+ usin->sin6_addr = in6addr_loopback;
24448+ }
24449 }
4bf69007
AM
24450
24451 addr_type = ipv6_addr_type(&usin->sin6_addr);
cef7ea10
AM
24452diff -NurpP --minimal linux-4.9.82/net/ipv6/udp.c linux-4.9.82-vs2.3.9.7/net/ipv6/udp.c
24453--- linux-4.9.82/net/ipv6/udp.c 2018-02-22 21:19:02.000000000 +0000
24454+++ linux-4.9.82-vs2.3.9.7/net/ipv6/udp.c 2018-01-13 22:11:04.000000000 +0000
cc23e853
AM
24455@@ -135,6 +135,10 @@ static int compute_score(struct sock *sk
24456 if (inet->inet_dport != sport)
24457 return -1;
24458 score++;
4bf69007
AM
24459+ } else {
24460+ /* block non nx_info ips */
24461+ if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1))
24462+ return -1;
cc23e853
AM
24463 }
24464
24465 if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
cef7ea10
AM
24466diff -NurpP --minimal linux-4.9.82/net/ipv6/xfrm6_policy.c linux-4.9.82-vs2.3.9.7/net/ipv6/xfrm6_policy.c
24467--- linux-4.9.82/net/ipv6/xfrm6_policy.c 2016-12-11 19:17:54.000000000 +0000
24468+++ linux-4.9.82-vs2.3.9.7/net/ipv6/xfrm6_policy.c 2018-01-10 02:50:49.000000000 +0000
cc23e853
AM
24469@@ -64,7 +64,8 @@ static int xfrm6_get_saddr(struct net *n
24470 return -EHOSTUNREACH;
24471
4bf69007 24472 dev = ip6_dst_idev(dst)->dev;
cc23e853
AM
24473- ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6, 0, &saddr->in6);
24474+ ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6,
24475+ 0, &saddr->in6, NULL);
4bf69007
AM
24476 dst_release(dst);
24477 return 0;
24478 }
cef7ea10
AM
24479diff -NurpP --minimal linux-4.9.82/net/netfilter/ipvs/ip_vs_xmit.c linux-4.9.82-vs2.3.9.7/net/netfilter/ipvs/ip_vs_xmit.c
24480--- linux-4.9.82/net/netfilter/ipvs/ip_vs_xmit.c 2016-12-11 19:17:54.000000000 +0000
24481+++ linux-4.9.82-vs2.3.9.7/net/netfilter/ipvs/ip_vs_xmit.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 24482@@ -381,7 +381,7 @@ __ip_vs_route_output_v6(struct net *net,
4bf69007
AM
24483 return dst;
24484 if (ipv6_addr_any(&fl6.saddr) &&
24485 ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev,
24486- &fl6.daddr, 0, &fl6.saddr) < 0)
24487+ &fl6.daddr, 0, &fl6.saddr, NULL) < 0)
24488 goto out_err;
24489 if (do_xfrm) {
24490 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
cef7ea10
AM
24491diff -NurpP --minimal linux-4.9.82/net/netlink/af_netlink.c linux-4.9.82-vs2.3.9.7/net/netlink/af_netlink.c
24492--- linux-4.9.82/net/netlink/af_netlink.c 2018-02-22 21:19:04.000000000 +0000
24493+++ linux-4.9.82-vs2.3.9.7/net/netlink/af_netlink.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 24494@@ -62,6 +62,8 @@
bb20add7
AM
24495 #include <asm/cacheflush.h>
24496 #include <linux/hash.h>
cc23e853 24497 #include <linux/genetlink.h>
4bf69007
AM
24498+#include <linux/vs_context.h>
24499+#include <linux/vs_network.h>
4bf69007
AM
24500
24501 #include <net/net_namespace.h>
bb20add7 24502 #include <net/sock.h>
cc23e853
AM
24503@@ -2463,7 +2465,8 @@ static void *__netlink_seq_next(struct s
24504 if (err)
24505 return ERR_PTR(err);
24506 }
24507- } while (sock_net(&nlk->sk) != seq_file_net(seq));
24508+ } while ((sock_net(&nlk->sk) != seq_file_net(seq)) ||
24509+ !nx_check(nlk->sk.sk_nid, VS_WATCH_P | VS_IDENT));
bb20add7 24510
cc23e853
AM
24511 return nlk;
24512 }
cef7ea10
AM
24513diff -NurpP --minimal linux-4.9.82/net/socket.c linux-4.9.82-vs2.3.9.7/net/socket.c
24514--- linux-4.9.82/net/socket.c 2018-02-22 21:19:05.000000000 +0000
24515+++ linux-4.9.82-vs2.3.9.7/net/socket.c 2018-02-10 15:15:43.000000000 +0000
cc23e853 24516@@ -99,10 +99,12 @@
4bf69007
AM
24517
24518 #include <net/sock.h>
24519 #include <linux/netfilter.h>
4bf69007
AM
24520+#include <linux/vs_socket.h>
24521+#include <linux/vs_inet.h>
24522+#include <linux/vs_inet6.h>
24523
24524 #include <linux/if_tun.h>
24525 #include <linux/ipv6_route.h>
cc23e853
AM
24526-#include <linux/route.h>
24527 #include <linux/sockios.h>
24528 #include <linux/atalk.h>
24529 #include <net/busy_poll.h>
24530@@ -618,8 +620,24 @@ EXPORT_SYMBOL(__sock_tx_timestamp);
4bf69007 24531
cc23e853
AM
24532 static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
24533 {
24534- int ret = sock->ops->sendmsg(sock, msg, msg_data_left(msg));
24535- BUG_ON(ret == -EIOCBQUEUED);
24536+ size_t size = msg_data_left(msg);
24537+ int ret = sock->ops->sendmsg(sock, msg, size);
24538+#if 0
4bf69007 24539+ if (sock->sk) {
cc23e853 24540+ if (!ret)
4bf69007 24541+ vx_sock_fail(sock->sk, size);
cc23e853
AM
24542+ else
24543+ vx_sock_send(sock->sk, size);
4bf69007 24544+ }
cc23e853 24545+#endif
4bf69007 24546+ vxdprintk(VXD_CBIT(net, 7),
cc23e853 24547+ "sock_sendmsg_nosec: %p[%p,%p,%p;%d/%d]:%zu/%zu",
4bf69007
AM
24548+ sock, sock->sk,
24549+ (sock->sk)?sock->sk->sk_nx_info:0,
24550+ (sock->sk)?sock->sk->sk_vx_info:0,
24551+ (sock->sk)?sock->sk->sk_xid:0,
24552+ (sock->sk)?sock->sk->sk_nid:0,
cc23e853
AM
24553+ size, msg_data_left(msg));
24554 return ret;
4bf69007
AM
24555 }
24556
cc23e853 24557@@ -1109,6 +1127,13 @@ int __sock_create(struct net *net, int f
4bf69007
AM
24558 if (type < 0 || type >= SOCK_MAX)
24559 return -EINVAL;
24560
24561+ if (!nx_check(0, VS_ADMIN)) {
24562+ if (family == PF_INET && !current_nx_info_has_v4())
24563+ return -EAFNOSUPPORT;
24564+ if (family == PF_INET6 && !current_nx_info_has_v6())
24565+ return -EAFNOSUPPORT;
24566+ }
2ba6f0dd 24567+
4bf69007
AM
24568 /* Compatibility.
24569
24570 This uglymoron is moved from INET layer to here to avoid
cc23e853 24571@@ -1239,6 +1264,7 @@ SYSCALL_DEFINE3(socket, int, family, int
4bf69007
AM
24572 if (retval < 0)
24573 goto out;
24574
24575+ set_bit(SOCK_USER_SOCKET, &sock->flags);
24576 retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
24577 if (retval < 0)
24578 goto out_release;
cc23e853 24579@@ -1280,10 +1306,12 @@ SYSCALL_DEFINE4(socketpair, int, family,
4bf69007
AM
24580 err = sock_create(family, type, protocol, &sock1);
24581 if (err < 0)
24582 goto out;
24583+ set_bit(SOCK_USER_SOCKET, &sock1->flags);
24584
24585 err = sock_create(family, type, protocol, &sock2);
24586 if (err < 0)
24587 goto out_release_1;
24588+ set_bit(SOCK_USER_SOCKET, &sock2->flags);
24589
24590 err = sock1->ops->socketpair(sock1, sock2);
24591 if (err < 0)
cef7ea10
AM
24592diff -NurpP --minimal linux-4.9.82/net/sunrpc/auth.c linux-4.9.82-vs2.3.9.7/net/sunrpc/auth.c
24593--- linux-4.9.82/net/sunrpc/auth.c 2016-12-11 19:17:54.000000000 +0000
24594+++ linux-4.9.82-vs2.3.9.7/net/sunrpc/auth.c 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
24595@@ -15,6 +15,7 @@
24596 #include <linux/sunrpc/clnt.h>
24597 #include <linux/sunrpc/gss_api.h>
24598 #include <linux/spinlock.h>
24599+#include <linux/vs_tag.h>
24600
cc23e853 24601 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
4bf69007 24602 # define RPCDBG_FACILITY RPCDBG_AUTH
bb20add7 24603@@ -630,6 +631,7 @@ rpcauth_lookupcred(struct rpc_auth *auth
4bf69007
AM
24604 memset(&acred, 0, sizeof(acred));
24605 acred.uid = cred->fsuid;
24606 acred.gid = cred->fsgid;
a4a22af8 24607+ acred.tag = make_ktag(&init_user_ns, dx_current_tag());
bb20add7 24608 acred.group_info = cred->group_info;
4bf69007 24609 ret = auth->au_ops->lookup_cred(auth, &acred, flags);
bb20add7
AM
24610 return ret;
24611@@ -669,6 +671,7 @@ rpcauth_bind_root_cred(struct rpc_task *
4bf69007 24612 struct auth_cred acred = {
b00e13aa
AM
24613 .uid = GLOBAL_ROOT_UID,
24614 .gid = GLOBAL_ROOT_GID,
a4a22af8 24615+ .tag = KTAGT_INIT(dx_current_tag()),
4bf69007
AM
24616 };
24617
24618 dprintk("RPC: %5u looking up %s cred\n",
cef7ea10
AM
24619diff -NurpP --minimal linux-4.9.82/net/sunrpc/auth_unix.c linux-4.9.82-vs2.3.9.7/net/sunrpc/auth_unix.c
24620--- linux-4.9.82/net/sunrpc/auth_unix.c 2016-12-11 19:17:54.000000000 +0000
24621+++ linux-4.9.82-vs2.3.9.7/net/sunrpc/auth_unix.c 2018-01-10 02:50:49.000000000 +0000
4bf69007
AM
24622@@ -13,11 +13,13 @@
24623 #include <linux/sunrpc/clnt.h>
24624 #include <linux/sunrpc/auth.h>
24625 #include <linux/user_namespace.h>
24626+#include <linux/vs_tag.h>
24627
24628 #define NFS_NGROUPS 16
24629
24630 struct unx_cred {
24631 struct rpc_cred uc_base;
b00e13aa
AM
24632+ ktag_t uc_tag;
24633 kgid_t uc_gid;
24634 kgid_t uc_gids[NFS_NGROUPS];
4bf69007 24635 };
cc23e853 24636@@ -86,6 +88,7 @@ unx_create_cred(struct rpc_auth *auth, s
4bf69007
AM
24637 groups = NFS_NGROUPS;
24638
24639 cred->uc_gid = acred->gid;
24640+ cred->uc_tag = acred->tag;
b00e13aa 24641 for (i = 0; i < groups; i++)
cc23e853 24642 cred->uc_gids[i] = acred->group_info->gid[i];
b00e13aa 24643 if (i < NFS_NGROUPS)
cc23e853 24644@@ -127,7 +130,9 @@ unx_match(struct auth_cred *acred, struc
4bf69007
AM
24645 unsigned int i;
24646
24647
b00e13aa
AM
24648- if (!uid_eq(cred->uc_uid, acred->uid) || !gid_eq(cred->uc_gid, acred->gid))
24649+ if (!uid_eq(cred->uc_uid, acred->uid) ||
24650+ !gid_eq(cred->uc_gid, acred->gid) ||
24651+ !tag_eq(cred->uc_tag, acred->tag))
4bf69007
AM
24652 return 0;
24653
24654 if (acred->group_info != NULL)
cc23e853 24655@@ -152,7 +157,7 @@ unx_marshal(struct rpc_task *task, __be3
4bf69007
AM
24656 struct rpc_clnt *clnt = task->tk_client;
24657 struct unx_cred *cred = container_of(task->tk_rqstp->rq_cred, struct unx_cred, uc_base);
24658 __be32 *base, *hold;
24659- int i;
24660+ int i, tag;
24661
24662 *p++ = htonl(RPC_AUTH_UNIX);
24663 base = p++;
cc23e853 24664@@ -163,8 +168,11 @@ unx_marshal(struct rpc_task *task, __be3
4bf69007
AM
24665 */
24666 p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
4bf69007 24667
b00e13aa
AM
24668- *p++ = htonl((u32) from_kuid(&init_user_ns, cred->uc_uid));
24669- *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gid));
24670+ tag = task->tk_client->cl_tag;
a4a22af8
AM
24671+ *p++ = htonl((u32) from_kuid(&init_user_ns,
24672+ TAGINO_KUID(tag, cred->uc_uid, cred->uc_tag)));
24673+ *p++ = htonl((u32) from_kgid(&init_user_ns,
24674+ TAGINO_KGID(tag, cred->uc_gid, cred->uc_tag)));
4bf69007 24675 hold = p++;
b00e13aa
AM
24676 for (i = 0; i < 16 && gid_valid(cred->uc_gids[i]); i++)
24677 *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gids[i]));
cef7ea10
AM
24678diff -NurpP --minimal linux-4.9.82/net/sunrpc/clnt.c linux-4.9.82-vs2.3.9.7/net/sunrpc/clnt.c
24679--- linux-4.9.82/net/sunrpc/clnt.c 2018-02-22 21:19:05.000000000 +0000
24680+++ linux-4.9.82-vs2.3.9.7/net/sunrpc/clnt.c 2018-01-10 02:50:49.000000000 +0000
4bf69007 24681@@ -31,6 +31,7 @@
c2e5f7c8 24682 #include <linux/in.h>
4bf69007
AM
24683 #include <linux/in6.h>
24684 #include <linux/un.h>
4bf69007
AM
24685+#include <linux/vs_cvirt.h>
24686
24687 #include <linux/sunrpc/clnt.h>
b00e13aa 24688 #include <linux/sunrpc/addr.h>
cc23e853 24689@@ -496,6 +497,9 @@ static struct rpc_clnt *rpc_create_xprt(
4bf69007
AM
24690 if (!(args->flags & RPC_CLNT_CREATE_QUIET))
24691 clnt->cl_chatty = 1;
24692
24693+ /* TODO: handle RPC_CLNT_CREATE_TAGGED
24694+ if (args->flags & RPC_CLNT_CREATE_TAGGED)
24695+ clnt->cl_tag = 1; */
24696 return clnt;
24697 }
cc23e853 24698
cef7ea10
AM
24699diff -NurpP --minimal linux-4.9.82/net/unix/af_unix.c linux-4.9.82-vs2.3.9.7/net/unix/af_unix.c
24700--- linux-4.9.82/net/unix/af_unix.c 2018-02-22 21:19:05.000000000 +0000
24701+++ linux-4.9.82-vs2.3.9.7/net/unix/af_unix.c 2018-01-10 02:50:49.000000000 +0000
bb20add7 24702@@ -117,6 +117,8 @@
4bf69007
AM
24703 #include <net/checksum.h>
24704 #include <linux/security.h>
c2e5f7c8 24705 #include <linux/freezer.h>
4bf69007
AM
24706+#include <linux/vs_context.h>
24707+#include <linux/vs_limit.h>
24708
24709 struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
24710 EXPORT_SYMBOL_GPL(unix_socket_table);
cc23e853 24711@@ -282,6 +284,8 @@ static struct sock *__unix_find_socket_b
4bf69007
AM
24712 if (!net_eq(sock_net(s), net))
24713 continue;
24714
24715+ if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT))
24716+ continue;
24717 if (u->addr->len == len &&
24718 !memcmp(u->addr->name, sunname, len))
24719 goto found;
cc23e853 24720@@ -2732,6 +2736,8 @@ static struct sock *unix_from_bucket(str
4bf69007
AM
24721 for (sk = sk_head(&unix_socket_table[bucket]); sk; sk = sk_next(sk)) {
24722 if (sock_net(sk) != seq_file_net(seq))
24723 continue;
24724+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24725+ continue;
24726 if (++count == offset)
24727 break;
24728 }
cc23e853 24729@@ -2749,6 +2755,8 @@ static struct sock *unix_next_socket(str
4bf69007
AM
24730 sk = sk_next(sk);
24731 if (!sk)
24732 goto next_bucket;
24733+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24734+ continue;
24735 if (sock_net(sk) == seq_file_net(seq))
24736 return sk;
24737 }
cef7ea10
AM
24738diff -NurpP --minimal linux-4.9.82/scripts/checksyscalls.sh linux-4.9.82-vs2.3.9.7/scripts/checksyscalls.sh
24739--- linux-4.9.82/scripts/checksyscalls.sh 2016-12-11 19:17:54.000000000 +0000
24740+++ linux-4.9.82-vs2.3.9.7/scripts/checksyscalls.sh 2018-01-10 02:50:49.000000000 +0000
bb20add7 24741@@ -196,7 +196,6 @@ cat << EOF
4bf69007
AM
24742 #define __IGNORE_afs_syscall
24743 #define __IGNORE_getpmsg
24744 #define __IGNORE_putpmsg
24745-#define __IGNORE_vserver
24746 EOF
24747 }
24748
cef7ea10
AM
24749diff -NurpP --minimal linux-4.9.82/security/commoncap.c linux-4.9.82-vs2.3.9.7/security/commoncap.c
24750--- linux-4.9.82/security/commoncap.c 2016-12-11 19:17:54.000000000 +0000
24751+++ linux-4.9.82-vs2.3.9.7/security/commoncap.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 24752@@ -71,6 +71,7 @@ static void warn_setuid_and_fcaps_mixed(
4bf69007
AM
24753 int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
24754 int cap, int audit)
24755 {
24756+ struct vx_info *vxi = current_vx_info(); /* FIXME: get vxi from cred? */
b00e13aa 24757 struct user_namespace *ns = targ_ns;
4bf69007 24758
b00e13aa 24759 /* See if cred has the capability in the target user namespace
cc23e853 24760@@ -79,8 +80,12 @@ int cap_capable(const struct cred *cred,
b00e13aa
AM
24761 */
24762 for (;;) {
4bf69007 24763 /* Do we have the necessary capabilities? */
b00e13aa 24764- if (ns == cred->user_ns)
4bf69007 24765- return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM;
b00e13aa 24766+ if (ns == cred->user_ns) {
4bf69007
AM
24767+ if (vx_info_flags(vxi, VXF_STATE_SETUP, 0) &&
24768+ cap_raised(cred->cap_effective, cap))
24769+ return 0;
24770+ return vx_cap_raised(vxi, cred->cap_effective, cap) ? 0 : -EPERM;
24771+ }
24772
24773 /* Have we tried all of the parent namespaces? */
b00e13aa 24774 if (ns == &init_user_ns)
cc23e853 24775@@ -667,7 +672,7 @@ int cap_inode_setxattr(struct dentry *de
4bf69007
AM
24776
24777 if (!strncmp(name, XATTR_SECURITY_PREFIX,
24778 sizeof(XATTR_SECURITY_PREFIX) - 1) &&
24779- !capable(CAP_SYS_ADMIN))
24780+ !vx_capable(CAP_SYS_ADMIN, VXC_FS_SECURITY))
24781 return -EPERM;
24782 return 0;
24783 }
cc23e853 24784@@ -693,7 +698,7 @@ int cap_inode_removexattr(struct dentry
4bf69007
AM
24785
24786 if (!strncmp(name, XATTR_SECURITY_PREFIX,
24787 sizeof(XATTR_SECURITY_PREFIX) - 1) &&
24788- !capable(CAP_SYS_ADMIN))
24789+ !vx_capable(CAP_SYS_ADMIN, VXC_FS_SECURITY))
24790 return -EPERM;
24791 return 0;
24792 }
cef7ea10
AM
24793diff -NurpP --minimal linux-4.9.82/security/selinux/hooks.c linux-4.9.82-vs2.3.9.7/security/selinux/hooks.c
24794--- linux-4.9.82/security/selinux/hooks.c 2018-02-22 21:19:06.000000000 +0000
24795+++ linux-4.9.82-vs2.3.9.7/security/selinux/hooks.c 2018-01-10 02:50:49.000000000 +0000
cc23e853 24796@@ -67,7 +67,6 @@
4bf69007
AM
24797 #include <linux/dccp.h>
24798 #include <linux/quota.h>
24799 #include <linux/un.h> /* for Unix socket types */
24800-#include <net/af_unix.h> /* for Unix socket types */
24801 #include <linux/parser.h>
24802 #include <linux/nfs_mount.h>
24803 #include <net/ipv6.h>
This page took 8.456643 seconds and 4 git commands to generate.