]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-vserver-2.3.patch
- up to 4.4.113; SECURITY: spectre v2 mitigations
[packages/kernel.git] / kernel-vserver-2.3.patch
CommitLineData
8de2f54c 1diff -NurpP --minimal linux-4.4.111/Documentation/vserver/debug.txt linux-4.4.111-vs2.3.9.5/Documentation/vserver/debug.txt
f19bd705 2--- linux-4.4.111/Documentation/vserver/debug.txt 1970-01-01 00:00:00.000000000 +0000
8de2f54c 3+++ linux-4.4.111-vs2.3.9.5/Documentation/vserver/debug.txt 2018-01-09 16:36:20.000000000 +0000
d33d7b00
AM
4@@ -0,0 +1,154 @@
5+
6+debug_cvirt:
7+
8+ 2 4 "vx_map_tgid: %p/%llx: %d -> %d"
9+ "vx_rmap_tgid: %p/%llx: %d -> %d"
10+
11+debug_dlim:
12+
13+ 0 1 "ALLOC (%p,#%d)%c inode (%d)"
14+ "FREE (%p,#%d)%c inode"
15+ 1 2 "ALLOC (%p,#%d)%c %lld bytes (%d)"
16+ "FREE (%p,#%d)%c %lld bytes"
17+ 2 4 "ADJUST: %lld,%lld on %ld,%ld [mult=%d]"
18+ 3 8 "ext3_has_free_blocks(%p): %lu<%lu+1, %c, %u!=%u r=%d"
19+ "ext3_has_free_blocks(%p): free=%lu, root=%lu"
20+ "rcu_free_dl_info(%p)"
21+ 4 10 "alloc_dl_info(%p,%d) = %p"
22+ "dealloc_dl_info(%p)"
23+ "get_dl_info(%p[#%d.%d])"
24+ "put_dl_info(%p[#%d.%d])"
25+ 5 20 "alloc_dl_info(%p,%d)*"
26+ 6 40 "__hash_dl_info: %p[#%d]"
27+ "__unhash_dl_info: %p[#%d]"
28+ 7 80 "locate_dl_info(%p,#%d) = %p"
29+
30+debug_misc:
31+
32+ 0 1 "destroy_dqhash: %p [#0x%08x] c=%d"
33+ "new_dqhash: %p [#0x%08x]"
34+ "vroot[%d]_clr_dev: dev=%p[%lu,%d:%d]"
35+ "vroot[%d]_get_real_bdev: dev=%p[%lu,%d:%d]"
36+ "vroot[%d]_set_dev: dev=%p[%lu,%d:%d]"
37+ "vroot_get_real_bdev not set"
927ca606
AM
38+ 1 2 "cow_break_link(?%s?)"
39+ "temp copy ?%s?"
d33d7b00
AM
40+ 2 4 "dentry_open(new): %p"
41+ "dentry_open(old): %p"
42+ "lookup_create(new): %p"
927ca606 43+ "old path ?%s?"
d33d7b00
AM
44+ "path_lookup(old): %d"
45+ "vfs_create(new): %d"
46+ "vfs_rename: %d"
47+ "vfs_sendfile: %d"
48+ 3 8 "fput(new_file=%p[#%d])"
49+ "fput(old_file=%p[#%d])"
50+ 4 10 "vx_info_kill(%p[#%d],%d,%d) = %d"
51+ "vx_info_kill(%p[#%d],%d,%d)*"
52+ 5 20 "vs_reboot(%p[#%d],%d)"
53+ 6 40 "dropping task %p[#%u,%u] for %p[#%u,%u]"
54+
55+debug_net:
56+
57+ 2 4 "nx_addr_conflict(%p,%p) %d.%d,%d.%d"
58+ 3 8 "inet_bind(%p) %d.%d.%d.%d, %d.%d.%d.%d, %d.%d.%d.%d"
59+ "inet_bind(%p)* %p,%p;%lx %d.%d.%d.%d"
60+ 4 10 "ip_route_connect(%p) %p,%p;%lx"
61+ 5 20 "__addr_in_socket(%p,%d.%d.%d.%d) %p:%d.%d.%d.%d %p;%lx"
62+ 6 40 "sk,egf: %p [#%d] (from %d)"
63+ "sk,egn: %p [#%d] (from %d)"
64+ "sk,req: %p [#%d] (from %d)"
65+ "sk: %p [#%d] (from %d)"
66+ "tw: %p [#%d] (from %d)"
67+ 7 80 "__sock_recvmsg: %p[%p,%p,%p;%d]:%d/%d"
68+ "__sock_sendmsg: %p[%p,%p,%p;%d]:%d/%d"
69+
70+debug_nid:
71+
72+ 0 1 "__lookup_nx_info(#%u): %p[#%u]"
73+ "alloc_nx_info(%d) = %p"
74+ "create_nx_info(%d) (dynamic rejected)"
75+ "create_nx_info(%d) = %p (already there)"
76+ "create_nx_info(%d) = %p (new)"
77+ "dealloc_nx_info(%p)"
78+ 1 2 "alloc_nx_info(%d)*"
79+ "create_nx_info(%d)*"
80+ 2 4 "get_nx_info(%p[#%d.%d])"
81+ "put_nx_info(%p[#%d.%d])"
82+ 3 8 "claim_nx_info(%p[#%d.%d.%d]) %p"
83+ "clr_nx_info(%p[#%d.%d])"
84+ "init_nx_info(%p[#%d.%d])"
85+ "release_nx_info(%p[#%d.%d.%d]) %p"
86+ "set_nx_info(%p[#%d.%d])"
87+ 4 10 "__hash_nx_info: %p[#%d]"
88+ "__nx_dynamic_id: [#%d]"
89+ "__unhash_nx_info: %p[#%d.%d.%d]"
90+ 5 20 "moved task %p into nxi:%p[#%d]"
91+ "nx_migrate_task(%p,%p[#%d.%d.%d])"
92+ "task_get_nx_info(%p)"
93+ 6 40 "nx_clear_persistent(%p[#%d])"
94+
95+debug_quota:
96+
97+ 0 1 "quota_sync_dqh(%p,%d) discard inode %p"
98+ 1 2 "quota_sync_dqh(%p,%d)"
99+ "sync_dquots(%p,%d)"
100+ "sync_dquots_dqh(%p,%d)"
101+ 3 8 "do_quotactl(%p,%d,cmd=%d,id=%d,%p)"
102+
103+debug_switch:
104+
105+ 0 1 "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]"
106+ 1 2 "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]"
107+ 4 10 "%s: (%s %s) returned %s with %d"
108+
109+debug_tag:
110+
927ca606 111+ 7 80 "dx_parse_tag(?%s?): %d:#%d"
d33d7b00
AM
112+ "dx_propagate_tag(%p[#%lu.%d]): %d,%d"
113+
114+debug_xid:
115+
116+ 0 1 "__lookup_vx_info(#%u): %p[#%u]"
117+ "alloc_vx_info(%d) = %p"
118+ "alloc_vx_info(%d)*"
119+ "create_vx_info(%d) (dynamic rejected)"
120+ "create_vx_info(%d) = %p (already there)"
121+ "create_vx_info(%d) = %p (new)"
122+ "dealloc_vx_info(%p)"
123+ "loc_vx_info(%d) = %p (found)"
124+ "loc_vx_info(%d) = %p (new)"
125+ "loc_vx_info(%d) = %p (not available)"
126+ 1 2 "create_vx_info(%d)*"
127+ "loc_vx_info(%d)*"
128+ 2 4 "get_vx_info(%p[#%d.%d])"
129+ "put_vx_info(%p[#%d.%d])"
130+ 3 8 "claim_vx_info(%p[#%d.%d.%d]) %p"
131+ "clr_vx_info(%p[#%d.%d])"
132+ "init_vx_info(%p[#%d.%d])"
133+ "release_vx_info(%p[#%d.%d.%d]) %p"
134+ "set_vx_info(%p[#%d.%d])"
135+ 4 10 "__hash_vx_info: %p[#%d]"
136+ "__unhash_vx_info: %p[#%d.%d.%d]"
137+ "__vx_dynamic_id: [#%d]"
138+ 5 20 "enter_vx_info(%p[#%d],%p) %p[#%d,%p]"
139+ "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]"
140+ "moved task %p into vxi:%p[#%d]"
141+ "task_get_vx_info(%p)"
142+ "vx_migrate_task(%p,%p[#%d.%d])"
143+ 6 40 "vx_clear_persistent(%p[#%d])"
144+ "vx_exit_init(%p[#%d],%p[#%d,%d,%d])"
145+ "vx_set_init(%p[#%d],%p[#%d,%d,%d])"
146+ "vx_set_persistent(%p[#%d])"
147+ "vx_set_reaper(%p[#%d],%p[#%d,%d])"
148+ 7 80 "vx_child_reaper(%p[#%u,%u]) = %p[#%u,%u]"
149+
150+
151+debug_limit:
152+
153+ n 2^n "vx_acc_cres[%5d,%s,%2d]: %5d%s"
154+ "vx_cres_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
155+
156+ m 2^m "vx_acc_page[%5d,%s,%2d]: %5d%s"
157+ "vx_acc_pages[%5d,%s,%2d]: %5d += %5d"
158+ "vx_pages_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
8de2f54c 159diff -NurpP --minimal linux-4.4.111/arch/alpha/Kconfig linux-4.4.111-vs2.3.9.5/arch/alpha/Kconfig
f19bd705 160--- linux-4.4.111/arch/alpha/Kconfig 2016-07-05 04:11:34.000000000 +0000
8de2f54c 161+++ linux-4.4.111-vs2.3.9.5/arch/alpha/Kconfig 2018-01-09 16:36:20.000000000 +0000
927ca606 162@@ -745,6 +745,8 @@ config DUMMY_CONSOLE
2380c486
JR
163 depends on VGA_HOSE
164 default y
d337f35e
JR
165
166+source "kernel/vserver/Kconfig"
167+
168 source "security/Kconfig"
169
170 source "crypto/Kconfig"
8de2f54c 171diff -NurpP --minimal linux-4.4.111/arch/alpha/kernel/systbls.S linux-4.4.111-vs2.3.9.5/arch/alpha/kernel/systbls.S
f19bd705 172--- linux-4.4.111/arch/alpha/kernel/systbls.S 2015-07-06 20:41:36.000000000 +0000
8de2f54c 173+++ linux-4.4.111-vs2.3.9.5/arch/alpha/kernel/systbls.S 2018-01-09 16:36:20.000000000 +0000
d337f35e
JR
174@@ -446,7 +446,7 @@ sys_call_table:
175 .quad sys_stat64 /* 425 */
176 .quad sys_lstat64
177 .quad sys_fstat64
178- .quad sys_ni_syscall /* sys_vserver */
179+ .quad sys_vserver /* sys_vserver */
180 .quad sys_ni_syscall /* sys_mbind */
181 .quad sys_ni_syscall /* sys_get_mempolicy */
182 .quad sys_ni_syscall /* sys_set_mempolicy */
8de2f54c 183diff -NurpP --minimal linux-4.4.111/arch/alpha/kernel/traps.c linux-4.4.111-vs2.3.9.5/arch/alpha/kernel/traps.c
f19bd705 184--- linux-4.4.111/arch/alpha/kernel/traps.c 2015-07-06 20:41:36.000000000 +0000
8de2f54c 185+++ linux-4.4.111-vs2.3.9.5/arch/alpha/kernel/traps.c 2018-01-09 16:36:20.000000000 +0000
927ca606 186@@ -174,7 +174,8 @@ die_if_kernel(char * str, struct pt_regs
d337f35e
JR
187 #ifdef CONFIG_SMP
188 printk("CPU %d ", hard_smp_processor_id());
189 #endif
2380c486 190- printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err);
61333608 191+ printk("%s(%d:#%u): %s %ld\n", current->comm,
2380c486 192+ task_pid_nr(current), current->xid, str, err);
d337f35e 193 dik_show_regs(regs, r9_15);
b00e13aa 194 add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
d337f35e 195 dik_show_trace((unsigned long *)(regs+1));
8de2f54c 196diff -NurpP --minimal linux-4.4.111/arch/arm/Kconfig linux-4.4.111-vs2.3.9.5/arch/arm/Kconfig
f19bd705 197--- linux-4.4.111/arch/arm/Kconfig 2016-07-05 04:14:23.000000000 +0000
8de2f54c 198+++ linux-4.4.111-vs2.3.9.5/arch/arm/Kconfig 2018-01-09 16:36:20.000000000 +0000
927ca606 199@@ -2159,6 +2159,8 @@ source "fs/Kconfig"
d337f35e
JR
200
201 source "arch/arm/Kconfig.debug"
202
203+source "kernel/vserver/Kconfig"
204+
205 source "security/Kconfig"
206
207 source "crypto/Kconfig"
8de2f54c 208diff -NurpP --minimal linux-4.4.111/arch/arm/kernel/calls.S linux-4.4.111-vs2.3.9.5/arch/arm/kernel/calls.S
f19bd705 209--- linux-4.4.111/arch/arm/kernel/calls.S 2016-07-05 04:14:26.000000000 +0000
8de2f54c 210+++ linux-4.4.111-vs2.3.9.5/arch/arm/kernel/calls.S 2018-01-09 16:36:20.000000000 +0000
d337f35e
JR
211@@ -322,7 +322,7 @@
212 /* 310 */ CALL(sys_request_key)
213 CALL(sys_keyctl)
214 CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
215-/* vserver */ CALL(sys_ni_syscall)
216+ CALL(sys_vserver)
217 CALL(sys_ioprio_set)
218 /* 315 */ CALL(sys_ioprio_get)
219 CALL(sys_inotify_init)
8de2f54c 220diff -NurpP --minimal linux-4.4.111/arch/arm/kernel/traps.c linux-4.4.111-vs2.3.9.5/arch/arm/kernel/traps.c
f19bd705 221--- linux-4.4.111/arch/arm/kernel/traps.c 2018-01-11 07:57:02.000000000 +0000
8de2f54c 222+++ linux-4.4.111-vs2.3.9.5/arch/arm/kernel/traps.c 2018-01-09 16:36:20.000000000 +0000
927ca606 223@@ -258,8 +258,8 @@ static int __die(const char *str, int er
78865d5b 224
d337f35e
JR
225 print_modules();
226 __show_regs(regs);
927ca606
AM
227- pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n",
228- TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk));
229+ pr_emerg("Process %.*s (pid: %d:%u, stack limit = 0x%p)\n",
230+ TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), tsk->xid, end_of_stack(tsk));
d337f35e
JR
231
232 if (!user_mode(regs) || in_interrupt()) {
7e46296a 233 dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
8de2f54c 234diff -NurpP --minimal linux-4.4.111/arch/cris/Kconfig linux-4.4.111-vs2.3.9.5/arch/cris/Kconfig
f19bd705 235--- linux-4.4.111/arch/cris/Kconfig 2016-07-05 04:14:27.000000000 +0000
8de2f54c 236+++ linux-4.4.111-vs2.3.9.5/arch/cris/Kconfig 2018-01-09 16:36:20.000000000 +0000
927ca606 237@@ -581,6 +581,8 @@ source "fs/Kconfig"
d337f35e
JR
238
239 source "arch/cris/Kconfig.debug"
240
241+source "kernel/vserver/Kconfig"
242+
243 source "security/Kconfig"
244
245 source "crypto/Kconfig"
8de2f54c 246diff -NurpP --minimal linux-4.4.111/arch/ia64/Kconfig linux-4.4.111-vs2.3.9.5/arch/ia64/Kconfig
f19bd705 247--- linux-4.4.111/arch/ia64/Kconfig 2016-07-05 04:11:39.000000000 +0000
8de2f54c 248+++ linux-4.4.111-vs2.3.9.5/arch/ia64/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 249@@ -606,6 +606,8 @@ source "fs/Kconfig"
2380c486
JR
250
251 source "arch/ia64/Kconfig.debug"
d337f35e
JR
252
253+source "kernel/vserver/Kconfig"
254+
255 source "security/Kconfig"
256
257 source "crypto/Kconfig"
8de2f54c 258diff -NurpP --minimal linux-4.4.111/arch/ia64/kernel/entry.S linux-4.4.111-vs2.3.9.5/arch/ia64/kernel/entry.S
f19bd705 259--- linux-4.4.111/arch/ia64/kernel/entry.S 2016-07-05 04:14:27.000000000 +0000
8de2f54c 260+++ linux-4.4.111-vs2.3.9.5/arch/ia64/kernel/entry.S 2018-01-09 16:36:21.000000000 +0000
927ca606 261@@ -1694,7 +1694,7 @@ sys_call_table:
2380c486
JR
262 data8 sys_mq_notify
263 data8 sys_mq_getsetattr
264 data8 sys_kexec_load
265- data8 sys_ni_syscall // reserved for vserver
266+ data8 sys_vserver
267 data8 sys_waitid // 1270
268 data8 sys_add_key
269 data8 sys_request_key
8de2f54c 270diff -NurpP --minimal linux-4.4.111/arch/ia64/kernel/ptrace.c linux-4.4.111-vs2.3.9.5/arch/ia64/kernel/ptrace.c
f19bd705 271--- linux-4.4.111/arch/ia64/kernel/ptrace.c 2015-04-12 22:12:50.000000000 +0000
8de2f54c 272+++ linux-4.4.111-vs2.3.9.5/arch/ia64/kernel/ptrace.c 2018-01-09 16:36:21.000000000 +0000
78865d5b 273@@ -21,6 +21,7 @@
2380c486 274 #include <linux/regset.h>
d337f35e 275 #include <linux/elf.h>
ec22aa5c 276 #include <linux/tracehook.h>
d337f35e
JR
277+#include <linux/vs_base.h>
278
279 #include <asm/pgtable.h>
280 #include <asm/processor.h>
8de2f54c 281diff -NurpP --minimal linux-4.4.111/arch/ia64/kernel/traps.c linux-4.4.111-vs2.3.9.5/arch/ia64/kernel/traps.c
f19bd705 282--- linux-4.4.111/arch/ia64/kernel/traps.c 2015-04-12 22:12:50.000000000 +0000
8de2f54c 283+++ linux-4.4.111-vs2.3.9.5/arch/ia64/kernel/traps.c 2018-01-09 16:36:21.000000000 +0000
1e8b8f9b 284@@ -60,8 +60,9 @@ die (const char *str, struct pt_regs *re
d337f35e
JR
285 put_cpu();
286
287 if (++die.lock_owner_depth < 3) {
288- printk("%s[%d]: %s %ld [%d]\n",
2380c486 289- current->comm, task_pid_nr(current), str, err, ++die_counter);
61333608 290+ printk("%s[%d:#%u]: %s %ld [%d]\n",
2380c486 291+ current->comm, task_pid_nr(current), current->xid,
d337f35e 292+ str, err, ++die_counter);
2380c486
JR
293 if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV)
294 != NOTIFY_STOP)
295 show_regs(regs);
1e8b8f9b 296@@ -324,8 +325,9 @@ handle_fpu_swa (int fp_fault, struct pt_
2380c486
JR
297 if ((last.count & 15) < 5 && (ia64_fetchadd(1, &last.count, acq) & 15) < 5) {
298 last.time = current_jiffies + 5 * HZ;
299 printk(KERN_WARNING
300- "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
301- current->comm, task_pid_nr(current), regs->cr_iip + ia64_psr(regs)->ri, isr);
61333608 302+ "%s(%d:#%u): floating-point assist fault at ip %016lx, isr %016lx\n",
2380c486
JR
303+ current->comm, task_pid_nr(current), current->xid,
304+ regs->cr_iip + ia64_psr(regs)->ri, isr);
305 }
306 }
d337f35e 307 }
8de2f54c 308diff -NurpP --minimal linux-4.4.111/arch/m32r/kernel/traps.c linux-4.4.111-vs2.3.9.5/arch/m32r/kernel/traps.c
f19bd705 309--- linux-4.4.111/arch/m32r/kernel/traps.c 2015-04-12 22:12:50.000000000 +0000
8de2f54c 310+++ linux-4.4.111-vs2.3.9.5/arch/m32r/kernel/traps.c 2018-01-09 16:36:21.000000000 +0000
09be7631 311@@ -184,8 +184,9 @@ static void show_registers(struct pt_reg
d337f35e
JR
312 } else {
313 printk("SPI: %08lx\n", sp);
314 }
315- printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
2380c486 316- current->comm, task_pid_nr(current), 0xffff & i, 4096+(unsigned long)current);
61333608 317+ printk("Process %s (pid: %d:#%u, process nr: %d, stackpage=%08lx)",
2380c486 318+ current->comm, task_pid_nr(current), current->xid,
d337f35e
JR
319+ 0xffff & i, 4096+(unsigned long)current);
320
321 /*
322 * When in-kernel, we also print out the stack and code at the
8de2f54c 323diff -NurpP --minimal linux-4.4.111/arch/m68k/Kconfig linux-4.4.111-vs2.3.9.5/arch/m68k/Kconfig
f19bd705 324--- linux-4.4.111/arch/m68k/Kconfig 2016-07-05 04:11:39.000000000 +0000
8de2f54c 325+++ linux-4.4.111-vs2.3.9.5/arch/m68k/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 326@@ -164,6 +164,8 @@ source "fs/Kconfig"
d337f35e
JR
327
328 source "arch/m68k/Kconfig.debug"
329
330+source "kernel/vserver/Kconfig"
331+
332 source "security/Kconfig"
333
334 source "crypto/Kconfig"
8de2f54c 335diff -NurpP --minimal linux-4.4.111/arch/mips/Kconfig linux-4.4.111-vs2.3.9.5/arch/mips/Kconfig
f19bd705 336--- linux-4.4.111/arch/mips/Kconfig 2018-01-11 07:57:04.000000000 +0000
8de2f54c 337+++ linux-4.4.111-vs2.3.9.5/arch/mips/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 338@@ -3026,6 +3026,8 @@ source "fs/Kconfig"
d337f35e
JR
339
340 source "arch/mips/Kconfig.debug"
341
342+source "kernel/vserver/Kconfig"
343+
344 source "security/Kconfig"
345
346 source "crypto/Kconfig"
8de2f54c 347diff -NurpP --minimal linux-4.4.111/arch/mips/kernel/ptrace.c linux-4.4.111-vs2.3.9.5/arch/mips/kernel/ptrace.c
f19bd705 348--- linux-4.4.111/arch/mips/kernel/ptrace.c 2018-01-11 07:57:05.000000000 +0000
8de2f54c 349+++ linux-4.4.111-vs2.3.9.5/arch/mips/kernel/ptrace.c 2018-01-09 16:36:21.000000000 +0000
927ca606 350@@ -30,6 +30,7 @@
2380c486
JR
351 #include <linux/audit.h>
352 #include <linux/seccomp.h>
c2e5f7c8 353 #include <linux/ftrace.h>
d337f35e
JR
354+#include <linux/vs_base.h>
355
356 #include <asm/byteorder.h>
357 #include <asm/cpu.h>
927ca606 358@@ -690,6 +691,9 @@ long arch_ptrace(struct task_struct *chi
ab30d09f
AM
359 void __user *datavp = (void __user *) data;
360 unsigned long __user *datalp = (void __user *) data;
d337f35e 361
2380c486 362+ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT))
d337f35e
JR
363+ goto out;
364+
365 switch (request) {
366 /* when I and D space are separate, these will need to be fixed. */
367 case PTRACE_PEEKTEXT: /* read word at location addr. */
8de2f54c 368diff -NurpP --minimal linux-4.4.111/arch/mips/kernel/scall32-o32.S linux-4.4.111-vs2.3.9.5/arch/mips/kernel/scall32-o32.S
f19bd705 369--- linux-4.4.111/arch/mips/kernel/scall32-o32.S 2018-01-11 07:57:05.000000000 +0000
8de2f54c 370+++ linux-4.4.111-vs2.3.9.5/arch/mips/kernel/scall32-o32.S 2018-01-09 16:36:21.000000000 +0000
927ca606 371@@ -512,7 +512,7 @@ EXPORT(sys_call_table)
c2e5f7c8
JR
372 PTR sys_mq_timedreceive
373 PTR sys_mq_notify /* 4275 */
374 PTR sys_mq_getsetattr
375- PTR sys_ni_syscall /* sys_vserver */
376+ PTR sys_vserver
377 PTR sys_waitid
378 PTR sys_ni_syscall /* available, was setaltroot */
379 PTR sys_add_key /* 4280 */
8de2f54c 380diff -NurpP --minimal linux-4.4.111/arch/mips/kernel/scall64-64.S linux-4.4.111-vs2.3.9.5/arch/mips/kernel/scall64-64.S
f19bd705 381--- linux-4.4.111/arch/mips/kernel/scall64-64.S 2018-01-11 07:57:05.000000000 +0000
8de2f54c 382+++ linux-4.4.111-vs2.3.9.5/arch/mips/kernel/scall64-64.S 2018-01-09 16:36:21.000000000 +0000
927ca606 383@@ -349,7 +349,7 @@ EXPORT(sys_call_table)
d337f35e
JR
384 PTR sys_mq_timedreceive
385 PTR sys_mq_notify
386 PTR sys_mq_getsetattr /* 5235 */
387- PTR sys_ni_syscall /* sys_vserver */
388+ PTR sys_vserver
389 PTR sys_waitid
390 PTR sys_ni_syscall /* available, was setaltroot */
391 PTR sys_add_key
8de2f54c 392diff -NurpP --minimal linux-4.4.111/arch/mips/kernel/scall64-n32.S linux-4.4.111-vs2.3.9.5/arch/mips/kernel/scall64-n32.S
f19bd705 393--- linux-4.4.111/arch/mips/kernel/scall64-n32.S 2018-01-11 07:57:05.000000000 +0000
8de2f54c 394+++ linux-4.4.111-vs2.3.9.5/arch/mips/kernel/scall64-n32.S 2018-01-09 16:36:21.000000000 +0000
927ca606 395@@ -339,7 +339,7 @@ EXPORT(sysn32_call_table)
d337f35e
JR
396 PTR compat_sys_mq_timedreceive
397 PTR compat_sys_mq_notify
398 PTR compat_sys_mq_getsetattr
399- PTR sys_ni_syscall /* 6240, sys_vserver */
400+ PTR sys32_vserver /* 6240 */
2380c486 401 PTR compat_sys_waitid
d337f35e
JR
402 PTR sys_ni_syscall /* available, was setaltroot */
403 PTR sys_add_key
8de2f54c 404diff -NurpP --minimal linux-4.4.111/arch/mips/kernel/scall64-o32.S linux-4.4.111-vs2.3.9.5/arch/mips/kernel/scall64-o32.S
f19bd705 405--- linux-4.4.111/arch/mips/kernel/scall64-o32.S 2018-01-11 07:57:05.000000000 +0000
8de2f54c 406+++ linux-4.4.111-vs2.3.9.5/arch/mips/kernel/scall64-o32.S 2018-01-09 16:36:21.000000000 +0000
927ca606 407@@ -495,7 +495,7 @@ EXPORT(sys32_call_table)
d337f35e
JR
408 PTR compat_sys_mq_timedreceive
409 PTR compat_sys_mq_notify /* 4275 */
410 PTR compat_sys_mq_getsetattr
411- PTR sys_ni_syscall /* sys_vserver */
412+ PTR sys32_vserver
b00e13aa 413 PTR compat_sys_waitid
d337f35e
JR
414 PTR sys_ni_syscall /* available, was setaltroot */
415 PTR sys_add_key /* 4280 */
8de2f54c 416diff -NurpP --minimal linux-4.4.111/arch/mips/kernel/traps.c linux-4.4.111-vs2.3.9.5/arch/mips/kernel/traps.c
f19bd705 417--- linux-4.4.111/arch/mips/kernel/traps.c 2018-01-11 07:57:05.000000000 +0000
8de2f54c 418+++ linux-4.4.111-vs2.3.9.5/arch/mips/kernel/traps.c 2018-01-09 16:36:21.000000000 +0000
927ca606 419@@ -353,9 +353,10 @@ void show_registers(struct pt_regs *regs
2380c486
JR
420
421 __show_regs(regs);
d337f35e 422 print_modules();
2380c486
JR
423- printk("Process %s (pid: %d, threadinfo=%p, task=%p, tls=%0*lx)\n",
424- current->comm, current->pid, current_thread_info(), current,
425- field, current_thread_info()->tp_value);
426+ printk("Process %s (pid: %d:#%u, threadinfo=%p, task=%p, tls=%0*lx)\n",
427+ current->comm, task_pid_nr(current), current->xid,
428+ current_thread_info(), current,
429+ field, current_thread_info()->tp_value);
430 if (cpu_has_userlocal) {
431 unsigned long tls;
432
8de2f54c 433diff -NurpP --minimal linux-4.4.111/arch/parisc/Kconfig linux-4.4.111-vs2.3.9.5/arch/parisc/Kconfig
f19bd705 434--- linux-4.4.111/arch/parisc/Kconfig 2016-07-05 04:14:29.000000000 +0000
8de2f54c 435+++ linux-4.4.111-vs2.3.9.5/arch/parisc/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 436@@ -341,6 +341,8 @@ config SECCOMP
d337f35e 437
bb20add7 438 If unsure, say Y. Only embedded should say N here.
d337f35e
JR
439
440+source "kernel/vserver/Kconfig"
441+
442 source "security/Kconfig"
443
444 source "crypto/Kconfig"
8de2f54c 445diff -NurpP --minimal linux-4.4.111/arch/parisc/kernel/syscall_table.S linux-4.4.111-vs2.3.9.5/arch/parisc/kernel/syscall_table.S
f19bd705 446--- linux-4.4.111/arch/parisc/kernel/syscall_table.S 2018-01-11 07:57:05.000000000 +0000
8de2f54c 447+++ linux-4.4.111-vs2.3.9.5/arch/parisc/kernel/syscall_table.S 2018-01-09 16:36:21.000000000 +0000
b00e13aa 448@@ -358,7 +358,7 @@
d337f35e
JR
449 ENTRY_COMP(mbind) /* 260 */
450 ENTRY_COMP(get_mempolicy)
451 ENTRY_COMP(set_mempolicy)
452- ENTRY_SAME(ni_syscall) /* 263: reserved for vserver */
453+ ENTRY_DIFF(vserver)
454 ENTRY_SAME(add_key)
455 ENTRY_SAME(request_key) /* 265 */
927ca606 456 ENTRY_COMP(keyctl)
8de2f54c 457diff -NurpP --minimal linux-4.4.111/arch/parisc/kernel/traps.c linux-4.4.111-vs2.3.9.5/arch/parisc/kernel/traps.c
f19bd705 458--- linux-4.4.111/arch/parisc/kernel/traps.c 2018-01-11 07:57:05.000000000 +0000
8de2f54c 459+++ linux-4.4.111-vs2.3.9.5/arch/parisc/kernel/traps.c 2018-01-09 16:36:21.000000000 +0000
927ca606 460@@ -235,8 +235,9 @@ void die_if_kernel(char *str, struct pt_
d337f35e
JR
461 return; /* STFU */
462
98968f7b
JR
463 parisc_printk_ratelimited(1, regs,
464- KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
2380c486 465- current->comm, task_pid_nr(current), str, err, regs->iaoq[0]);
98968f7b 466+ KERN_CRIT "%s (pid %d:#%u): %s (code %ld) at " RFMT "\n",
2380c486 467+ current->comm, task_pid_nr(current), current->xid,
d337f35e 468+ str, err, regs->iaoq[0]);
98968f7b
JR
469
470 return;
471 }
927ca606 472@@ -266,8 +267,8 @@ void die_if_kernel(char *str, struct pt_
d337f35e
JR
473 pdc_console_restart();
474
2380c486
JR
475 if (err)
476- printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
477- current->comm, task_pid_nr(current), str, err);
478+ printk(KERN_CRIT "%s (pid %d:#%u): %s (code %ld)\n",
479+ current->comm, task_pid_nr(current), current->xid, str, err);
480
481 /* Wot's wrong wif bein' racy? */
482 if (current->thread.flags & PARISC_KERNEL_DEATH) {
8de2f54c 483diff -NurpP --minimal linux-4.4.111/arch/powerpc/Kconfig linux-4.4.111-vs2.3.9.5/arch/powerpc/Kconfig
f19bd705 484--- linux-4.4.111/arch/powerpc/Kconfig 2018-01-11 07:57:05.000000000 +0000
8de2f54c 485+++ linux-4.4.111-vs2.3.9.5/arch/powerpc/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 486@@ -1080,6 +1080,8 @@ source "lib/Kconfig"
d33d7b00
AM
487
488 source "arch/powerpc/Kconfig.debug"
489
490+source "kernel/vserver/Kconfig"
491+
492 source "security/Kconfig"
493
927ca606 494 source "crypto/Kconfig"
8de2f54c 495diff -NurpP --minimal linux-4.4.111/arch/powerpc/include/uapi/asm/unistd.h linux-4.4.111-vs2.3.9.5/arch/powerpc/include/uapi/asm/unistd.h
f19bd705 496--- linux-4.4.111/arch/powerpc/include/uapi/asm/unistd.h 2016-07-05 04:14:29.000000000 +0000
8de2f54c 497+++ linux-4.4.111-vs2.3.9.5/arch/powerpc/include/uapi/asm/unistd.h 2018-01-09 16:36:21.000000000 +0000
adc1caaa
AM
498@@ -275,7 +275,7 @@
499 #endif
500 #define __NR_rtas 255
501 #define __NR_sys_debug_setcontext 256
502-/* Number 257 is reserved for vserver */
503+#define __NR_vserver 257
504 #define __NR_migrate_pages 258
505 #define __NR_mbind 259
506 #define __NR_get_mempolicy 260
8de2f54c 507diff -NurpP --minimal linux-4.4.111/arch/powerpc/kernel/traps.c linux-4.4.111-vs2.3.9.5/arch/powerpc/kernel/traps.c
f19bd705 508--- linux-4.4.111/arch/powerpc/kernel/traps.c 2018-01-11 07:57:06.000000000 +0000
8de2f54c 509+++ linux-4.4.111-vs2.3.9.5/arch/powerpc/kernel/traps.c 2018-01-09 16:36:21.000000000 +0000
927ca606 510@@ -1315,8 +1315,9 @@ void nonrecoverable_exception(struct pt_
d337f35e
JR
511
512 void trace_syscall(struct pt_regs *regs)
513 {
514- printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
2380c486 515- current, task_pid_nr(current), regs->nip, regs->link, regs->gpr[0],
61333608 516+ printk("Task: %p(%d:#%u), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
2380c486 517+ current, task_pid_nr(current), current->xid,
d337f35e
JR
518+ regs->nip, regs->link, regs->gpr[0],
519 regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
520 }
521
8de2f54c 522diff -NurpP --minimal linux-4.4.111/arch/s390/Kconfig linux-4.4.111-vs2.3.9.5/arch/s390/Kconfig
f19bd705 523--- linux-4.4.111/arch/s390/Kconfig 2018-01-11 07:57:06.000000000 +0000
8de2f54c 524+++ linux-4.4.111-vs2.3.9.5/arch/s390/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 525@@ -729,6 +729,8 @@ source "fs/Kconfig"
d33d7b00
AM
526
527 source "arch/s390/Kconfig.debug"
528
529+source "kernel/vserver/Kconfig"
530+
531 source "security/Kconfig"
0411181d 532
d33d7b00 533 source "crypto/Kconfig"
8de2f54c 534diff -NurpP --minimal linux-4.4.111/arch/s390/include/asm/tlb.h linux-4.4.111-vs2.3.9.5/arch/s390/include/asm/tlb.h
f19bd705 535--- linux-4.4.111/arch/s390/include/asm/tlb.h 2015-07-06 20:41:37.000000000 +0000
8de2f54c 536+++ linux-4.4.111-vs2.3.9.5/arch/s390/include/asm/tlb.h 2018-01-09 16:36:21.000000000 +0000
dd5f3080 537@@ -24,6 +24,7 @@
0411181d 538 #include <linux/mm.h>
d33d7b00 539 #include <linux/pagemap.h>
0411181d 540 #include <linux/swap.h>
0411181d
AM
541+
542 #include <asm/processor.h>
543 #include <asm/pgalloc.h>
763640ca 544 #include <asm/tlbflush.h>
8de2f54c 545diff -NurpP --minimal linux-4.4.111/arch/s390/include/uapi/asm/unistd.h linux-4.4.111-vs2.3.9.5/arch/s390/include/uapi/asm/unistd.h
f19bd705 546--- linux-4.4.111/arch/s390/include/uapi/asm/unistd.h 2016-07-05 04:14:30.000000000 +0000
8de2f54c 547+++ linux-4.4.111-vs2.3.9.5/arch/s390/include/uapi/asm/unistd.h 2018-01-09 16:48:33.000000000 +0000
92598135 548@@ -200,7 +200,7 @@
927ca606
AM
549 #define __NR_clock_gettime 260
550 #define __NR_clock_getres 261
551 #define __NR_clock_nanosleep 262
0411181d
AM
552-/* Number 263 is reserved for vserver */
553+#define __NR_vserver 263
554 #define __NR_statfs64 265
555 #define __NR_fstatfs64 266
556 #define __NR_remap_file_pages 267
8de2f54c 557diff -NurpP --minimal linux-4.4.111/arch/s390/kernel/ptrace.c linux-4.4.111-vs2.3.9.5/arch/s390/kernel/ptrace.c
f19bd705 558--- linux-4.4.111/arch/s390/kernel/ptrace.c 2018-01-11 07:57:07.000000000 +0000
8de2f54c 559+++ linux-4.4.111-vs2.3.9.5/arch/s390/kernel/ptrace.c 2018-01-09 16:36:21.000000000 +0000
db55b927 560@@ -21,6 +21,7 @@
ec22aa5c
AM
561 #include <linux/tracehook.h>
562 #include <linux/seccomp.h>
969f5c41 563 #include <linux/compat.h>
db55b927 564+#include <linux/vs_base.h>
ec22aa5c 565 #include <trace/syscall.h>
d337f35e 566 #include <asm/segment.h>
db55b927 567 #include <asm/page.h>
8de2f54c 568diff -NurpP --minimal linux-4.4.111/arch/s390/kernel/syscalls.S linux-4.4.111-vs2.3.9.5/arch/s390/kernel/syscalls.S
f19bd705 569--- linux-4.4.111/arch/s390/kernel/syscalls.S 2018-01-11 07:57:07.000000000 +0000
8de2f54c 570+++ linux-4.4.111-vs2.3.9.5/arch/s390/kernel/syscalls.S 2018-01-09 16:36:21.000000000 +0000
927ca606
AM
571@@ -271,7 +271,7 @@ SYSCALL(sys_clock_settime,compat_sys_clo
572 SYSCALL(sys_clock_gettime,compat_sys_clock_gettime) /* 260 */
573 SYSCALL(sys_clock_getres,compat_sys_clock_getres)
574 SYSCALL(sys_clock_nanosleep,compat_sys_clock_nanosleep)
575-NI_SYSCALL /* reserved for vserver */
d337f35e 576+SYSCALL(sys_vserver,sys_vserver,sys32_vserver)
927ca606
AM
577 SYSCALL(sys_ni_syscall,compat_sys_s390_fadvise64_64)
578 SYSCALL(sys_statfs64,compat_sys_statfs64)
579 SYSCALL(sys_fstatfs64,compat_sys_fstatfs64)
8de2f54c 580diff -NurpP --minimal linux-4.4.111/arch/sh/Kconfig linux-4.4.111-vs2.3.9.5/arch/sh/Kconfig
f19bd705 581--- linux-4.4.111/arch/sh/Kconfig 2016-07-05 04:11:46.000000000 +0000
8de2f54c 582+++ linux-4.4.111-vs2.3.9.5/arch/sh/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 583@@ -883,6 +883,8 @@ source "fs/Kconfig"
d337f35e
JR
584
585 source "arch/sh/Kconfig.debug"
586
587+source "kernel/vserver/Kconfig"
588+
589 source "security/Kconfig"
590
591 source "crypto/Kconfig"
8de2f54c 592diff -NurpP --minimal linux-4.4.111/arch/sh/kernel/irq.c linux-4.4.111-vs2.3.9.5/arch/sh/kernel/irq.c
f19bd705 593--- linux-4.4.111/arch/sh/kernel/irq.c 2016-07-05 04:11:46.000000000 +0000
8de2f54c 594+++ linux-4.4.111-vs2.3.9.5/arch/sh/kernel/irq.c 2018-01-09 16:36:21.000000000 +0000
f86f0b53 595@@ -14,6 +14,7 @@
7e46296a 596 #include <linux/ftrace.h>
76514441 597 #include <linux/delay.h>
763640ca 598 #include <linux/ratelimit.h>
f86f0b53 599+// #include <linux/vs_context.h>
d337f35e 600 #include <asm/processor.h>
2380c486 601 #include <asm/machvec.h>
f86f0b53 602 #include <asm/uaccess.h>
8de2f54c 603diff -NurpP --minimal linux-4.4.111/arch/sparc/Kconfig linux-4.4.111-vs2.3.9.5/arch/sparc/Kconfig
f19bd705 604--- linux-4.4.111/arch/sparc/Kconfig 2018-01-11 07:57:07.000000000 +0000
8de2f54c 605+++ linux-4.4.111-vs2.3.9.5/arch/sparc/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 606@@ -561,6 +561,8 @@ source "fs/Kconfig"
d33d7b00
AM
607
608 source "arch/sparc/Kconfig.debug"
609
610+source "kernel/vserver/Kconfig"
611+
612 source "security/Kconfig"
613
614 source "crypto/Kconfig"
8de2f54c 615diff -NurpP --minimal linux-4.4.111/arch/sparc/include/uapi/asm/unistd.h linux-4.4.111-vs2.3.9.5/arch/sparc/include/uapi/asm/unistd.h
f19bd705 616--- linux-4.4.111/arch/sparc/include/uapi/asm/unistd.h 2016-07-05 04:14:33.000000000 +0000
8de2f54c 617+++ linux-4.4.111-vs2.3.9.5/arch/sparc/include/uapi/asm/unistd.h 2018-01-09 16:36:21.000000000 +0000
537831f9 618@@ -332,7 +332,7 @@
ec22aa5c
AM
619 #define __NR_timer_getoverrun 264
620 #define __NR_timer_delete 265
621 #define __NR_timer_create 266
622-/* #define __NR_vserver 267 Reserved for VSERVER */
623+#define __NR_vserver 267
624 #define __NR_io_setup 268
625 #define __NR_io_destroy 269
626 #define __NR_io_submit 270
8de2f54c 627diff -NurpP --minimal linux-4.4.111/arch/sparc/kernel/systbls_32.S linux-4.4.111-vs2.3.9.5/arch/sparc/kernel/systbls_32.S
f19bd705 628--- linux-4.4.111/arch/sparc/kernel/systbls_32.S 2016-07-05 04:14:33.000000000 +0000
8de2f54c 629+++ linux-4.4.111-vs2.3.9.5/arch/sparc/kernel/systbls_32.S 2018-01-09 16:36:21.000000000 +0000
50e68740 630@@ -70,7 +70,7 @@ sys_call_table:
a168f21d 631 /*250*/ .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_ni_syscall
50e68740
JR
632 /*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
633 /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
634-/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
635+/*265*/ .long sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
636 /*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
637 /*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
638 /*280*/ .long sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
8de2f54c 639diff -NurpP --minimal linux-4.4.111/arch/sparc/kernel/systbls_64.S linux-4.4.111-vs2.3.9.5/arch/sparc/kernel/systbls_64.S
f19bd705 640--- linux-4.4.111/arch/sparc/kernel/systbls_64.S 2016-07-05 04:14:33.000000000 +0000
8de2f54c 641+++ linux-4.4.111-vs2.3.9.5/arch/sparc/kernel/systbls_64.S 2018-01-09 16:36:21.000000000 +0000
50e68740 642@@ -71,7 +71,7 @@ sys_call_table32:
b00e13aa 643 /*250*/ .word sys_mremap, compat_sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall
50e68740
JR
644 .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
645 /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun
646- .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
647+ .word sys_timer_delete, compat_sys_timer_create, sys32_vserver, compat_sys_io_setup, sys_io_destroy
648 /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
649 .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
b00e13aa 650 /*280*/ .word sys_tee, sys_add_key, sys_request_key, compat_sys_keyctl, compat_sys_openat
927ca606 651@@ -152,7 +152,7 @@ sys_call_table:
a168f21d 652 /*250*/ .word sys_64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall
50e68740
JR
653 .word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
654 /*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
655- .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
656+ .word sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
657 /*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
658 .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
659 /*280*/ .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
8de2f54c 660diff -NurpP --minimal linux-4.4.111/arch/um/Kconfig.rest linux-4.4.111-vs2.3.9.5/arch/um/Kconfig.rest
f19bd705 661--- linux-4.4.111/arch/um/Kconfig.rest 2015-04-12 22:12:50.000000000 +0000
8de2f54c 662+++ linux-4.4.111-vs2.3.9.5/arch/um/Kconfig.rest 2018-01-09 16:36:21.000000000 +0000
f6c5ef8b 663@@ -12,6 +12,8 @@ source "arch/um/Kconfig.net"
d33d7b00
AM
664
665 source "fs/Kconfig"
666
667+source "kernel/vserver/Kconfig"
668+
669 source "security/Kconfig"
670
671 source "crypto/Kconfig"
8de2f54c 672diff -NurpP --minimal linux-4.4.111/arch/x86/Kconfig linux-4.4.111-vs2.3.9.5/arch/x86/Kconfig
f19bd705 673--- linux-4.4.111/arch/x86/Kconfig 2018-01-11 07:57:08.000000000 +0000
8de2f54c 674+++ linux-4.4.111-vs2.3.9.5/arch/x86/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 675@@ -2672,6 +2672,8 @@ source "fs/Kconfig"
e03b8c3c 676
d33d7b00 677 source "arch/x86/Kconfig.debug"
e03b8c3c
AM
678
679+source "kernel/vserver/Kconfig"
680+
681 source "security/Kconfig"
682
683 source "crypto/Kconfig"
8de2f54c 684diff -NurpP --minimal linux-4.4.111/arch/x86/entry/syscalls/syscall_32.tbl linux-4.4.111-vs2.3.9.5/arch/x86/entry/syscalls/syscall_32.tbl
f19bd705 685--- linux-4.4.111/arch/x86/entry/syscalls/syscall_32.tbl 2018-01-11 07:57:08.000000000 +0000
8de2f54c 686+++ linux-4.4.111-vs2.3.9.5/arch/x86/entry/syscalls/syscall_32.tbl 2018-01-10 01:51:14.000000000 +0000
db55b927
AM
687@@ -279,7 +279,7 @@
688 270 i386 tgkill sys_tgkill
689 271 i386 utimes sys_utimes compat_sys_utimes
690 272 i386 fadvise64_64 sys_fadvise64_64 sys32_fadvise64_64
691-273 i386 vserver
692+273 i386 vserver sys_vserver sys32_vserver
693 274 i386 mbind sys_mbind
694 275 i386 get_mempolicy sys_get_mempolicy compat_sys_get_mempolicy
695 276 i386 set_mempolicy sys_set_mempolicy
8de2f54c 696diff -NurpP --minimal linux-4.4.111/arch/x86/entry/syscalls/syscall_64.tbl linux-4.4.111-vs2.3.9.5/arch/x86/entry/syscalls/syscall_64.tbl
f19bd705 697--- linux-4.4.111/arch/x86/entry/syscalls/syscall_64.tbl 2016-07-05 04:14:33.000000000 +0000
8de2f54c 698+++ linux-4.4.111-vs2.3.9.5/arch/x86/entry/syscalls/syscall_64.tbl 2018-01-10 01:51:32.000000000 +0000
db55b927 699@@ -242,7 +242,7 @@
1e8b8f9b
AM
700 233 common epoll_ctl sys_epoll_ctl
701 234 common tgkill sys_tgkill
702 235 common utimes sys_utimes
db55b927
AM
703-236 64 vserver
704+236 64 vserver sys_vserver
1e8b8f9b
AM
705 237 common mbind sys_mbind
706 238 common set_mempolicy sys_set_mempolicy
707 239 common get_mempolicy sys_get_mempolicy
8de2f54c 708diff -NurpP --minimal linux-4.4.111/block/ioprio.c linux-4.4.111-vs2.3.9.5/block/ioprio.c
f19bd705 709--- linux-4.4.111/block/ioprio.c 2018-01-11 07:57:12.000000000 +0000
8de2f54c 710+++ linux-4.4.111-vs2.3.9.5/block/ioprio.c 2018-01-09 16:36:23.000000000 +0000
bb20add7
AM
711@@ -28,6 +28,7 @@
712 #include <linux/syscalls.h>
713 #include <linux/security.h>
714 #include <linux/pid_namespace.h>
715+#include <linux/vs_base.h>
716
717 int set_task_ioprio(struct task_struct *task, int ioprio)
718 {
719@@ -105,6 +106,8 @@ SYSCALL_DEFINE3(ioprio_set, int, which,
720 else
721 pgrp = find_vpid(who);
722 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
723+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
724+ continue;
725 ret = set_task_ioprio(p, ioprio);
726 if (ret)
727 break;
927ca606 728@@ -203,6 +206,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which,
bb20add7
AM
729 else
730 pgrp = find_vpid(who);
731 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
732+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
733+ continue;
734 tmpio = get_task_ioprio(p);
735 if (tmpio < 0)
736 continue;
8de2f54c 737diff -NurpP --minimal linux-4.4.111/drivers/block/Kconfig linux-4.4.111-vs2.3.9.5/drivers/block/Kconfig
f19bd705 738--- linux-4.4.111/drivers/block/Kconfig 2016-07-05 04:14:35.000000000 +0000
8de2f54c 739+++ linux-4.4.111-vs2.3.9.5/drivers/block/Kconfig 2018-01-09 16:36:23.000000000 +0000
bb20add7 740@@ -283,6 +283,13 @@ config BLK_DEV_CRYPTOLOOP
2bf5ad28
AM
741
742 source "drivers/block/drbd/Kconfig"
d337f35e
JR
743
744+config BLK_DEV_VROOT
745+ tristate "Virtual Root device support"
746+ depends on QUOTACTL
747+ ---help---
748+ Saying Y here will allow you to use quota/fs ioctls on a shared
749+ partition within a virtual server without compromising security.
750+
751 config BLK_DEV_NBD
752 tristate "Network block device support"
753 depends on NET
8de2f54c 754diff -NurpP --minimal linux-4.4.111/drivers/block/Makefile linux-4.4.111-vs2.3.9.5/drivers/block/Makefile
f19bd705 755--- linux-4.4.111/drivers/block/Makefile 2016-07-05 04:14:35.000000000 +0000
8de2f54c 756+++ linux-4.4.111-vs2.3.9.5/drivers/block/Makefile 2018-01-09 16:36:23.000000000 +0000
927ca606 757@@ -32,6 +32,7 @@ obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o
bb20add7 758
d33d7b00 759 obj-$(CONFIG_BLK_DEV_SX8) += sx8.o
d33d7b00
AM
760 obj-$(CONFIG_BLK_DEV_HD) += hd.o
761+obj-$(CONFIG_BLK_DEV_VROOT) += vroot.o
762
763 obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o
763640ca 764 obj-$(CONFIG_XEN_BLKDEV_BACKEND) += xen-blkback/
8de2f54c 765diff -NurpP --minimal linux-4.4.111/drivers/block/loop.c linux-4.4.111-vs2.3.9.5/drivers/block/loop.c
f19bd705 766--- linux-4.4.111/drivers/block/loop.c 2018-01-11 07:57:13.000000000 +0000
8de2f54c 767+++ linux-4.4.111-vs2.3.9.5/drivers/block/loop.c 2018-01-09 23:00:25.000000000 +0000
927ca606 768@@ -76,6 +76,7 @@
a168f21d 769 #include <linux/miscdevice.h>
f6c5ef8b 770 #include <linux/falloc.h>
927ca606 771 #include <linux/uio.h>
d337f35e 772+#include <linux/vs_context.h>
c2e5f7c8 773 #include "loop.h"
f6c5ef8b 774
d337f35e 775 #include <asm/uaccess.h>
927ca606 776@@ -935,6 +936,7 @@ static int loop_set_fd(struct loop_devic
d337f35e
JR
777 lo->lo_blocksize = lo_blocksize;
778 lo->lo_device = bdev;
779 lo->lo_flags = lo_flags;
780+ lo->lo_xid = vx_current_xid();
781 lo->lo_backing_file = file;
927ca606 782 lo->transfer = NULL;
d337f35e 783 lo->ioctl = NULL;
927ca606
AM
784@@ -1055,6 +1057,7 @@ static int loop_clr_fd(struct loop_devic
785 lo->lo_offset = 0;
f6c5ef8b 786 lo->lo_sizelimit = 0;
2380c486 787 lo->lo_encrypt_key_size = 0;
2380c486
JR
788+ lo->lo_xid = 0;
789 memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
790 memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
791 memset(lo->lo_file_name, 0, LO_NAME_SIZE);
927ca606 792@@ -1101,7 +1104,7 @@ loop_set_status(struct loop_device *lo,
2380c486 793
ec22aa5c 794 if (lo->lo_encrypt_key_size &&
537831f9 795 !uid_eq(lo->lo_key_owner, uid) &&
d337f35e
JR
796- !capable(CAP_SYS_ADMIN))
797+ !vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP))
798 return -EPERM;
799 if (lo->lo_state != Lo_bound)
800 return -ENXIO;
927ca606 801@@ -1202,7 +1205,8 @@ loop_get_status(struct loop_device *lo,
d337f35e
JR
802 memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE);
803 info->lo_encrypt_type =
804 lo->lo_encryption ? lo->lo_encryption->number : 0;
805- if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
806+ if (lo->lo_encrypt_key_size &&
807+ vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP)) {
808 info->lo_encrypt_key_size = lo->lo_encrypt_key_size;
809 memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
810 lo->lo_encrypt_key_size);
927ca606 811@@ -1563,6 +1567,11 @@ static int lo_open(struct block_device *
a168f21d
AM
812 goto out;
813 }
d337f35e 814
dd5f3080 815+ if (!vx_check(lo->lo_xid, VS_IDENT|VS_HOSTID|VS_ADMIN_P)) {
816+ err = -EACCES;
817+ goto out;
818+ }
d337f35e 819+
927ca606
AM
820 atomic_inc(&lo->lo_refcnt);
821 out:
822 mutex_unlock(&loop_index_mutex);
8de2f54c 823diff -NurpP --minimal linux-4.4.111/drivers/block/loop.h linux-4.4.111-vs2.3.9.5/drivers/block/loop.h
f19bd705 824--- linux-4.4.111/drivers/block/loop.h 2016-07-05 04:14:35.000000000 +0000
8de2f54c 825+++ linux-4.4.111-vs2.3.9.5/drivers/block/loop.h 2018-01-09 16:36:23.000000000 +0000
927ca606 826@@ -43,6 +43,7 @@ struct loop_device {
c2e5f7c8
JR
827 struct loop_func_table *lo_encryption;
828 __u32 lo_init[2];
829 kuid_t lo_key_owner; /* Who set the key */
830+ vxid_t lo_xid;
831 int (*ioctl)(struct loop_device *, int cmd,
832 unsigned long arg);
833
8de2f54c 834diff -NurpP --minimal linux-4.4.111/drivers/block/vroot.c linux-4.4.111-vs2.3.9.5/drivers/block/vroot.c
f19bd705 835--- linux-4.4.111/drivers/block/vroot.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 836+++ linux-4.4.111-vs2.3.9.5/drivers/block/vroot.c 2018-01-11 07:37:22.000000000 +0000
f19bd705 837@@ -0,0 +1,291 @@
d337f35e
JR
838+/*
839+ * linux/drivers/block/vroot.c
840+ *
927ca606
AM
841+ * written by Herbert P?tzl, 9/11/2002
842+ * ported to 2.6.10 by Herbert P?tzl, 30/12/2004
d337f35e
JR
843+ *
844+ * based on the loop.c code by Theodore Ts'o.
845+ *
927ca606 846+ * Copyright (C) 2002-2007 by Herbert P?tzl.
d337f35e
JR
847+ * Redistribution of this file is permitted under the
848+ * GNU General Public License.
849+ *
850+ */
851+
852+#include <linux/module.h>
853+#include <linux/moduleparam.h>
854+#include <linux/file.h>
855+#include <linux/major.h>
856+#include <linux/blkdev.h>
76514441 857+#include <linux/slab.h>
d337f35e
JR
858+
859+#include <linux/vroot.h>
860+#include <linux/vs_context.h>
861+
862+
863+static int max_vroot = 8;
864+
865+static struct vroot_device *vroot_dev;
866+static struct gendisk **disks;
867+
868+
869+static int vroot_set_dev(
870+ struct vroot_device *vr,
d337f35e
JR
871+ struct block_device *bdev,
872+ unsigned int arg)
873+{
874+ struct block_device *real_bdev;
875+ struct file *file;
876+ struct inode *inode;
877+ int error;
878+
879+ error = -EBUSY;
880+ if (vr->vr_state != Vr_unbound)
881+ goto out;
882+
883+ error = -EBADF;
884+ file = fget(arg);
885+ if (!file)
886+ goto out;
887+
888+ error = -EINVAL;
927ca606 889+ inode = file->f_path.dentry->d_inode;
d337f35e
JR
890+
891+
892+ if (S_ISBLK(inode->i_mode)) {
893+ real_bdev = inode->i_bdev;
894+ vr->vr_device = real_bdev;
895+ __iget(real_bdev->bd_inode);
896+ } else
897+ goto out_fput;
898+
899+ vxdprintk(VXD_CBIT(misc, 0),
900+ "vroot[%d]_set_dev: dev=" VXF_DEV,
901+ vr->vr_number, VXD_DEV(real_bdev));
902+
903+ vr->vr_state = Vr_bound;
904+ error = 0;
905+
906+ out_fput:
907+ fput(file);
908+ out:
909+ return error;
910+}
911+
912+static int vroot_clr_dev(
913+ struct vroot_device *vr,
d337f35e
JR
914+ struct block_device *bdev)
915+{
916+ struct block_device *real_bdev;
917+
918+ if (vr->vr_state != Vr_bound)
919+ return -ENXIO;
920+ if (vr->vr_refcnt > 1) /* we needed one fd for the ioctl */
921+ return -EBUSY;
922+
923+ real_bdev = vr->vr_device;
924+
925+ vxdprintk(VXD_CBIT(misc, 0),
926+ "vroot[%d]_clr_dev: dev=" VXF_DEV,
927+ vr->vr_number, VXD_DEV(real_bdev));
928+
929+ bdput(real_bdev);
930+ vr->vr_state = Vr_unbound;
931+ vr->vr_device = NULL;
932+ return 0;
933+}
934+
935+
ec22aa5c 936+static int vr_ioctl(struct block_device *bdev, fmode_t mode,
d337f35e
JR
937+ unsigned int cmd, unsigned long arg)
938+{
ec22aa5c 939+ struct vroot_device *vr = bdev->bd_disk->private_data;
d337f35e
JR
940+ int err;
941+
942+ down(&vr->vr_ctl_mutex);
943+ switch (cmd) {
944+ case VROOT_SET_DEV:
ec22aa5c 945+ err = vroot_set_dev(vr, bdev, arg);
d337f35e
JR
946+ break;
947+ case VROOT_CLR_DEV:
ec22aa5c 948+ err = vroot_clr_dev(vr, bdev);
d337f35e
JR
949+ break;
950+ default:
951+ err = -EINVAL;
952+ break;
953+ }
954+ up(&vr->vr_ctl_mutex);
955+ return err;
956+}
957+
ec22aa5c 958+static int vr_open(struct block_device *bdev, fmode_t mode)
d337f35e 959+{
ec22aa5c 960+ struct vroot_device *vr = bdev->bd_disk->private_data;
d337f35e
JR
961+
962+ down(&vr->vr_ctl_mutex);
963+ vr->vr_refcnt++;
964+ up(&vr->vr_ctl_mutex);
965+ return 0;
966+}
967+
09be7631 968+static void vr_release(struct gendisk *disk, fmode_t mode)
d337f35e 969+{
ec22aa5c 970+ struct vroot_device *vr = disk->private_data;
d337f35e
JR
971+
972+ down(&vr->vr_ctl_mutex);
973+ --vr->vr_refcnt;
974+ up(&vr->vr_ctl_mutex);
d337f35e
JR
975+}
976+
977+static struct block_device_operations vr_fops = {
978+ .owner = THIS_MODULE,
979+ .open = vr_open,
980+ .release = vr_release,
981+ .ioctl = vr_ioctl,
982+};
983+
f19bd705 984+static blk_qc_t vroot_make_request(struct request_queue *q, struct bio *bio)
b3b0d4fd
AM
985+{
986+ printk("vroot_make_request %p, %p\n", q, bio);
987+ bio_io_error(bio);
f19bd705 988+ return BLK_QC_T_NONE;
b3b0d4fd
AM
989+}
990+
d337f35e
JR
991+struct block_device *__vroot_get_real_bdev(struct block_device *bdev)
992+{
993+ struct inode *inode = bdev->bd_inode;
994+ struct vroot_device *vr;
995+ struct block_device *real_bdev;
996+ int minor = iminor(inode);
997+
998+ vr = &vroot_dev[minor];
999+ real_bdev = vr->vr_device;
1000+
1001+ vxdprintk(VXD_CBIT(misc, 0),
1002+ "vroot[%d]_get_real_bdev: dev=" VXF_DEV,
1003+ vr->vr_number, VXD_DEV(real_bdev));
1004+
1005+ if (vr->vr_state != Vr_bound)
1006+ return ERR_PTR(-ENXIO);
1007+
1008+ __iget(real_bdev->bd_inode);
1009+ return real_bdev;
1010+}
1011+
b3b0d4fd
AM
1012+
1013+
d337f35e
JR
1014+/*
1015+ * And now the modules code and kernel interface.
1016+ */
1017+
1018+module_param(max_vroot, int, 0);
1019+
1020+MODULE_PARM_DESC(max_vroot, "Maximum number of vroot devices (1-256)");
1021+MODULE_LICENSE("GPL");
1022+MODULE_ALIAS_BLOCKDEV_MAJOR(VROOT_MAJOR);
1023+
927ca606 1024+MODULE_AUTHOR ("Herbert P?tzl");
d337f35e
JR
1025+MODULE_DESCRIPTION ("Virtual Root Device Mapper");
1026+
1027+
1028+int __init vroot_init(void)
1029+{
1030+ int err, i;
1031+
1032+ if (max_vroot < 1 || max_vroot > 256) {
1033+ max_vroot = MAX_VROOT_DEFAULT;
1034+ printk(KERN_WARNING "vroot: invalid max_vroot "
1035+ "(must be between 1 and 256), "
1036+ "using default (%d)\n", max_vroot);
1037+ }
1038+
1039+ if (register_blkdev(VROOT_MAJOR, "vroot"))
1040+ return -EIO;
1041+
1042+ err = -ENOMEM;
1043+ vroot_dev = kmalloc(max_vroot * sizeof(struct vroot_device), GFP_KERNEL);
1044+ if (!vroot_dev)
1045+ goto out_mem1;
1046+ memset(vroot_dev, 0, max_vroot * sizeof(struct vroot_device));
1047+
1048+ disks = kmalloc(max_vroot * sizeof(struct gendisk *), GFP_KERNEL);
1049+ if (!disks)
1050+ goto out_mem2;
1051+
1052+ for (i = 0; i < max_vroot; i++) {
1053+ disks[i] = alloc_disk(1);
1054+ if (!disks[i])
1055+ goto out_mem3;
2380c486
JR
1056+ disks[i]->queue = blk_alloc_queue(GFP_KERNEL);
1057+ if (!disks[i]->queue)
1058+ goto out_mem3;
b3b0d4fd 1059+ blk_queue_make_request(disks[i]->queue, vroot_make_request);
d337f35e
JR
1060+ }
1061+
1062+ for (i = 0; i < max_vroot; i++) {
1063+ struct vroot_device *vr = &vroot_dev[i];
1064+ struct gendisk *disk = disks[i];
1065+
1066+ memset(vr, 0, sizeof(*vr));
5a9fc8e8 1067+ sema_init(&vr->vr_ctl_mutex, 1);
d337f35e
JR
1068+ vr->vr_number = i;
1069+ disk->major = VROOT_MAJOR;
1070+ disk->first_minor = i;
1071+ disk->fops = &vr_fops;
1072+ sprintf(disk->disk_name, "vroot%d", i);
1073+ disk->private_data = vr;
1074+ }
1075+
1076+ err = register_vroot_grb(&__vroot_get_real_bdev);
1077+ if (err)
1078+ goto out_mem3;
1079+
1080+ for (i = 0; i < max_vroot; i++)
1081+ add_disk(disks[i]);
1082+ printk(KERN_INFO "vroot: loaded (max %d devices)\n", max_vroot);
1083+ return 0;
1084+
1085+out_mem3:
1086+ while (i--)
1087+ put_disk(disks[i]);
1088+ kfree(disks);
1089+out_mem2:
1090+ kfree(vroot_dev);
1091+out_mem1:
1092+ unregister_blkdev(VROOT_MAJOR, "vroot");
1093+ printk(KERN_ERR "vroot: ran out of memory\n");
1094+ return err;
1095+}
1096+
1097+void vroot_exit(void)
1098+{
1099+ int i;
1100+
1101+ if (unregister_vroot_grb(&__vroot_get_real_bdev))
1102+ printk(KERN_WARNING "vroot: cannot unregister grb\n");
1103+
1104+ for (i = 0; i < max_vroot; i++) {
1105+ del_gendisk(disks[i]);
1106+ put_disk(disks[i]);
1107+ }
2380c486 1108+ unregister_blkdev(VROOT_MAJOR, "vroot");
d337f35e
JR
1109+
1110+ kfree(disks);
1111+ kfree(vroot_dev);
1112+}
1113+
1114+module_init(vroot_init);
1115+module_exit(vroot_exit);
1116+
1117+#ifndef MODULE
1118+
1119+static int __init max_vroot_setup(char *str)
1120+{
1121+ max_vroot = simple_strtol(str, NULL, 0);
1122+ return 1;
1123+}
1124+
1125+__setup("max_vroot=", max_vroot_setup);
1126+
1127+#endif
1128+
8de2f54c 1129diff -NurpP --minimal linux-4.4.111/drivers/infiniband/core/addr.c linux-4.4.111-vs2.3.9.5/drivers/infiniband/core/addr.c
f19bd705 1130--- linux-4.4.111/drivers/infiniband/core/addr.c 2018-01-11 07:57:21.000000000 +0000
8de2f54c 1131+++ linux-4.4.111-vs2.3.9.5/drivers/infiniband/core/addr.c 2018-01-09 16:49:06.000000000 +0000
927ca606 1132@@ -283,7 +283,7 @@ static int addr6_resolve(struct sockaddr
5dd10c98 1133
763640ca 1134 if (ipv6_addr_any(&fl6.saddr)) {
927ca606 1135 ret = ipv6_dev_get_saddr(addr->net, ip6_dst_idev(dst)->dev,
763640ca
JR
1136- &fl6.daddr, 0, &fl6.saddr);
1137+ &fl6.daddr, 0, &fl6.saddr, NULL);
5dd10c98
AM
1138 if (ret)
1139 goto put;
1140
8de2f54c 1141diff -NurpP --minimal linux-4.4.111/drivers/md/dm-ioctl.c linux-4.4.111-vs2.3.9.5/drivers/md/dm-ioctl.c
f19bd705 1142--- linux-4.4.111/drivers/md/dm-ioctl.c 2018-01-11 07:57:23.000000000 +0000
8de2f54c 1143+++ linux-4.4.111-vs2.3.9.5/drivers/md/dm-ioctl.c 2018-01-09 16:36:23.000000000 +0000
3bac966d
AM
1144@@ -16,6 +16,7 @@
1145 #include <linux/dm-ioctl.h>
1146 #include <linux/hdreg.h>
1147 #include <linux/compat.h>
1148+#include <linux/vs_context.h>
1149
1150 #include <asm/uaccess.h>
1151
c2e5f7c8 1152@@ -114,7 +115,8 @@ static struct hash_cell *__get_name_cell
3bac966d
AM
1153 unsigned int h = hash_str(str);
1154
1155 list_for_each_entry (hc, _name_buckets + h, name_list)
1156- if (!strcmp(hc->name, str)) {
1157+ if (vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT) &&
1158+ !strcmp(hc->name, str)) {
1159 dm_get(hc->md);
1160 return hc;
1161 }
c2e5f7c8 1162@@ -128,7 +130,8 @@ static struct hash_cell *__get_uuid_cell
3bac966d
AM
1163 unsigned int h = hash_str(str);
1164
1165 list_for_each_entry (hc, _uuid_buckets + h, uuid_list)
1166- if (!strcmp(hc->uuid, str)) {
1167+ if (vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT) &&
1168+ !strcmp(hc->uuid, str)) {
1169 dm_get(hc->md);
1170 return hc;
1171 }
c2e5f7c8 1172@@ -139,13 +142,15 @@ static struct hash_cell *__get_uuid_cell
a168f21d
AM
1173 static struct hash_cell *__get_dev_cell(uint64_t dev)
1174 {
1175 struct mapped_device *md;
1176- struct hash_cell *hc;
1177+ struct hash_cell *hc = NULL;
1178
1179 md = dm_get_md(huge_decode_dev(dev));
1180 if (!md)
1181 return NULL;
1182
1183- hc = dm_get_mdptr(md);
1184+ if (vx_check(dm_get_xid(md), VS_WATCH_P | VS_IDENT))
1185+ hc = dm_get_mdptr(md);
1186+
1187 if (!hc) {
1188 dm_put(md);
1189 return NULL;
c2e5f7c8 1190@@ -467,6 +472,9 @@ typedef int (*ioctl_fn)(struct dm_ioctl
3bac966d
AM
1191
1192 static int remove_all(struct dm_ioctl *param, size_t param_size)
1193 {
1194+ if (!vx_check(0, VS_ADMIN))
1195+ return -EPERM;
1196+
c2e5f7c8 1197 dm_hash_remove_all(true, !!(param->flags & DM_DEFERRED_REMOVE), false);
3bac966d
AM
1198 param->data_size = 0;
1199 return 0;
c2e5f7c8 1200@@ -514,6 +522,8 @@ static int list_devices(struct dm_ioctl
3bac966d
AM
1201 */
1202 for (i = 0; i < NUM_BUCKETS; i++) {
1203 list_for_each_entry (hc, _name_buckets + i, name_list) {
1204+ if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT))
1205+ continue;
1206 needed += sizeof(struct dm_name_list);
1207 needed += strlen(hc->name) + 1;
1208 needed += ALIGN_MASK;
c2e5f7c8 1209@@ -537,6 +547,8 @@ static int list_devices(struct dm_ioctl
3bac966d
AM
1210 */
1211 for (i = 0; i < NUM_BUCKETS; i++) {
1212 list_for_each_entry (hc, _name_buckets + i, name_list) {
1213+ if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT))
1214+ continue;
1215 if (old_nl)
1216 old_nl->next = (uint32_t) ((void *) nl -
1217 (void *) old_nl);
927ca606 1218@@ -1801,8 +1813,8 @@ static int ctl_ioctl(uint command, struc
763640ca 1219 size_t input_param_size;
b00e13aa 1220 struct dm_ioctl param_kernel;
3bac966d
AM
1221
1222- /* only root can play with this */
1223- if (!capable(CAP_SYS_ADMIN))
1224+ /* only root and certain contexts can play with this */
1225+ if (!vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_MAPPER))
1226 return -EACCES;
1227
1228 if (_IOC_TYPE(command) != DM_IOCTL)
8de2f54c 1229diff -NurpP --minimal linux-4.4.111/drivers/md/dm.c linux-4.4.111-vs2.3.9.5/drivers/md/dm.c
f19bd705 1230--- linux-4.4.111/drivers/md/dm.c 2018-01-11 07:57:23.000000000 +0000
8de2f54c 1231+++ linux-4.4.111-vs2.3.9.5/drivers/md/dm.c 2018-01-09 16:49:30.000000000 +0000
927ca606
AM
1232@@ -25,6 +25,7 @@
1233 #include <linux/elevator.h> /* for rq_end_sector() */
1234 #include <linux/blk-mq.h>
1235 #include <linux/pr.h>
d33d7b00
AM
1236+#include <linux/vs_base.h>
1237
1238 #include <trace/events/block.h>
1239
927ca606 1240@@ -144,6 +145,7 @@ struct mapped_device {
c2e5f7c8 1241 struct mutex suspend_lock;
d33d7b00
AM
1242 atomic_t holders;
1243 atomic_t open_count;
61333608 1244+ vxid_t xid;
d33d7b00 1245
c2e5f7c8
JR
1246 /*
1247 * The current mapping.
927ca606 1248@@ -445,6 +447,7 @@ int dm_deleting_md(struct mapped_device
d33d7b00
AM
1249 static int dm_blk_open(struct block_device *bdev, fmode_t mode)
1250 {
1251 struct mapped_device *md;
1252+ int ret = -ENXIO;
1253
1254 spin_lock(&_minor_lock);
1255
927ca606 1256@@ -453,17 +456,19 @@ static int dm_blk_open(struct block_devi
d33d7b00
AM
1257 goto out;
1258
1259 if (test_bit(DMF_FREEING, &md->flags) ||
1260- dm_deleting_md(md)) {
1261- md = NULL;
1262+ dm_deleting_md(md))
1263+ goto out;
1264+
1265+ ret = -EACCES;
1266+ if (!vx_check(md->xid, VS_IDENT|VS_HOSTID))
1267 goto out;
1268- }
1269
1270 dm_get(md);
1271 atomic_inc(&md->open_count);
d33d7b00
AM
1272+ ret = 0;
1273 out:
1274 spin_unlock(&_minor_lock);
1275-
1276- return md ? 0 : -ENXIO;
1277+ return ret;
1278 }
1279
09be7631 1280 static void dm_blk_close(struct gendisk *disk, fmode_t mode)
927ca606 1281@@ -909,6 +914,14 @@ int dm_set_geometry(struct mapped_device
d33d7b00
AM
1282 return 0;
1283 }
1284
1285+/*
1286+ * Get the xid associated with a dm device
1287+ */
61333608 1288+vxid_t dm_get_xid(struct mapped_device *md)
d33d7b00
AM
1289+{
1290+ return md->xid;
1291+}
1292+
1293 /*-----------------------------------------------------------------
1294 * CRUD START:
1295 * A more elegant soln is in the works that uses the queue
927ca606 1296@@ -2380,6 +2393,7 @@ static struct mapped_device *alloc_dev(i
bb20add7 1297 INIT_LIST_HEAD(&md->table_devices);
d33d7b00
AM
1298 spin_lock_init(&md->uevent_lock);
1299
1300+ md->xid = vx_current_xid();
1301 md->queue = blk_alloc_queue(GFP_KERNEL);
1302 if (!md->queue)
927ca606 1303 goto bad;
8de2f54c 1304diff -NurpP --minimal linux-4.4.111/drivers/md/dm.h linux-4.4.111-vs2.3.9.5/drivers/md/dm.h
f19bd705 1305--- linux-4.4.111/drivers/md/dm.h 2016-07-05 04:12:06.000000000 +0000
8de2f54c 1306+++ linux-4.4.111-vs2.3.9.5/drivers/md/dm.h 2018-01-09 16:36:24.000000000 +0000
927ca606 1307@@ -52,6 +52,8 @@ struct dm_dev_internal {
d33d7b00
AM
1308 struct dm_table;
1309 struct dm_md_mempools;
1310
61333608 1311+vxid_t dm_get_xid(struct mapped_device *md);
d33d7b00
AM
1312+
1313 /*-----------------------------------------------------------------
1314 * Internal table functions.
1315 *---------------------------------------------------------------*/
8de2f54c 1316diff -NurpP --minimal linux-4.4.111/drivers/net/tun.c linux-4.4.111-vs2.3.9.5/drivers/net/tun.c
f19bd705 1317--- linux-4.4.111/drivers/net/tun.c 2018-01-11 07:57:30.000000000 +0000
8de2f54c 1318+++ linux-4.4.111-vs2.3.9.5/drivers/net/tun.c 2018-01-09 16:36:24.000000000 +0000
c2e5f7c8 1319@@ -65,6 +65,7 @@
d33d7b00
AM
1320 #include <linux/nsproxy.h>
1321 #include <linux/virtio_net.h>
1322 #include <linux/rcupdate.h>
1323+#include <linux/vs_network.h>
1324 #include <net/net_namespace.h>
1325 #include <net/netns/generic.h>
927ca606
AM
1326 #include <net/rtnetlink.h>
1327@@ -181,6 +182,7 @@ struct tun_struct {
d33d7b00 1328 unsigned int flags;
537831f9
AM
1329 kuid_t owner;
1330 kgid_t group;
61333608 1331+ vnid_t nid;
d33d7b00
AM
1332
1333 struct net_device *dev;
db55b927 1334 netdev_features_t set_features;
927ca606 1335@@ -475,6 +477,7 @@ static inline bool tun_not_capable(struc
b00e13aa
AM
1336 return ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) ||
1337 (gid_valid(tun->group) && !in_egroup_p(tun->group))) &&
1338 !ns_capable(net->user_ns, CAP_NET_ADMIN);
1339+ /* !cap_raised(current_cap(), CAP_NET_ADMIN) */
1340 }
1341
1342 static void tun_set_real_num_queues(struct tun_struct *tun)
927ca606 1343@@ -1463,6 +1466,7 @@ static void tun_setup(struct net_device
2380c486 1344
537831f9
AM
1345 tun->owner = INVALID_UID;
1346 tun->group = INVALID_GID;
1347+ tun->nid = nx_current_nid();
2380c486 1348
ec22aa5c
AM
1349 dev->ethtool_ops = &tun_ethtool_ops;
1350 dev->destructor = tun_free_netdev;
927ca606 1351@@ -1657,7 +1661,7 @@ static int tun_set_iff(struct net *net,
b00e13aa
AM
1352 int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ?
1353 MAX_TAP_QUEUES : 1;
1354
1355- if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
c2e5f7c8 1356+ if (!nx_ns_capable(net->user_ns, CAP_NET_ADMIN, NXC_TUN_CREATE))
b00e13aa
AM
1357 return -EPERM;
1358 err = security_tun_dev_create();
1359 if (err < 0)
927ca606 1360@@ -2010,6 +2014,16 @@ static long __tun_chr_ioctl(struct file
537831f9 1361 from_kgid(&init_user_ns, tun->group));
2380c486 1362 break;
d337f35e 1363
2380c486
JR
1364+ case TUNSETNID:
1365+ if (!capable(CAP_CONTEXT))
1366+ return -EPERM;
d337f35e 1367+
2380c486 1368+ /* Set nid owner of the device */
61333608 1369+ tun->nid = (vnid_t) arg;
d337f35e 1370+
763640ca 1371+ tun_debug(KERN_INFO, tun, "nid owner set to %u\n", tun->nid);
2380c486 1372+ break;
d337f35e 1373+
2380c486
JR
1374 case TUNSETLINK:
1375 /* Only allow setting the type when the interface is down */
ec22aa5c 1376 if (tun->dev->flags & IFF_UP) {
8de2f54c 1377diff -NurpP --minimal linux-4.4.111/drivers/scsi/cxgbi/libcxgbi.c linux-4.4.111-vs2.3.9.5/drivers/scsi/cxgbi/libcxgbi.c
f19bd705 1378--- linux-4.4.111/drivers/scsi/cxgbi/libcxgbi.c 2015-10-29 09:21:24.000000000 +0000
8de2f54c 1379+++ linux-4.4.111-vs2.3.9.5/drivers/scsi/cxgbi/libcxgbi.c 2018-01-09 16:36:24.000000000 +0000
927ca606 1380@@ -768,7 +768,8 @@ static struct cxgbi_sock *cxgbi_check_ro
bb20add7
AM
1381 struct inet6_dev *idev = ip6_dst_idev((struct dst_entry *)rt);
1382
1383 err = ipv6_dev_get_saddr(&init_net, idev ? idev->dev : NULL,
1384- &daddr6->sin6_addr, 0, &pref_saddr);
1385+ &daddr6->sin6_addr, 0, &pref_saddr,
1386+ NULL);
1387 if (err) {
1388 pr_info("failed to get source address to reach %pI6\n",
1389 &daddr6->sin6_addr);
8de2f54c 1390diff -NurpP --minimal linux-4.4.111/drivers/tty/sysrq.c linux-4.4.111-vs2.3.9.5/drivers/tty/sysrq.c
f19bd705 1391--- linux-4.4.111/drivers/tty/sysrq.c 2018-01-11 07:57:38.000000000 +0000
8de2f54c 1392+++ linux-4.4.111-vs2.3.9.5/drivers/tty/sysrq.c 2018-01-09 16:36:24.000000000 +0000
bb20add7 1393@@ -47,6 +47,7 @@
c2e5f7c8
JR
1394 #include <linux/syscalls.h>
1395 #include <linux/of.h>
bb20add7 1396 #include <linux/rcupdate.h>
ab30d09f
AM
1397+#include <linux/vserver/debug.h>
1398
1399 #include <asm/ptrace.h>
1400 #include <asm/irq_regs.h>
927ca606 1401@@ -421,6 +422,21 @@ static struct sysrq_key_op sysrq_unrt_op
ab30d09f
AM
1402 .enable_mask = SYSRQ_ENABLE_RTNICE,
1403 };
1404
1405+
1406+#ifdef CONFIG_VSERVER_DEBUG
1407+static void sysrq_handle_vxinfo(int key)
1408+{
1409+ dump_vx_info_inactive((key == 'x') ? 0 : 1);
1410+}
1411+
1412+static struct sysrq_key_op sysrq_showvxinfo_op = {
1413+ .handler = sysrq_handle_vxinfo,
1414+ .help_msg = "conteXt",
1415+ .action_msg = "Show Context Info",
1416+ .enable_mask = SYSRQ_ENABLE_DUMP,
1417+};
1418+#endif
1419+
1420 /* Key Operations table and lock */
1421 static DEFINE_SPINLOCK(sysrq_key_table_lock);
1422
927ca606
AM
1423@@ -477,7 +493,11 @@ static struct sysrq_key_op *sysrq_key_ta
1424 /* x: May be registered on mips for TLB dump */
ab30d09f 1425 /* x: May be registered on ppc/powerpc for xmon */
537831f9 1426 /* x: May be registered on sparc64 for global PMU dump */
ab30d09f
AM
1427+#ifdef CONFIG_VSERVER_DEBUG
1428+ &sysrq_showvxinfo_op, /* x */
1429+#else
4bf69007 1430 NULL, /* x */
ab30d09f
AM
1431+#endif
1432 /* y: May be registered on sparc64 for global register dump */
1433 NULL, /* y */
1434 &sysrq_ftrace_dump_op, /* z */
927ca606 1435@@ -492,6 +512,8 @@ static int sysrq_key_table_key2index(int
ab30d09f
AM
1436 retval = key - '0';
1437 else if ((key >= 'a') && (key <= 'z'))
1438 retval = key + 10 - 'a';
1439+ else if ((key >= 'A') && (key <= 'Z'))
1440+ retval = key + 10 - 'A';
1441 else
1442 retval = -1;
1443 return retval;
8de2f54c 1444diff -NurpP --minimal linux-4.4.111/drivers/tty/tty_io.c linux-4.4.111-vs2.3.9.5/drivers/tty/tty_io.c
f19bd705 1445--- linux-4.4.111/drivers/tty/tty_io.c 2018-01-11 07:57:38.000000000 +0000
8de2f54c 1446+++ linux-4.4.111-vs2.3.9.5/drivers/tty/tty_io.c 2018-01-09 16:36:24.000000000 +0000
1e8b8f9b 1447@@ -104,6 +104,7 @@
ab30d09f
AM
1448
1449 #include <linux/kmod.h>
1450 #include <linux/nsproxy.h>
1451+#include <linux/vs_pid.h>
1452
1453 #undef TTY_DEBUG_HANGUP
927ca606
AM
1454 #ifdef TTY_DEBUG_HANGUP
1455@@ -2280,7 +2281,8 @@ static int tiocsti(struct tty_struct *tt
ab30d09f
AM
1456 char ch, mbz = 0;
1457 struct tty_ldisc *ld;
1458
1459- if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN))
1460+ if (((current->signal->tty != tty) &&
1461+ !vx_capable(CAP_SYS_ADMIN, VXC_TIOCSTI)))
1462 return -EPERM;
1463 if (get_user(ch, p))
1464 return -EFAULT;
927ca606 1465@@ -2593,6 +2595,7 @@ static int tiocspgrp(struct tty_struct *
ab30d09f
AM
1466 return -ENOTTY;
1467 if (get_user(pgrp_nr, p))
1468 return -EFAULT;
1469+ pgrp_nr = vx_rmap_pid(pgrp_nr);
1470 if (pgrp_nr < 0)
1471 return -EINVAL;
1472 rcu_read_lock();
8de2f54c 1473diff -NurpP --minimal linux-4.4.111/fs/attr.c linux-4.4.111-vs2.3.9.5/fs/attr.c
f19bd705 1474--- linux-4.4.111/fs/attr.c 2018-01-11 07:57:43.000000000 +0000
8de2f54c 1475+++ linux-4.4.111-vs2.3.9.5/fs/attr.c 2018-01-09 17:27:12.000000000 +0000
537831f9 1476@@ -15,6 +15,9 @@
d337f35e 1477 #include <linux/security.h>
f6c5ef8b 1478 #include <linux/evm.h>
537831f9 1479 #include <linux/ima.h>
d337f35e
JR
1480+#include <linux/proc_fs.h>
1481+#include <linux/devpts_fs.h>
2380c486 1482+#include <linux/vs_tag.h>
d337f35e 1483
93de0823
AM
1484 /**
1485 * inode_change_ok - check if attribute changes to an inode are allowed
b00e13aa 1486@@ -77,6 +80,10 @@ int inode_change_ok(const struct inode *
93de0823 1487 return -EPERM;
d337f35e 1488 }
93de0823
AM
1489
1490+ /* check for inode tag permission */
2380c486 1491+ if (dx_permission(inode, MAY_WRITE))
93de0823 1492+ return -EACCES;
2380c486 1493+
93de0823
AM
1494 return 0;
1495 }
1496 EXPORT_SYMBOL(inode_change_ok);
b00e13aa 1497@@ -147,6 +154,8 @@ void setattr_copy(struct inode *inode, c
d337f35e
JR
1498 inode->i_uid = attr->ia_uid;
1499 if (ia_valid & ATTR_GID)
1500 inode->i_gid = attr->ia_gid;
1501+ if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode))
1502+ inode->i_tag = attr->ia_tag;
1503 if (ia_valid & ATTR_ATIME)
1504 inode->i_atime = timespec_trunc(attr->ia_atime,
1505 inode->i_sb->s_time_gran);
c2e5f7c8 1506@@ -197,7 +206,8 @@ int notify_change(struct dentry * dentry
92598135
AM
1507
1508 WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));
78865d5b
AM
1509
1510- if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
1511+ if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
1512+ ATTR_TAG | ATTR_TIMES_SET)) {
1513 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1514 return -EPERM;
1515 }
8de2f54c 1516diff -NurpP --minimal linux-4.4.111/fs/block_dev.c linux-4.4.111-vs2.3.9.5/fs/block_dev.c
f19bd705 1517--- linux-4.4.111/fs/block_dev.c 2018-01-11 07:57:43.000000000 +0000
8de2f54c 1518+++ linux-4.4.111-vs2.3.9.5/fs/block_dev.c 2018-01-09 17:16:29.000000000 +0000
927ca606 1519@@ -29,6 +29,7 @@
2380c486 1520 #include <linux/log2.h>
db55b927 1521 #include <linux/cleancache.h>
927ca606 1522 #include <linux/dax.h>
2380c486
JR
1523+#include <linux/vs_device.h>
1524 #include <asm/uaccess.h>
1525 #include "internal.h"
1526
927ca606 1527@@ -645,6 +646,7 @@ struct block_device *bdget(dev_t dev)
2380c486
JR
1528 bdev->bd_invalidated = 0;
1529 inode->i_mode = S_IFBLK;
1530 inode->i_rdev = dev;
1531+ inode->i_mdev = dev;
1532 inode->i_bdev = bdev;
1533 inode->i_data.a_ops = &def_blk_aops;
1534 mapping_set_gfp_mask(&inode->i_data, GFP_USER);
927ca606 1535@@ -691,6 +693,11 @@ EXPORT_SYMBOL(bdput);
2380c486
JR
1536 static struct block_device *bd_acquire(struct inode *inode)
1537 {
1538 struct block_device *bdev;
1539+ dev_t mdev;
1540+
1541+ if (!vs_map_blkdev(inode->i_rdev, &mdev, DATTR_OPEN))
1542+ return NULL;
1543+ inode->i_mdev = mdev;
1544
1545 spin_lock(&bdev_lock);
1546 bdev = inode->i_bdev;
927ca606 1547@@ -701,7 +708,7 @@ static struct block_device *bd_acquire(s
2380c486
JR
1548 }
1549 spin_unlock(&bdev_lock);
1550
1551- bdev = bdget(inode->i_rdev);
1552+ bdev = bdget(mdev);
1553 if (bdev) {
1554 spin_lock(&bdev_lock);
1555 if (!inode->i_bdev) {
8de2f54c 1556diff -NurpP --minimal linux-4.4.111/fs/btrfs/ctree.h linux-4.4.111-vs2.3.9.5/fs/btrfs/ctree.h
f19bd705 1557--- linux-4.4.111/fs/btrfs/ctree.h 2018-01-11 07:57:43.000000000 +0000
8de2f54c 1558+++ linux-4.4.111-vs2.3.9.5/fs/btrfs/ctree.h 2018-01-09 16:36:24.000000000 +0000
927ca606 1559@@ -731,11 +731,14 @@ struct btrfs_inode_item {
e22b5178
AM
1560 /* modification sequence number for NFS */
1561 __le64 sequence;
1562
1563+ __le16 tag;
1564 /*
1565 * a little future expansion, for more than this we can
1566 * just grow the inode item and version it
1567 */
1568- __le64 reserved[4];
1569+ __le16 reserved16;
1570+ __le32 reserved32;
1571+ __le64 reserved[3];
1572 struct btrfs_timespec atime;
1573 struct btrfs_timespec ctime;
1574 struct btrfs_timespec mtime;
927ca606 1575@@ -2189,6 +2192,8 @@ struct btrfs_ioctl_defrag_range_args {
c2e5f7c8 1576 #define BTRFS_DEFAULT_COMMIT_INTERVAL (30)
bb20add7 1577 #define BTRFS_DEFAULT_MAX_INLINE (8192)
e22b5178
AM
1578
1579+#define BTRFS_MOUNT_TAGGED (1 << 24)
1580+
1581 #define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt)
1582 #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt)
b00e13aa 1583 #define btrfs_raw_test_opt(o, opt) ((o) & BTRFS_MOUNT_##opt)
927ca606 1584@@ -2528,6 +2533,7 @@ BTRFS_SETGET_FUNCS(inode_block_group, st
e22b5178
AM
1585 BTRFS_SETGET_FUNCS(inode_nlink, struct btrfs_inode_item, nlink, 32);
1586 BTRFS_SETGET_FUNCS(inode_uid, struct btrfs_inode_item, uid, 32);
1587 BTRFS_SETGET_FUNCS(inode_gid, struct btrfs_inode_item, gid, 32);
1588+BTRFS_SETGET_FUNCS(inode_tag, struct btrfs_inode_item, tag, 16);
1589 BTRFS_SETGET_FUNCS(inode_mode, struct btrfs_inode_item, mode, 32);
1590 BTRFS_SETGET_FUNCS(inode_rdev, struct btrfs_inode_item, rdev, 64);
1591 BTRFS_SETGET_FUNCS(inode_flags, struct btrfs_inode_item, flags, 64);
927ca606 1592@@ -2575,6 +2581,10 @@ BTRFS_SETGET_FUNCS(extent_flags, struct
78865d5b
AM
1593
1594 BTRFS_SETGET_FUNCS(extent_refs_v0, struct btrfs_extent_item_v0, refs, 32);
1595
1596+#define BTRFS_INODE_IXUNLINK (1 << 24)
1597+#define BTRFS_INODE_BARRIER (1 << 25)
1598+#define BTRFS_INODE_COW (1 << 26)
1599+
1600
1601 BTRFS_SETGET_FUNCS(tree_block_level, struct btrfs_tree_block_info, level, 8);
1602
927ca606 1603@@ -4022,6 +4032,7 @@ long btrfs_ioctl(struct file *file, unsi
d4263eb0
JR
1604 void btrfs_update_iflags(struct inode *inode);
1605 void btrfs_inherit_iflags(struct inode *inode, struct inode *dir);
c2e5f7c8 1606 int btrfs_is_empty_uuid(u8 *uuid);
d4263eb0 1607+int btrfs_sync_flags(struct inode *inode, int, int);
763640ca
JR
1608 int btrfs_defrag_file(struct inode *inode, struct file *file,
1609 struct btrfs_ioctl_defrag_range_args *range,
1610 u64 newer_than, unsigned long max_pages);
8de2f54c 1611diff -NurpP --minimal linux-4.4.111/fs/btrfs/disk-io.c linux-4.4.111-vs2.3.9.5/fs/btrfs/disk-io.c
f19bd705 1612--- linux-4.4.111/fs/btrfs/disk-io.c 2018-01-11 07:57:43.000000000 +0000
8de2f54c 1613+++ linux-4.4.111-vs2.3.9.5/fs/btrfs/disk-io.c 2018-01-09 16:36:24.000000000 +0000
927ca606 1614@@ -2736,6 +2736,9 @@ int open_ctree(struct super_block *sb,
763640ca 1615 goto fail_alloc;
e22b5178
AM
1616 }
1617
1618+ if (btrfs_test_opt(tree_root, TAGGED))
1619+ sb->s_flags |= MS_TAGGED;
1620+
1621 features = btrfs_super_incompat_flags(disk_super) &
1622 ~BTRFS_FEATURE_INCOMPAT_SUPP;
1623 if (features) {
8de2f54c 1624diff -NurpP --minimal linux-4.4.111/fs/btrfs/inode.c linux-4.4.111-vs2.3.9.5/fs/btrfs/inode.c
f19bd705 1625--- linux-4.4.111/fs/btrfs/inode.c 2018-01-11 07:57:43.000000000 +0000
8de2f54c 1626+++ linux-4.4.111-vs2.3.9.5/fs/btrfs/inode.c 2018-01-09 16:36:24.000000000 +0000
c2e5f7c8 1627@@ -43,6 +43,7 @@
b00e13aa 1628 #include <linux/blkdev.h>
c2e5f7c8 1629 #include <linux/posix_acl_xattr.h>
927ca606 1630 #include <linux/uio.h>
e22b5178 1631+#include <linux/vs_tag.h>
e22b5178
AM
1632 #include "ctree.h"
1633 #include "disk-io.h"
c2e5f7c8 1634 #include "transaction.h"
927ca606 1635@@ -3611,6 +3612,9 @@ static void btrfs_read_locked_inode(stru
bb20add7 1636 unsigned long ptr;
e22b5178 1637 int maybe_acls;
e22b5178 1638 u32 rdev;
a4a22af8
AM
1639+ kuid_t kuid;
1640+ kgid_t kgid;
1641+ ktag_t ktag;
e22b5178 1642 int ret;
763640ca 1643 bool filled = false;
bb20add7 1644 int first_xattr_slot;
927ca606 1645@@ -3638,8 +3642,14 @@ static void btrfs_read_locked_inode(stru
a168f21d 1646 struct btrfs_inode_item);
e22b5178 1647 inode->i_mode = btrfs_inode_mode(leaf, inode_item);
f6c5ef8b 1648 set_nlink(inode, btrfs_inode_nlink(leaf, inode_item));
537831f9
AM
1649- i_uid_write(inode, btrfs_inode_uid(leaf, inode_item));
1650- i_gid_write(inode, btrfs_inode_gid(leaf, inode_item));
e22b5178 1651+
a4a22af8
AM
1652+ kuid = make_kuid(&init_user_ns, btrfs_inode_uid(leaf, inode_item));
1653+ kgid = make_kgid(&init_user_ns, btrfs_inode_gid(leaf, inode_item));
1654+ ktag = make_ktag(&init_user_ns, btrfs_inode_tag(leaf, inode_item));
1655+
1656+ inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
1657+ inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
1658+ inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, ktag);
e22b5178
AM
1659 btrfs_i_size_write(inode, btrfs_inode_size(leaf, inode_item));
1660
927ca606
AM
1661 inode->i_atime.tv_sec = btrfs_timespec_sec(leaf, &inode_item->atime);
1662@@ -3795,11 +3805,18 @@ static void fill_inode_item(struct btrfs
e22b5178
AM
1663 struct inode *inode)
1664 {
b00e13aa 1665 struct btrfs_map_token token;
a4a22af8
AM
1666+ uid_t uid = from_kuid(&init_user_ns,
1667+ TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
1668+ gid_t gid = from_kgid(&init_user_ns,
1669+ TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
b00e13aa
AM
1670
1671 btrfs_init_map_token(&token);
1672
1673- btrfs_set_token_inode_uid(leaf, item, i_uid_read(inode), &token);
1674- btrfs_set_token_inode_gid(leaf, item, i_gid_read(inode), &token);
1675+ btrfs_set_token_inode_uid(leaf, item, uid, &token);
1676+ btrfs_set_token_inode_gid(leaf, item, gid, &token);
e22b5178 1677+#ifdef CONFIG_TAGGING_INTERN
b00e13aa 1678+ btrfs_set_token_inode_tag(leaf, item, i_tag_read(inode), &token);
e22b5178 1679+#endif
b00e13aa
AM
1680 btrfs_set_token_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size,
1681 &token);
1682 btrfs_set_token_inode_mode(leaf, item, inode->i_mode, &token);
927ca606 1683@@ -10062,6 +10079,7 @@ static const struct inode_operations btr
d4263eb0
JR
1684 .listxattr = btrfs_listxattr,
1685 .removexattr = btrfs_removexattr,
d4263eb0
JR
1686 .permission = btrfs_permission,
1687+ .sync_flags = btrfs_sync_flags,
a168f21d 1688 .get_acl = btrfs_get_acl,
f15949f2 1689 .set_acl = btrfs_set_acl,
c2e5f7c8 1690 .update_time = btrfs_update_time,
927ca606 1691@@ -10070,6 +10088,7 @@ static const struct inode_operations btr
7e46296a 1692 static const struct inode_operations btrfs_dir_ro_inode_operations = {
d4263eb0 1693 .lookup = btrfs_lookup,
d4263eb0 1694 .permission = btrfs_permission,
d4263eb0 1695+ .sync_flags = btrfs_sync_flags,
a168f21d 1696 .get_acl = btrfs_get_acl,
f15949f2 1697 .set_acl = btrfs_set_acl,
c2e5f7c8 1698 .update_time = btrfs_update_time,
927ca606 1699@@ -10140,6 +10159,7 @@ static const struct inode_operations btr
c2e5f7c8
JR
1700 .removexattr = btrfs_removexattr,
1701 .permission = btrfs_permission,
1702 .fiemap = btrfs_fiemap,
1703+ .sync_flags = btrfs_sync_flags,
1704 .get_acl = btrfs_get_acl,
bb20add7 1705 .set_acl = btrfs_set_acl,
c2e5f7c8 1706 .update_time = btrfs_update_time,
8de2f54c 1707diff -NurpP --minimal linux-4.4.111/fs/btrfs/ioctl.c linux-4.4.111-vs2.3.9.5/fs/btrfs/ioctl.c
f19bd705 1708--- linux-4.4.111/fs/btrfs/ioctl.c 2018-01-11 07:57:43.000000000 +0000
8de2f54c 1709+++ linux-4.4.111-vs2.3.9.5/fs/btrfs/ioctl.c 2018-01-09 16:36:24.000000000 +0000
927ca606 1710@@ -108,10 +108,13 @@ static unsigned int btrfs_flags_to_ioctl
d4263eb0
JR
1711 {
1712 unsigned int iflags = 0;
1713
1714- if (flags & BTRFS_INODE_SYNC)
1715- iflags |= FS_SYNC_FL;
1716 if (flags & BTRFS_INODE_IMMUTABLE)
1717 iflags |= FS_IMMUTABLE_FL;
1718+ if (flags & BTRFS_INODE_IXUNLINK)
1719+ iflags |= FS_IXUNLINK_FL;
1720+
1721+ if (flags & BTRFS_INODE_SYNC)
1722+ iflags |= FS_SYNC_FL;
1723 if (flags & BTRFS_INODE_APPEND)
1724 iflags |= FS_APPEND_FL;
1725 if (flags & BTRFS_INODE_NODUMP)
927ca606 1726@@ -128,34 +131,84 @@ static unsigned int btrfs_flags_to_ioctl
763640ca
JR
1727 else if (flags & BTRFS_INODE_NOCOMPRESS)
1728 iflags |= FS_NOCOMP_FL;
d4263eb0
JR
1729
1730+ if (flags & BTRFS_INODE_BARRIER)
1731+ iflags |= FS_BARRIER_FL;
1732+ if (flags & BTRFS_INODE_COW)
1733+ iflags |= FS_COW_FL;
1734 return iflags;
1735 }
1736
1737 /*
1738- * Update inode->i_flags based on the btrfs internal flags.
1739+ * Update inode->i_(v)flags based on the btrfs internal flags.
1740 */
1741 void btrfs_update_iflags(struct inode *inode)
1742 {
1743 struct btrfs_inode *ip = BTRFS_I(inode);
bb20add7 1744 unsigned int new_fl = 0;
d4263eb0
JR
1745
1746- if (ip->flags & BTRFS_INODE_SYNC)
bb20add7 1747- new_fl |= S_SYNC;
d4263eb0 1748 if (ip->flags & BTRFS_INODE_IMMUTABLE)
bb20add7 1749 new_fl |= S_IMMUTABLE;
d4263eb0 1750+ if (ip->flags & BTRFS_INODE_IXUNLINK)
bb20add7 1751+ new_fl |= S_IXUNLINK;
d4263eb0
JR
1752+
1753+ if (ip->flags & BTRFS_INODE_SYNC)
bb20add7 1754+ new_fl |= S_SYNC;
d4263eb0 1755 if (ip->flags & BTRFS_INODE_APPEND)
bb20add7 1756 new_fl |= S_APPEND;
d4263eb0 1757 if (ip->flags & BTRFS_INODE_NOATIME)
bb20add7 1758 new_fl |= S_NOATIME;
d4263eb0 1759 if (ip->flags & BTRFS_INODE_DIRSYNC)
bb20add7
AM
1760 new_fl |= S_DIRSYNC;
1761-
1762 set_mask_bits(&inode->i_flags,
1763- S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC,
1764+ S_SYNC | S_APPEND | S_IMMUTABLE | S_IXUNLINK | S_NOATIME | S_DIRSYNC,
1765 new_fl);
d4263eb0 1766+
bb20add7 1767+ new_fl = 0;
d4263eb0 1768+ if (ip->flags & BTRFS_INODE_BARRIER)
bb20add7 1769+ new_fl |= V_BARRIER;
d4263eb0 1770+ if (ip->flags & BTRFS_INODE_COW)
bb20add7 1771+ new_fl |= V_COW;
d4263eb0 1772+
bb20add7
AM
1773+ set_mask_bits(&inode->i_vflags,
1774+ V_BARRIER | V_COW, new_fl);
1775 }
1776
1777 /*
d4263eb0
JR
1778+ * Update btrfs internal flags from inode->i_(v)flags.
1779+ */
1780+void btrfs_update_flags(struct inode *inode)
1781+{
1782+ struct btrfs_inode *ip = BTRFS_I(inode);
1783+
1784+ unsigned int flags = inode->i_flags;
1785+ unsigned int vflags = inode->i_vflags;
1786+
1787+ ip->flags &= ~(BTRFS_INODE_SYNC | BTRFS_INODE_APPEND |
1788+ BTRFS_INODE_IMMUTABLE | BTRFS_INODE_IXUNLINK |
1789+ BTRFS_INODE_NOATIME | BTRFS_INODE_DIRSYNC |
1790+ BTRFS_INODE_BARRIER | BTRFS_INODE_COW);
1791+
1792+ if (flags & S_IMMUTABLE)
1793+ ip->flags |= BTRFS_INODE_IMMUTABLE;
1794+ if (flags & S_IXUNLINK)
1795+ ip->flags |= BTRFS_INODE_IXUNLINK;
1796+
1797+ if (flags & S_SYNC)
1798+ ip->flags |= BTRFS_INODE_SYNC;
1799+ if (flags & S_APPEND)
1800+ ip->flags |= BTRFS_INODE_APPEND;
1801+ if (flags & S_NOATIME)
1802+ ip->flags |= BTRFS_INODE_NOATIME;
1803+ if (flags & S_DIRSYNC)
1804+ ip->flags |= BTRFS_INODE_DIRSYNC;
1805+
1806+ if (vflags & V_BARRIER)
1807+ ip->flags |= BTRFS_INODE_BARRIER;
1808+ if (vflags & V_COW)
1809+ ip->flags |= BTRFS_INODE_COW;
bb20add7
AM
1810+ }
1811+
1812+/*
1813 * Inherit flags from the parent inode.
1814 *
1815 * Currently only the compression flags and the cow flags are inherited.
927ca606 1816@@ -168,6 +221,7 @@ void btrfs_inherit_iflags(struct inode *
f6c5ef8b 1817 return;
d4263eb0 1818
f6c5ef8b
AM
1819 flags = BTRFS_I(dir)->flags;
1820+ flags &= ~BTRFS_INODE_BARRIER;
d4263eb0 1821
f6c5ef8b
AM
1822 if (flags & BTRFS_INODE_NOCOMPRESS) {
1823 BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS;
927ca606 1824@@ -186,6 +240,30 @@ void btrfs_inherit_iflags(struct inode *
d4263eb0
JR
1825 btrfs_update_iflags(inode);
1826 }
1827
1828+int btrfs_sync_flags(struct inode *inode, int flags, int vflags)
1829+{
1830+ struct btrfs_inode *ip = BTRFS_I(inode);
1831+ struct btrfs_root *root = ip->root;
1832+ struct btrfs_trans_handle *trans;
1833+ int ret;
1834+
763640ca 1835+ trans = btrfs_join_transaction(root);
d4263eb0
JR
1836+ BUG_ON(!trans);
1837+
d4263eb0
JR
1838+ inode->i_flags = flags;
1839+ inode->i_vflags = vflags;
1840+ btrfs_update_flags(inode);
e22b5178
AM
1841+
1842+ ret = btrfs_update_inode(trans, root, inode);
1843+ BUG_ON(ret);
1844+
1845+ btrfs_update_iflags(inode);
d4263eb0
JR
1846+ inode->i_ctime = CURRENT_TIME;
1847+ btrfs_end_transaction(trans, root);
1848+
1849+ return 0;
1850+}
1851+
1852 static int btrfs_ioctl_getflags(struct file *file, void __user *arg)
1853 {
b00e13aa 1854 struct btrfs_inode *ip = BTRFS_I(file_inode(file));
927ca606 1855@@ -248,21 +326,27 @@ static int btrfs_ioctl_setflags(struct f
d4263eb0
JR
1856
1857 flags = btrfs_mask_flags(inode->i_mode, flags);
1858 oldflags = btrfs_flags_to_ioctl(ip->flags);
1859- if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) {
1860+ if ((flags ^ oldflags) & (FS_APPEND_FL |
1861+ FS_IMMUTABLE_FL | FS_IXUNLINK_FL)) {
1862 if (!capable(CAP_LINUX_IMMUTABLE)) {
1863 ret = -EPERM;
1864 goto out_unlock;
92598135
AM
1865 }
1866 }
d4263eb0
JR
1867
1868- if (flags & FS_SYNC_FL)
1869- ip->flags |= BTRFS_INODE_SYNC;
1870- else
1871- ip->flags &= ~BTRFS_INODE_SYNC;
1872 if (flags & FS_IMMUTABLE_FL)
1873 ip->flags |= BTRFS_INODE_IMMUTABLE;
1874 else
1875 ip->flags &= ~BTRFS_INODE_IMMUTABLE;
1876+ if (flags & FS_IXUNLINK_FL)
1877+ ip->flags |= BTRFS_INODE_IXUNLINK;
1878+ else
1879+ ip->flags &= ~BTRFS_INODE_IXUNLINK;
1880+
1881+ if (flags & FS_SYNC_FL)
1882+ ip->flags |= BTRFS_INODE_SYNC;
1883+ else
1884+ ip->flags &= ~BTRFS_INODE_SYNC;
1885 if (flags & FS_APPEND_FL)
1886 ip->flags |= BTRFS_INODE_APPEND;
1887 else
8de2f54c 1888diff -NurpP --minimal linux-4.4.111/fs/btrfs/super.c linux-4.4.111-vs2.3.9.5/fs/btrfs/super.c
f19bd705 1889--- linux-4.4.111/fs/btrfs/super.c 2018-01-11 07:57:43.000000000 +0000
8de2f54c 1890+++ linux-4.4.111-vs2.3.9.5/fs/btrfs/super.c 2018-01-09 17:25:27.000000000 +0000
927ca606
AM
1891@@ -306,7 +306,7 @@ enum {
1892 #ifdef CONFIG_BTRFS_DEBUG
1893 Opt_fragment_data, Opt_fragment_metadata, Opt_fragment_all,
1894 #endif
db55b927 1895- Opt_err,
f6c5ef8b 1896+ Opt_tag, Opt_notag, Opt_tagid, Opt_err,
e22b5178
AM
1897 };
1898
1899 static match_table_t tokens = {
927ca606
AM
1900@@ -363,6 +363,9 @@ static match_table_t tokens = {
1901 {Opt_fragment_metadata, "fragment=metadata"},
1902 {Opt_fragment_all, "fragment=all"},
1903 #endif
e22b5178
AM
1904+ {Opt_tag, "tag"},
1905+ {Opt_notag, "notag"},
1906+ {Opt_tagid, "tagid=%u"},
1907 {Opt_err, NULL},
1908 };
1909
927ca606
AM
1910@@ -745,6 +748,22 @@ int btrfs_parse_options(struct btrfs_roo
1911 btrfs_set_opt(info->mount_opt, FRAGMENT_DATA);
1e8b8f9b 1912 break;
927ca606 1913 #endif
e22b5178
AM
1914+#ifndef CONFIG_TAGGING_NONE
1915+ case Opt_tag:
1916+ printk(KERN_INFO "btrfs: use tagging\n");
1917+ btrfs_set_opt(info->mount_opt, TAGGED);
1918+ break;
1919+ case Opt_notag:
1920+ printk(KERN_INFO "btrfs: disabled tagging\n");
1921+ btrfs_clear_opt(info->mount_opt, TAGGED);
1922+ break;
1923+#endif
1924+#ifdef CONFIG_PROPAGATE
1925+ case Opt_tagid:
1926+ /* use args[0] */
1927+ btrfs_set_opt(info->mount_opt, TAGGED);
1928+ break;
1929+#endif
2bf5ad28 1930 case Opt_err:
bb20add7
AM
1931 btrfs_info(root->fs_info, "unrecognized mount option '%s'", p);
1932 ret = -EINVAL;
927ca606 1933@@ -1647,6 +1666,12 @@ static int btrfs_remount(struct super_bl
42bc425c
AM
1934 btrfs_resize_thread_pool(fs_info,
1935 fs_info->thread_pool_size, old_thread_pool_size);
e22b5178
AM
1936
1937+ if (btrfs_test_opt(root, TAGGED) && !(sb->s_flags & MS_TAGGED)) {
1938+ printk("btrfs: %s: tagging not permitted on remount.\n",
1939+ sb->s_id);
1940+ return -EINVAL;
1941+ }
1942+
1943 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
b00e13aa 1944 goto out;
e22b5178 1945
8de2f54c 1946diff -NurpP --minimal linux-4.4.111/fs/char_dev.c linux-4.4.111-vs2.3.9.5/fs/char_dev.c
f19bd705 1947--- linux-4.4.111/fs/char_dev.c 2016-07-05 04:12:30.000000000 +0000
8de2f54c 1948+++ linux-4.4.111-vs2.3.9.5/fs/char_dev.c 2018-01-09 16:36:24.000000000 +0000
4744a4b1 1949@@ -21,6 +21,8 @@
2380c486
JR
1950 #include <linux/mutex.h>
1951 #include <linux/backing-dev.h>
7942c842 1952 #include <linux/tty.h>
2380c486
JR
1953+#include <linux/vs_context.h>
1954+#include <linux/vs_device.h>
1955
ec22aa5c
AM
1956 #include "internal.h"
1957
927ca606 1958@@ -350,14 +352,21 @@ static int chrdev_open(struct inode *ino
2380c486
JR
1959 struct cdev *p;
1960 struct cdev *new = NULL;
1961 int ret = 0;
1962+ dev_t mdev;
1963+
1964+ if (!vs_map_chrdev(inode->i_rdev, &mdev, DATTR_OPEN))
1965+ return -EPERM;
1966+ inode->i_mdev = mdev;
1967
1968 spin_lock(&cdev_lock);
1969 p = inode->i_cdev;
1970 if (!p) {
1971 struct kobject *kobj;
1972 int idx;
1973+
1974 spin_unlock(&cdev_lock);
1975- kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
1976+
1977+ kobj = kobj_lookup(cdev_map, mdev, &idx);
1978 if (!kobj)
1979 return -ENXIO;
1980 new = container_of(kobj, struct cdev, kobj);
8de2f54c 1981diff -NurpP --minimal linux-4.4.111/fs/dcache.c linux-4.4.111-vs2.3.9.5/fs/dcache.c
f19bd705 1982--- linux-4.4.111/fs/dcache.c 2018-01-11 07:57:44.000000000 +0000
8de2f54c 1983+++ linux-4.4.111-vs2.3.9.5/fs/dcache.c 2018-01-09 16:36:24.000000000 +0000
927ca606 1984@@ -39,6 +39,7 @@
f6c5ef8b 1985 #include <linux/ratelimit.h>
c2e5f7c8 1986 #include <linux/list_lru.h>
927ca606 1987 #include <linux/kasan.h>
d337f35e 1988+#include <linux/vs_limit.h>
927ca606 1989
d337f35e 1990 #include "internal.h"
db55b927 1991 #include "mount.h"
927ca606
AM
1992@@ -677,6 +678,7 @@ static inline bool fast_dput(struct dent
1993 spin_lock(&dentry->d_lock);
1994 if (dentry->d_lockref.count > 1) {
1995 dentry->d_lockref.count--;
1996+ vx_dentry_dec(dentry);
1997 spin_unlock(&dentry->d_lock);
1998 return 1;
1999 }
2000@@ -806,6 +808,7 @@ repeat:
2001 dentry_lru_add(dentry);
2002
2003 dentry->d_lockref.count--;
2004+ vx_dentry_dec(dentry);
2005 spin_unlock(&dentry->d_lock);
2006 return;
d337f35e 2007
927ca606 2008@@ -823,6 +826,7 @@ EXPORT_SYMBOL(dput);
d33d7b00 2009 static inline void __dget_dlock(struct dentry *dentry)
2380c486 2010 {
c2e5f7c8 2011 dentry->d_lockref.count++;
2380c486 2012+ vx_dentry_inc(dentry);
d337f35e 2013 }
2380c486 2014
d33d7b00 2015 static inline void __dget(struct dentry *dentry)
927ca606 2016@@ -835,6 +839,8 @@ struct dentry *dget_parent(struct dentry
bb20add7
AM
2017 int gotref;
2018 struct dentry *ret;
2019
2020+ vx_dentry_dec(dentry);
2021+
2022 /*
2023 * Do optimistic parent lookup without any
2024 * locking.
927ca606
AM
2025@@ -865,6 +871,7 @@ repeat:
2026 rcu_read_unlock();
2027 BUG_ON(!ret->d_lockref.count);
2028 ret->d_lockref.count++;
2029+ vx_dentry_inc(ret);
2030 spin_unlock(&ret->d_lock);
2031 return ret;
2032 }
2033@@ -1019,6 +1026,7 @@ static void shrink_dentry_list(struct li
2034 parent = lock_parent(dentry);
2035 if (dentry->d_lockref.count != 1) {
2036 dentry->d_lockref.count--;
2037+ vx_dentry_dec(dentry);
2038 spin_unlock(&dentry->d_lock);
2039 if (parent)
2040 spin_unlock(&parent->d_lock);
2041@@ -1581,6 +1589,9 @@ struct dentry *__d_alloc(struct super_bl
d337f35e
JR
2042 struct dentry *dentry;
2043 char *dname;
2044
2045+ if (!vx_dentry_avail(1))
2046+ return NULL;
2047+
2380c486 2048 dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
d337f35e
JR
2049 if (!dentry)
2050 return NULL;
927ca606 2051@@ -1619,6 +1630,7 @@ struct dentry *__d_alloc(struct super_bl
d337f35e 2052
c2e5f7c8 2053 dentry->d_lockref.count = 1;
763640ca 2054 dentry->d_flags = 0;
ab30d09f 2055+ vx_dentry_inc(dentry);
ab30d09f 2056 spin_lock_init(&dentry->d_lock);
d33d7b00 2057 seqcount_init(&dentry->d_seq);
763640ca 2058 dentry->d_inode = NULL;
927ca606 2059@@ -2355,6 +2367,7 @@ struct dentry *__d_lookup(const struct d
d337f35e 2060 }
2380c486 2061
c2e5f7c8 2062 dentry->d_lockref.count++;
2380c486
JR
2063+ vx_dentry_inc(dentry);
2064 found = dentry;
d337f35e 2065 spin_unlock(&dentry->d_lock);
2380c486 2066 break;
927ca606
AM
2067@@ -3371,6 +3384,7 @@ static enum d_walk_ret d_genocide_kill(v
2068 if (!(dentry->d_flags & DCACHE_GENOCIDE)) {
2069 dentry->d_flags |= DCACHE_GENOCIDE;
2070 dentry->d_lockref.count--;
2071+ vx_dentry_dec(dentry);
2072 }
2073 }
2074 return D_WALK_CONTINUE;
8de2f54c 2075diff -NurpP --minimal linux-4.4.111/fs/devpts/inode.c linux-4.4.111-vs2.3.9.5/fs/devpts/inode.c
f19bd705 2076--- linux-4.4.111/fs/devpts/inode.c 2018-01-11 07:57:44.000000000 +0000
8de2f54c 2077+++ linux-4.4.111-vs2.3.9.5/fs/devpts/inode.c 2018-01-09 16:36:24.000000000 +0000
bb20add7 2078@@ -27,6 +27,7 @@
d337f35e 2079 #include <linux/parser.h>
2380c486
JR
2080 #include <linux/fsnotify.h>
2081 #include <linux/seq_file.h>
d337f35e
JR
2082+#include <linux/vs_base.h>
2083
2380c486 2084 #define DEVPTS_DEFAULT_MODE 0600
ec22aa5c 2085 /*
bb20add7 2086@@ -38,6 +39,21 @@
ec22aa5c
AM
2087 #define DEVPTS_DEFAULT_PTMX_MODE 0000
2088 #define PTMX_MINOR 2
2380c486 2089
a168f21d 2090+static int devpts_permission(struct inode *inode, int mask)
d337f35e
JR
2091+{
2092+ int ret = -EACCES;
2093+
2094+ /* devpts is xid tagged */
61333608 2095+ if (vx_check((vxid_t)i_tag_read(inode), VS_WATCH_P | VS_IDENT))
a168f21d 2096+ ret = generic_permission(inode, mask);
d337f35e
JR
2097+ return ret;
2098+}
2099+
2100+static struct inode_operations devpts_file_inode_operations = {
2101+ .permission = devpts_permission,
2102+};
2380c486 2103+
1e8b8f9b
AM
2104+
2105 /*
2106 * sysctl support for setting limits on the number of Unix98 ptys allocated.
2107 * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly.
927ca606 2108@@ -353,6 +369,34 @@ static int devpts_show_options(struct se
d337f35e
JR
2109 return 0;
2110 }
2111
2112+static int devpts_filter(struct dentry *de)
2113+{
61333608 2114+ vxid_t xid = 0;
b3b0d4fd 2115+
d337f35e 2116+ /* devpts is xid tagged */
b3b0d4fd 2117+ if (de && de->d_inode)
61333608 2118+ xid = (vxid_t)i_tag_read(de->d_inode);
b3b0d4fd
AM
2119+#ifdef CONFIG_VSERVER_WARN_DEVPTS
2120+ else
2121+ vxwprintk_task(1, "devpts " VS_Q("%.*s") " without inode.",
2122+ de->d_name.len, de->d_name.name);
2123+#endif
2124+ return vx_check(xid, VS_WATCH_P | VS_IDENT);
d337f35e
JR
2125+}
2126+
c2e5f7c8 2127+static int devpts_readdir(struct file * filp, struct dir_context *ctx)
d337f35e 2128+{
c2e5f7c8 2129+ return dcache_readdir_filter(filp, ctx, devpts_filter);
d337f35e
JR
2130+}
2131+
2132+static struct file_operations devpts_dir_operations = {
2133+ .open = dcache_dir_open,
2134+ .release = dcache_dir_close,
2135+ .llseek = dcache_dir_lseek,
2136+ .read = generic_read_dir,
c2e5f7c8 2137+ .iterate = devpts_readdir,
d337f35e
JR
2138+};
2139+
2380c486 2140 static const struct super_operations devpts_sops = {
d337f35e
JR
2141 .statfs = simple_statfs,
2142 .remount_fs = devpts_remount,
927ca606 2143@@ -397,8 +441,10 @@ devpts_fill_super(struct super_block *s,
ec22aa5c 2144 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
d337f35e
JR
2145 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
2146 inode->i_op = &simple_dir_inode_operations;
2147- inode->i_fop = &simple_dir_operations;
2148+ inode->i_fop = &devpts_dir_operations;
f6c5ef8b 2149 set_nlink(inode, 2);
d337f35e 2150+ /* devpts is xid tagged */
61333608 2151+ i_tag_write(inode, (vtag_t)vx_current_xid());
d337f35e 2152
1e8b8f9b 2153 s->s_root = d_make_root(inode);
d337f35e 2154 if (s->s_root)
927ca606 2155@@ -630,6 +676,9 @@ struct inode *devpts_pty_new(struct pts_
ec22aa5c 2156 inode->i_gid = opts->setgid ? opts->gid : current_fsgid();
d337f35e 2157 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
ec22aa5c 2158 init_special_inode(inode, S_IFCHR|opts->mode, device);
d337f35e 2159+ /* devpts is xid tagged */
61333608 2160+ i_tag_write(inode, (vtag_t)vx_current_xid());
d337f35e 2161+ inode->i_op = &devpts_file_inode_operations;
b00e13aa 2162 inode->i_private = priv;
d337f35e 2163
b00e13aa 2164 sprintf(s, "%d", index);
8de2f54c 2165diff -NurpP --minimal linux-4.4.111/fs/ext2/balloc.c linux-4.4.111-vs2.3.9.5/fs/ext2/balloc.c
f19bd705 2166--- linux-4.4.111/fs/ext2/balloc.c 2015-04-12 22:12:50.000000000 +0000
8de2f54c 2167+++ linux-4.4.111-vs2.3.9.5/fs/ext2/balloc.c 2018-01-09 16:36:24.000000000 +0000
b00e13aa 2168@@ -693,7 +693,6 @@ ext2_try_to_allocate(struct super_block
2380c486
JR
2169 start = 0;
2170 end = EXT2_BLOCKS_PER_GROUP(sb);
d337f35e 2171 }
2380c486
JR
2172-
2173 BUG_ON(start > EXT2_BLOCKS_PER_GROUP(sb));
2174
2175 repeat:
8de2f54c 2176diff -NurpP --minimal linux-4.4.111/fs/ext2/ext2.h linux-4.4.111-vs2.3.9.5/fs/ext2/ext2.h
f19bd705 2177--- linux-4.4.111/fs/ext2/ext2.h 2016-07-05 04:15:07.000000000 +0000
8de2f54c 2178+++ linux-4.4.111-vs2.3.9.5/fs/ext2/ext2.h 2018-01-09 16:36:24.000000000 +0000
1e8b8f9b
AM
2179@@ -244,8 +244,12 @@ struct ext2_group_desc
2180 #define EXT2_NOTAIL_FL FS_NOTAIL_FL /* file tail should not be merged */
2181 #define EXT2_DIRSYNC_FL FS_DIRSYNC_FL /* dirsync behaviour (directories only) */
2182 #define EXT2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/
2183+#define EXT2_IXUNLINK_FL FS_IXUNLINK_FL /* Immutable invert on unlink */
2184 #define EXT2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */
2185
2186+#define EXT2_BARRIER_FL FS_BARRIER_FL /* Barrier for chroot() */
2187+#define EXT2_COW_FL FS_COW_FL /* Copy on Write marker */
2188+
2189 #define EXT2_FL_USER_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */
2190 #define EXT2_FL_USER_MODIFIABLE FS_FL_USER_MODIFIABLE /* User modifiable flags */
2191
2192@@ -329,7 +333,8 @@ struct ext2_inode {
2193 __u16 i_pad1;
2194 __le16 l_i_uid_high; /* these 2 fields */
2195 __le16 l_i_gid_high; /* were reserved2[0] */
2196- __u32 l_i_reserved2;
2197+ __le16 l_i_tag; /* Context Tag */
2198+ __u16 l_i_reserved2;
2199 } linux2;
2200 struct {
2201 __u8 h_i_frag; /* Fragment number */
2202@@ -357,6 +362,7 @@ struct ext2_inode {
2203 #define i_gid_low i_gid
2204 #define i_uid_high osd2.linux2.l_i_uid_high
2205 #define i_gid_high osd2.linux2.l_i_gid_high
2206+#define i_raw_tag osd2.linux2.l_i_tag
2207 #define i_reserved2 osd2.linux2.l_i_reserved2
2208
2209 /*
927ca606
AM
2210@@ -389,6 +395,7 @@ struct ext2_inode {
2211 #else
2212 #define EXT2_MOUNT_DAX 0
2213 #endif
2214+#define EXT2_MOUNT_TAGGED 0x200000 /* Enable Context Tags */
1e8b8f9b
AM
2215
2216
2217 #define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
927ca606 2218@@ -776,6 +783,7 @@ extern void ext2_set_inode_flags(struct
93de0823
AM
2219 extern void ext2_get_inode_flags(struct ext2_inode_info *);
2220 extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
2221 u64 start, u64 len);
d4263eb0
JR
2222+extern int ext2_sync_flags(struct inode *, int, int);
2223
2224 /* ioctl.c */
2225 extern long ext2_ioctl(struct file *, unsigned int, unsigned long);
8de2f54c 2226diff -NurpP --minimal linux-4.4.111/fs/ext2/file.c linux-4.4.111-vs2.3.9.5/fs/ext2/file.c
f19bd705 2227--- linux-4.4.111/fs/ext2/file.c 2016-07-05 04:15:07.000000000 +0000
8de2f54c 2228+++ linux-4.4.111-vs2.3.9.5/fs/ext2/file.c 2018-01-09 16:36:24.000000000 +0000
927ca606 2229@@ -202,4 +202,5 @@ const struct inode_operations ext2_file_
a168f21d 2230 .get_acl = ext2_get_acl,
bb20add7 2231 .set_acl = ext2_set_acl,
ec22aa5c 2232 .fiemap = ext2_fiemap,
d337f35e
JR
2233+ .sync_flags = ext2_sync_flags,
2234 };
8de2f54c 2235diff -NurpP --minimal linux-4.4.111/fs/ext2/ialloc.c linux-4.4.111-vs2.3.9.5/fs/ext2/ialloc.c
f19bd705 2236--- linux-4.4.111/fs/ext2/ialloc.c 2016-07-05 04:12:30.000000000 +0000
8de2f54c 2237+++ linux-4.4.111-vs2.3.9.5/fs/ext2/ialloc.c 2018-01-09 16:36:24.000000000 +0000
e22b5178
AM
2238@@ -17,6 +17,7 @@
2239 #include <linux/backing-dev.h>
2240 #include <linux/buffer_head.h>
2241 #include <linux/random.h>
2242+#include <linux/vs_tag.h>
2243 #include "ext2.h"
2244 #include "xattr.h"
2245 #include "acl.h"
a4a22af8 2246@@ -546,6 +547,7 @@ got:
76514441
AM
2247 inode->i_mode = mode;
2248 inode->i_uid = current_fsuid();
2249 inode->i_gid = dir->i_gid;
a4a22af8 2250+ i_tag_write(inode, dx_current_fstag(sb));
e22b5178 2251 } else
76514441 2252 inode_init_owner(inode, dir, mode);
e22b5178 2253
8de2f54c 2254diff -NurpP --minimal linux-4.4.111/fs/ext2/inode.c linux-4.4.111-vs2.3.9.5/fs/ext2/inode.c
f19bd705 2255--- linux-4.4.111/fs/ext2/inode.c 2016-07-05 04:15:07.000000000 +0000
8de2f54c 2256+++ linux-4.4.111-vs2.3.9.5/fs/ext2/inode.c 2018-01-09 16:36:24.000000000 +0000
927ca606 2257@@ -33,6 +33,7 @@
ec22aa5c
AM
2258 #include <linux/fiemap.h>
2259 #include <linux/namei.h>
927ca606 2260 #include <linux/uio.h>
d337f35e
JR
2261+#include <linux/vs_tag.h>
2262 #include "ext2.h"
2263 #include "acl.h"
927ca606
AM
2264 #include "xattr.h"
2265@@ -1188,7 +1189,7 @@ static void ext2_truncate_blocks(struct
d337f35e
JR
2266 return;
2267 if (ext2_inode_is_fast_symlink(inode))
2268 return;
2269- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
2270+ if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
2271 return;
927ca606
AM
2272
2273 dax_sem_down_write(EXT2_I(inode));
2274@@ -1284,39 +1285,62 @@ void ext2_set_inode_flags(struct inode *
d337f35e
JR
2275 {
2276 unsigned int flags = EXT2_I(inode)->i_flags;
2277
927ca606
AM
2278- inode->i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME |
2279- S_DIRSYNC | S_DAX);
2280+ inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK | S_DAX |
d337f35e
JR
2281+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
2282+
2283+ if (flags & EXT2_IMMUTABLE_FL)
2284+ inode->i_flags |= S_IMMUTABLE;
2380c486
JR
2285+ if (flags & EXT2_IXUNLINK_FL)
2286+ inode->i_flags |= S_IXUNLINK;
d337f35e
JR
2287+
2288 if (flags & EXT2_SYNC_FL)
2289 inode->i_flags |= S_SYNC;
2290 if (flags & EXT2_APPEND_FL)
2291 inode->i_flags |= S_APPEND;
2292- if (flags & EXT2_IMMUTABLE_FL)
2293- inode->i_flags |= S_IMMUTABLE;
2294 if (flags & EXT2_NOATIME_FL)
2295 inode->i_flags |= S_NOATIME;
2296 if (flags & EXT2_DIRSYNC_FL)
2297 inode->i_flags |= S_DIRSYNC;
927ca606
AM
2298 if (test_opt(inode->i_sb, DAX))
2299 inode->i_flags |= S_DAX;
2380c486
JR
2300+
2301+ inode->i_vflags &= ~(V_BARRIER | V_COW);
2302+
2303+ if (flags & EXT2_BARRIER_FL)
2304+ inode->i_vflags |= V_BARRIER;
2305+ if (flags & EXT2_COW_FL)
2306+ inode->i_vflags |= V_COW;
2307 }
2308
2309 /* Propagate flags from i_flags to EXT2_I(inode)->i_flags */
2310 void ext2_get_inode_flags(struct ext2_inode_info *ei)
2311 {
2312 unsigned int flags = ei->vfs_inode.i_flags;
2313+ unsigned int vflags = ei->vfs_inode.i_vflags;
2314+
2315+ ei->i_flags &= ~(EXT2_SYNC_FL | EXT2_APPEND_FL |
2316+ EXT2_IMMUTABLE_FL | EXT2_IXUNLINK_FL |
2317+ EXT2_NOATIME_FL | EXT2_DIRSYNC_FL |
2318+ EXT2_BARRIER_FL | EXT2_COW_FL);
2319+
2320+ if (flags & S_IMMUTABLE)
2321+ ei->i_flags |= EXT2_IMMUTABLE_FL;
2322+ if (flags & S_IXUNLINK)
2323+ ei->i_flags |= EXT2_IXUNLINK_FL;
2324
2325- ei->i_flags &= ~(EXT2_SYNC_FL|EXT2_APPEND_FL|
2326- EXT2_IMMUTABLE_FL|EXT2_NOATIME_FL|EXT2_DIRSYNC_FL);
2327 if (flags & S_SYNC)
2328 ei->i_flags |= EXT2_SYNC_FL;
2329 if (flags & S_APPEND)
2330 ei->i_flags |= EXT2_APPEND_FL;
2331- if (flags & S_IMMUTABLE)
2332- ei->i_flags |= EXT2_IMMUTABLE_FL;
2333 if (flags & S_NOATIME)
2334 ei->i_flags |= EXT2_NOATIME_FL;
2335 if (flags & S_DIRSYNC)
2336 ei->i_flags |= EXT2_DIRSYNC_FL;
2337+
2338+ if (vflags & V_BARRIER)
2339+ ei->i_flags |= EXT2_BARRIER_FL;
2340+ if (vflags & V_COW)
2341+ ei->i_flags |= EXT2_COW_FL;
d337f35e
JR
2342 }
2343
2380c486 2344 struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
927ca606 2345@@ -1352,8 +1376,10 @@ struct inode *ext2_iget (struct super_bl
42bc425c
AM
2346 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
2347 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
d337f35e 2348 }
42bc425c
AM
2349- i_uid_write(inode, i_uid);
2350- i_gid_write(inode, i_gid);
2351+ i_uid_write(inode, INOTAG_UID(DX_TAG(inode), i_uid, i_gid));
2352+ i_gid_write(inode, INOTAG_GID(DX_TAG(inode), i_uid, i_gid));
537831f9
AM
2353+ i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
2354+ le16_to_cpu(raw_inode->i_raw_tag)));
f6c5ef8b 2355 set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
d337f35e 2356 inode->i_size = le32_to_cpu(raw_inode->i_size);
2380c486 2357 inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
927ca606 2358@@ -1449,8 +1475,10 @@ static int __ext2_write_inode(struct ino
d337f35e
JR
2359 struct ext2_inode_info *ei = EXT2_I(inode);
2360 struct super_block *sb = inode->i_sb;
2361 ino_t ino = inode->i_ino;
42bc425c
AM
2362- uid_t uid = i_uid_read(inode);
2363- gid_t gid = i_gid_read(inode);
a4a22af8
AM
2364+ uid_t uid = from_kuid(&init_user_ns,
2365+ TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
2366+ gid_t gid = from_kgid(&init_user_ns,
2367+ TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
d337f35e
JR
2368 struct buffer_head * bh;
2369 struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh);
2370 int n;
927ca606 2371@@ -1486,6 +1514,9 @@ static int __ext2_write_inode(struct ino
d337f35e
JR
2372 raw_inode->i_uid_high = 0;
2373 raw_inode->i_gid_high = 0;
2374 }
2375+#ifdef CONFIG_TAGGING_INTERN
537831f9 2376+ raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
d337f35e
JR
2377+#endif
2378 raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
2379 raw_inode->i_size = cpu_to_le32(inode->i_size);
2380 raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
927ca606
AM
2381@@ -1569,7 +1600,8 @@ int ext2_setattr(struct dentry *dentry,
2382 return error;
2383 }
42bc425c
AM
2384 if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) ||
2385- (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) {
2386+ (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid)) ||
537831f9 2387+ (iattr->ia_valid & ATTR_TAG && !tag_eq(iattr->ia_tag, inode->i_tag))) {
78865d5b 2388 error = dquot_transfer(inode, iattr);
d337f35e
JR
2389 if (error)
2390 return error;
8de2f54c 2391diff -NurpP --minimal linux-4.4.111/fs/ext2/ioctl.c linux-4.4.111-vs2.3.9.5/fs/ext2/ioctl.c
f19bd705 2392--- linux-4.4.111/fs/ext2/ioctl.c 2015-04-12 22:12:50.000000000 +0000
8de2f54c 2393+++ linux-4.4.111-vs2.3.9.5/fs/ext2/ioctl.c 2018-01-09 16:36:24.000000000 +0000
d4263eb0
JR
2394@@ -17,6 +17,16 @@
2395 #include <asm/uaccess.h>
2396
2397
2398+int ext2_sync_flags(struct inode *inode, int flags, int vflags)
2399+{
2400+ inode->i_flags = flags;
2401+ inode->i_vflags = vflags;
2402+ ext2_get_inode_flags(EXT2_I(inode));
2403+ inode->i_ctime = CURRENT_TIME_SEC;
2404+ mark_inode_dirty(inode);
2405+ return 0;
2406+}
2407+
2408 long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
2409 {
b00e13aa 2410 struct inode *inode = file_inode(filp);
d4263eb0 2411@@ -51,6 +61,11 @@ long ext2_ioctl(struct file *filp, unsig
d337f35e 2412
ec22aa5c 2413 flags = ext2_mask_flags(inode->i_mode, flags);
d337f35e 2414
2380c486
JR
2415+ if (IS_BARRIER(inode)) {
2416+ vxwprintk_task(1, "messing with the barrier.");
2417+ return -EACCES;
2418+ }
2419+
2420 mutex_lock(&inode->i_mutex);
2421 /* Is it quota file? Do not allow user to mess with it */
2422 if (IS_NOQUOTA(inode)) {
d4263eb0 2423@@ -66,7 +81,9 @@ long ext2_ioctl(struct file *filp, unsig
d337f35e
JR
2424 *
2425 * This test looks nicer. Thanks to Pauline Middelink
2426 */
2427- if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {
2428+ if ((oldflags & EXT2_IMMUTABLE_FL) ||
2429+ ((flags ^ oldflags) & (EXT2_APPEND_FL |
2380c486
JR
2430+ EXT2_IMMUTABLE_FL | EXT2_IXUNLINK_FL))) {
2431 if (!capable(CAP_LINUX_IMMUTABLE)) {
2432 mutex_unlock(&inode->i_mutex);
2433 ret = -EPERM;
d4263eb0
JR
2434@@ -74,7 +91,7 @@ long ext2_ioctl(struct file *filp, unsig
2435 }
2436 }
2437
2438- flags = flags & EXT2_FL_USER_MODIFIABLE;
2439+ flags &= EXT2_FL_USER_MODIFIABLE;
2440 flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE;
2441 ei->i_flags = flags;
db55b927 2442
8de2f54c 2443diff -NurpP --minimal linux-4.4.111/fs/ext2/namei.c linux-4.4.111-vs2.3.9.5/fs/ext2/namei.c
f19bd705 2444--- linux-4.4.111/fs/ext2/namei.c 2016-07-05 04:15:07.000000000 +0000
8de2f54c 2445+++ linux-4.4.111-vs2.3.9.5/fs/ext2/namei.c 2018-01-09 16:36:24.000000000 +0000
78865d5b 2446@@ -32,6 +32,7 @@
d337f35e
JR
2447
2448 #include <linux/pagemap.h>
78865d5b 2449 #include <linux/quotaops.h>
d337f35e
JR
2450+#include <linux/vs_tag.h>
2451 #include "ext2.h"
2452 #include "xattr.h"
2453 #include "acl.h"
927ca606 2454@@ -72,6 +73,7 @@ static struct dentry *ext2_lookup(struct
a168f21d
AM
2455 (unsigned long) ino);
2456 return ERR_PTR(-EIO);
ec22aa5c 2457 }
a168f21d 2458+ dx_propagate_tag(nd, inode);
d337f35e 2459 }
a168f21d
AM
2460 return d_splice_alias(inode, dentry);
2461 }
927ca606 2462@@ -446,6 +448,7 @@ const struct inode_operations ext2_speci
a168f21d 2463 .removexattr = generic_removexattr,
d337f35e
JR
2464 #endif
2465 .setattr = ext2_setattr,
d337f35e 2466+ .sync_flags = ext2_sync_flags,
a168f21d 2467 .get_acl = ext2_get_acl,
bb20add7 2468 .set_acl = ext2_set_acl,
d337f35e 2469 };
8de2f54c 2470diff -NurpP --minimal linux-4.4.111/fs/ext2/super.c linux-4.4.111-vs2.3.9.5/fs/ext2/super.c
f19bd705 2471--- linux-4.4.111/fs/ext2/super.c 2016-07-05 04:15:07.000000000 +0000
8de2f54c 2472+++ linux-4.4.111-vs2.3.9.5/fs/ext2/super.c 2018-01-09 16:36:24.000000000 +0000
927ca606 2473@@ -408,7 +408,8 @@ enum {
d337f35e
JR
2474 Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
2475 Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
927ca606 2476 Opt_acl, Opt_noacl, Opt_xip, Opt_dax, Opt_ignore, Opt_err, Opt_quota,
2380c486
JR
2477- Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation
2478+ Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation,
2479+ Opt_tag, Opt_notag, Opt_tagid
d337f35e
JR
2480 };
2481
ec22aa5c 2482 static const match_table_t tokens = {
927ca606 2483@@ -436,6 +437,9 @@ static const match_table_t tokens = {
d337f35e
JR
2484 {Opt_acl, "acl"},
2485 {Opt_noacl, "noacl"},
2486 {Opt_xip, "xip"},
2487+ {Opt_tag, "tag"},
2488+ {Opt_notag, "notag"},
2489+ {Opt_tagid, "tagid=%u"},
927ca606 2490 {Opt_dax, "dax"},
d337f35e
JR
2491 {Opt_grpquota, "grpquota"},
2492 {Opt_ignore, "noquota"},
927ca606 2493@@ -520,6 +524,20 @@ static int parse_options(char *options,
d337f35e
JR
2494 case Opt_nouid32:
2495 set_opt (sbi->s_mount_opt, NO_UID32);
2496 break;
2497+#ifndef CONFIG_TAGGING_NONE
2498+ case Opt_tag:
2499+ set_opt (sbi->s_mount_opt, TAGGED);
2500+ break;
2501+ case Opt_notag:
2502+ clear_opt (sbi->s_mount_opt, TAGGED);
2503+ break;
2504+#endif
2505+#ifdef CONFIG_PROPAGATE
2506+ case Opt_tagid:
2507+ /* use args[0] */
2508+ set_opt (sbi->s_mount_opt, TAGGED);
2509+ break;
2510+#endif
2511 case Opt_nocheck:
2512 clear_opt (sbi->s_mount_opt, CHECK);
2513 break;
927ca606 2514@@ -884,6 +902,8 @@ static int ext2_fill_super(struct super_
2bf5ad28 2515 if (!parse_options((char *) data, sb))
d337f35e
JR
2516 goto failed_mount;
2517
2518+ if (EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_TAGGED)
2519+ sb->s_flags |= MS_TAGGED;
2520 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2521 ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
2522 MS_POSIXACL : 0);
927ca606 2523@@ -1294,6 +1314,14 @@ static int ext2_remount (struct super_bl
537831f9 2524 err = -EINVAL;
d337f35e
JR
2525 goto restore_opts;
2526 }
537831f9 2527+
d337f35e
JR
2528+ if ((sbi->s_mount_opt & EXT2_MOUNT_TAGGED) &&
2529+ !(sb->s_flags & MS_TAGGED)) {
2530+ printk("EXT2-fs: %s: tagging not permitted on remount.\n",
2531+ sb->s_id);
d4263eb0
JR
2532+ err = -EINVAL;
2533+ goto restore_opts;
d337f35e 2534+ }
537831f9 2535
d337f35e
JR
2536 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2537 ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
8de2f54c 2538diff -NurpP --minimal linux-4.4.111/fs/ext4/ext4.h linux-4.4.111-vs2.3.9.5/fs/ext4/ext4.h
f19bd705 2539--- linux-4.4.111/fs/ext4/ext4.h 2018-01-11 07:57:44.000000000 +0000
8de2f54c 2540+++ linux-4.4.111-vs2.3.9.5/fs/ext4/ext4.h 2018-01-09 17:33:10.000000000 +0000
927ca606 2541@@ -375,8 +375,11 @@ struct flex_groups {
2380c486 2542 #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
78865d5b
AM
2543 #define EXT4_EA_INODE_FL 0x00200000 /* Inode used for large EA */
2544 #define EXT4_EOFBLOCKS_FL 0x00400000 /* Blocks allocated beyond EOF */
b00e13aa 2545+#define EXT4_BARRIER_FL 0x04000000 /* Barrier for chroot() */
2380c486 2546+#define EXT4_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */
b00e13aa 2547 #define EXT4_INLINE_DATA_FL 0x10000000 /* Inode has inline data. */
927ca606
AM
2548 #define EXT4_PROJINHERIT_FL 0x20000000 /* Create with parents projid */
2549+#define EXT4_COW_FL 0x40000000 /* Copy on Write marker */
2380c486 2550 #define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
d337f35e 2551
78865d5b 2552 #define EXT4_FL_USER_VISIBLE 0x004BDFFF /* User visible flags */
927ca606 2553@@ -674,7 +677,7 @@ struct ext4_inode {
ec22aa5c
AM
2554 __le16 l_i_uid_high; /* these 2 fields */
2555 __le16 l_i_gid_high; /* were reserved2[0] */
42bc425c
AM
2556 __le16 l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
2557- __le16 l_i_reserved;
ec22aa5c 2558+ __le16 l_i_tag; /* Context Tag */
ec22aa5c
AM
2559 } linux2;
2560 struct {
2561 __le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
927ca606 2562@@ -831,6 +834,7 @@ do { \
ec22aa5c
AM
2563 #define i_gid_low i_gid
2564 #define i_uid_high osd2.linux2.l_i_uid_high
2565 #define i_gid_high osd2.linux2.l_i_gid_high
2566+#define i_raw_tag osd2.linux2.l_i_tag
42bc425c 2567 #define i_checksum_lo osd2.linux2.l_i_checksum_lo
d337f35e 2568
ec22aa5c 2569 #elif defined(__GNU__)
927ca606 2570@@ -1068,6 +1072,7 @@ struct ext4_inode_info {
ab30d09f
AM
2571 #define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */
2572 #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mapping */
2573 #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */
2574+#define EXT4_MOUNT_TAGGED 0x40000 /* Enable Context Tags */
2575 #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */
2576 #define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
2577 #define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
927ca606
AM
2578@@ -2501,6 +2506,7 @@ extern int ext4_punch_hole(struct inode
2579 extern int ext4_truncate_restart_trans(handle_t *, struct inode *, int nblocks);
2580 extern void ext4_set_inode_flags(struct inode *);
2581 extern void ext4_get_inode_flags(struct ext4_inode_info *);
d4263eb0 2582+extern int ext4_sync_flags(struct inode *, int, int);
927ca606
AM
2583 extern int ext4_alloc_da_blocks(struct inode *inode);
2584 extern void ext4_set_aops(struct inode *inode);
2585 extern int ext4_writepage_trans_blocks(struct inode *);
8de2f54c 2586diff -NurpP --minimal linux-4.4.111/fs/ext4/file.c linux-4.4.111-vs2.3.9.5/fs/ext4/file.c
f19bd705 2587--- linux-4.4.111/fs/ext4/file.c 2018-01-11 07:57:44.000000000 +0000
8de2f54c 2588+++ linux-4.4.111-vs2.3.9.5/fs/ext4/file.c 2018-01-09 16:36:31.000000000 +0000
927ca606 2589@@ -749,5 +749,6 @@ const struct inode_operations ext4_file_
a168f21d 2590 .get_acl = ext4_get_acl,
bb20add7 2591 .set_acl = ext4_set_acl,
ec22aa5c 2592 .fiemap = ext4_fiemap,
d337f35e
JR
2593+ .sync_flags = ext4_sync_flags,
2594 };
2595
8de2f54c 2596diff -NurpP --minimal linux-4.4.111/fs/ext4/ialloc.c linux-4.4.111-vs2.3.9.5/fs/ext4/ialloc.c
f19bd705 2597--- linux-4.4.111/fs/ext4/ialloc.c 2018-01-11 07:57:44.000000000 +0000
8de2f54c 2598+++ linux-4.4.111-vs2.3.9.5/fs/ext4/ialloc.c 2018-01-09 16:36:31.000000000 +0000
927ca606 2599@@ -21,6 +21,7 @@
e22b5178
AM
2600 #include <linux/random.h>
2601 #include <linux/bitops.h>
2602 #include <linux/blkdev.h>
2603+#include <linux/vs_tag.h>
2604 #include <asm/byteorder.h>
2605
2606 #include "ext4.h"
927ca606 2607@@ -799,6 +800,7 @@ struct inode *__ext4_new_inode(handle_t
76514441
AM
2608 inode->i_mode = mode;
2609 inode->i_uid = current_fsuid();
2610 inode->i_gid = dir->i_gid;
a4a22af8 2611+ i_tag_write(inode, dx_current_fstag(sb));
e22b5178 2612 } else
76514441 2613 inode_init_owner(inode, dir, mode);
927ca606 2614 err = dquot_initialize(inode);
8de2f54c 2615diff -NurpP --minimal linux-4.4.111/fs/ext4/inode.c linux-4.4.111-vs2.3.9.5/fs/ext4/inode.c
f19bd705 2616--- linux-4.4.111/fs/ext4/inode.c 2018-01-11 07:57:44.000000000 +0000
8de2f54c 2617+++ linux-4.4.111-vs2.3.9.5/fs/ext4/inode.c 2018-01-09 16:36:31.000000000 +0000
927ca606
AM
2618@@ -37,6 +37,7 @@
2619 #include <linux/printk.h>
2620 #include <linux/slab.h>
52afa9bd 2621 #include <linux/bitops.h>
d337f35e 2622+#include <linux/vs_tag.h>
ec22aa5c 2623
2380c486 2624 #include "ext4_jbd2.h"
d337f35e 2625 #include "xattr.h"
927ca606 2626@@ -4128,12 +4129,15 @@ void ext4_set_inode_flags(struct inode *
d337f35e 2627 unsigned int flags = EXT4_I(inode)->i_flags;
52afa9bd 2628 unsigned int new_fl = 0;
978063ce 2629
d337f35e 2630+ if (flags & EXT4_IMMUTABLE_FL)
52afa9bd 2631+ new_fl |= S_IMMUTABLE;
2380c486 2632+ if (flags & EXT4_IXUNLINK_FL)
52afa9bd 2633+ new_fl |= S_IXUNLINK;
978063ce 2634+
d337f35e 2635 if (flags & EXT4_SYNC_FL)
52afa9bd 2636 new_fl |= S_SYNC;
d337f35e 2637 if (flags & EXT4_APPEND_FL)
52afa9bd 2638 new_fl |= S_APPEND;
d337f35e 2639- if (flags & EXT4_IMMUTABLE_FL)
52afa9bd 2640- new_fl |= S_IMMUTABLE;
d337f35e 2641 if (flags & EXT4_NOATIME_FL)
52afa9bd 2642 new_fl |= S_NOATIME;
d337f35e 2643 if (flags & EXT4_DIRSYNC_FL)
927ca606
AM
2644@@ -4141,31 +4145,52 @@ void ext4_set_inode_flags(struct inode *
2645 if (test_opt(inode->i_sb, DAX))
2646 new_fl |= S_DAX;
ca5d134c 2647 inode_set_flags(inode, new_fl,
927ca606
AM
2648- S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX);
2649+ S_IXUNLINK | S_IMMUTABLE | S_DAX |
ca5d134c 2650+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
2380c486 2651+
978063ce 2652+ new_fl = 0;
2380c486 2653+ if (flags & EXT4_BARRIER_FL)
978063ce 2654+ new_fl |= V_BARRIER;
2380c486 2655+ if (flags & EXT4_COW_FL)
978063ce
JR
2656+ new_fl |= V_COW;
2657+
2658+ set_mask_bits(&inode->i_vflags,
2659+ V_BARRIER | V_COW, new_fl);
d337f35e
JR
2660 }
2661
2380c486
JR
2662 /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */
2663 void ext4_get_inode_flags(struct ext4_inode_info *ei)
2664 {
76514441
AM
2665- unsigned int vfs_fl;
2666+ unsigned int vfs_fl, vfs_vf;
2667 unsigned long old_fl, new_fl;
2380c486 2668
76514441
AM
2669 do {
2670 vfs_fl = ei->vfs_inode.i_flags;
2671+ vfs_vf = ei->vfs_inode.i_vflags;
2672 old_fl = ei->i_flags;
2673 new_fl = old_fl & ~(EXT4_SYNC_FL|EXT4_APPEND_FL|
2674 EXT4_IMMUTABLE_FL|EXT4_NOATIME_FL|
2675- EXT4_DIRSYNC_FL);
2676+ EXT4_DIRSYNC_FL|EXT4_BARRIER_FL|
2677+ EXT4_COW_FL);
2678+
2679+ if (vfs_fl & S_IMMUTABLE)
2680+ new_fl |= EXT4_IMMUTABLE_FL;
2681+ if (vfs_fl & S_IXUNLINK)
2682+ new_fl |= EXT4_IXUNLINK_FL;
2683+
2684 if (vfs_fl & S_SYNC)
2685 new_fl |= EXT4_SYNC_FL;
2686 if (vfs_fl & S_APPEND)
2687 new_fl |= EXT4_APPEND_FL;
2688- if (vfs_fl & S_IMMUTABLE)
2689- new_fl |= EXT4_IMMUTABLE_FL;
2690 if (vfs_fl & S_NOATIME)
2691 new_fl |= EXT4_NOATIME_FL;
2692 if (vfs_fl & S_DIRSYNC)
2693 new_fl |= EXT4_DIRSYNC_FL;
2694+
2695+ if (vfs_vf & V_BARRIER)
2696+ new_fl |= EXT4_BARRIER_FL;
2697+ if (vfs_vf & V_COW)
2698+ new_fl |= EXT4_COW_FL;
2699 } while (cmpxchg(&ei->i_flags, old_fl, new_fl) != old_fl);
ec22aa5c
AM
2700 }
2701
927ca606 2702@@ -4269,8 +4294,10 @@ struct inode *ext4_iget(struct super_blo
42bc425c
AM
2703 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
2704 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
d337f35e 2705 }
42bc425c
AM
2706- i_uid_write(inode, i_uid);
2707- i_gid_write(inode, i_gid);
2708+ i_uid_write(inode, INOTAG_UID(DX_TAG(inode), i_uid, i_gid));
2709+ i_gid_write(inode, INOTAG_GID(DX_TAG(inode), i_uid, i_gid));
537831f9
AM
2710+ i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
2711+ le16_to_cpu(raw_inode->i_raw_tag)));
f6c5ef8b 2712 set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
2380c486 2713
d33d7b00 2714 ext4_clear_state_flags(ei); /* Only relevant on 32-bit archs */
927ca606 2715@@ -4583,8 +4610,10 @@ static int ext4_do_update_inode(handle_t
d337f35e 2716
2380c486 2717 ext4_get_inode_flags(ei);
d337f35e 2718 raw_inode->i_mode = cpu_to_le16(inode->i_mode);
42bc425c
AM
2719- i_uid = i_uid_read(inode);
2720- i_gid = i_gid_read(inode);
a4a22af8
AM
2721+ i_uid = from_kuid(&init_user_ns,
2722+ TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
2723+ i_gid = from_kgid(&init_user_ns,
2724+ TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
ec22aa5c 2725 if (!(test_opt(inode->i_sb, NO_UID32))) {
42bc425c
AM
2726 raw_inode->i_uid_low = cpu_to_le16(low_16_bits(i_uid));
2727 raw_inode->i_gid_low = cpu_to_le16(low_16_bits(i_gid));
927ca606 2728@@ -4607,6 +4636,9 @@ static int ext4_do_update_inode(handle_t
d337f35e
JR
2729 raw_inode->i_uid_high = 0;
2730 raw_inode->i_gid_high = 0;
2731 }
2732+#ifdef CONFIG_TAGGING_INTERN
537831f9 2733+ raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
d337f35e
JR
2734+#endif
2735 raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
2380c486
JR
2736
2737 EXT4_INODE_SET_XTIME(i_ctime, inode, raw_inode);
927ca606
AM
2738@@ -4852,7 +4884,8 @@ int ext4_setattr(struct dentry *dentry,
2739 return error;
2740 }
42bc425c
AM
2741 if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) ||
2742- (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) {
2743+ (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid)) ||
537831f9 2744+ (ia_valid & ATTR_TAG && !tag_eq(attr->ia_tag, inode->i_tag))) {
d337f35e
JR
2745 handle_t *handle;
2746
2747 /* (user+group)*(old+new) structure, inode write (sb,
927ca606 2748@@ -4875,6 +4908,8 @@ int ext4_setattr(struct dentry *dentry,
d337f35e
JR
2749 inode->i_uid = attr->ia_uid;
2750 if (attr->ia_valid & ATTR_GID)
2751 inode->i_gid = attr->ia_gid;
2752+ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
2753+ inode->i_tag = attr->ia_tag;
2754 error = ext4_mark_inode_dirty(handle, inode);
2755 ext4_journal_stop(handle);
2756 }
8de2f54c 2757diff -NurpP --minimal linux-4.4.111/fs/ext4/ioctl.c linux-4.4.111-vs2.3.9.5/fs/ext4/ioctl.c
f19bd705 2758--- linux-4.4.111/fs/ext4/ioctl.c 2018-01-11 07:57:44.000000000 +0000
8de2f54c 2759+++ linux-4.4.111-vs2.3.9.5/fs/ext4/ioctl.c 2018-01-09 16:36:31.000000000 +0000
09be7631 2760@@ -14,6 +14,7 @@
2380c486 2761 #include <linux/mount.h>
ec22aa5c 2762 #include <linux/file.h>
927ca606 2763 #include <linux/random.h>
d337f35e
JR
2764+#include <linux/vs_tag.h>
2765 #include <asm/uaccess.h>
2380c486
JR
2766 #include "ext4_jbd2.h"
2767 #include "ext4.h"
927ca606
AM
2768@@ -202,6 +203,33 @@ static int uuid_is_zero(__u8 u[16])
2769 return 1;
09be7631 2770 }
db55b927 2771
d4263eb0
JR
2772+int ext4_sync_flags(struct inode *inode, int flags, int vflags)
2773+{
2774+ handle_t *handle = NULL;
2775+ struct ext4_iloc iloc;
2776+ int err;
2777+
b00e13aa 2778+ handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
d4263eb0
JR
2779+ if (IS_ERR(handle))
2780+ return PTR_ERR(handle);
2781+
2782+ if (IS_SYNC(inode))
2783+ ext4_handle_sync(handle);
2784+ err = ext4_reserve_inode_write(handle, inode, &iloc);
2785+ if (err)
2786+ goto flags_err;
2787+
2788+ inode->i_flags = flags;
2789+ inode->i_vflags = vflags;
2790+ ext4_get_inode_flags(EXT4_I(inode));
2791+ inode->i_ctime = ext4_current_time(inode);
2792+
2793+ err = ext4_mark_iloc_dirty(handle, inode, &iloc);
2794+flags_err:
2795+ ext4_journal_stop(handle);
2796+ return err;
2797+}
2798+
2799 long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
2800 {
b00e13aa 2801 struct inode *inode = file_inode(filp);
927ca606 2802@@ -235,6 +263,11 @@ long ext4_ioctl(struct file *filp, unsig
ec22aa5c
AM
2803
2804 flags = ext4_mask_flags(inode->i_mode, flags);
2380c486
JR
2805
2806+ if (IS_BARRIER(inode)) {
2807+ vxwprintk_task(1, "messing with the barrier.");
2808+ return -EACCES;
2809+ }
2810+
2811 err = -EPERM;
ec22aa5c
AM
2812 mutex_lock(&inode->i_mutex);
2813 /* Is it quota file? Do not allow user to mess with it */
927ca606 2814@@ -252,7 +285,9 @@ long ext4_ioctl(struct file *filp, unsig
d337f35e
JR
2815 *
2816 * This test looks nicer. Thanks to Pauline Middelink
2817 */
2818- if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
2819+ if ((oldflags & EXT4_IMMUTABLE_FL) ||
2820+ ((flags ^ oldflags) & (EXT4_APPEND_FL |
2380c486
JR
2821+ EXT4_IMMUTABLE_FL | EXT4_IXUNLINK_FL))) {
2822 if (!capable(CAP_LINUX_IMMUTABLE))
2823 goto flags_out;
2824 }
8de2f54c 2825diff -NurpP --minimal linux-4.4.111/fs/ext4/namei.c linux-4.4.111-vs2.3.9.5/fs/ext4/namei.c
f19bd705 2826--- linux-4.4.111/fs/ext4/namei.c 2018-01-11 07:57:44.000000000 +0000
8de2f54c 2827+++ linux-4.4.111-vs2.3.9.5/fs/ext4/namei.c 2018-01-09 16:36:31.000000000 +0000
927ca606 2828@@ -33,6 +33,7 @@
2380c486 2829 #include <linux/quotaops.h>
d337f35e
JR
2830 #include <linux/buffer_head.h>
2831 #include <linux/bio.h>
d337f35e 2832+#include <linux/vs_tag.h>
2380c486
JR
2833 #include "ext4.h"
2834 #include "ext4_jbd2.h"
d337f35e 2835
927ca606 2836@@ -1444,6 +1445,7 @@ restart:
a168f21d
AM
2837 ll_rw_block(READ | REQ_META | REQ_PRIO,
2838 1, &bh);
2380c486 2839 }
d337f35e 2840+ dx_propagate_tag(nd, inode);
2380c486
JR
2841 }
2842 if ((bh = bh_use[ra_ptr++]) == NULL)
2843 goto next;
927ca606 2844@@ -3881,6 +3883,7 @@ const struct inode_operations ext4_dir_i
a168f21d 2845 .get_acl = ext4_get_acl,
bb20add7 2846 .set_acl = ext4_set_acl,
d4263eb0 2847 .fiemap = ext4_fiemap,
d337f35e
JR
2848+ .sync_flags = ext4_sync_flags,
2849 };
d4263eb0
JR
2850
2851 const struct inode_operations ext4_special_inode_operations = {
8de2f54c 2852diff -NurpP --minimal linux-4.4.111/fs/ext4/super.c linux-4.4.111-vs2.3.9.5/fs/ext4/super.c
f19bd705 2853--- linux-4.4.111/fs/ext4/super.c 2018-01-11 07:57:44.000000000 +0000
8de2f54c 2854+++ linux-4.4.111-vs2.3.9.5/fs/ext4/super.c 2018-01-09 16:36:32.000000000 +0000
927ca606 2855@@ -1165,6 +1165,7 @@ enum {
78865d5b 2856 Opt_dioread_nolock, Opt_dioread_lock,
dd5f3080 2857 Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
927ca606
AM
2858 Opt_max_dir_size_kb, Opt_nojournal_checksum,
2859+ Opt_tag, Opt_notag, Opt_tagid
d337f35e
JR
2860 };
2861
ec22aa5c 2862 static const match_table_t tokens = {
927ca606 2863@@ -1250,6 +1251,9 @@ static const match_table_t tokens = {
1e8b8f9b
AM
2864 {Opt_removed, "reservation"}, /* mount option from ext2/3 */
2865 {Opt_removed, "noreservation"}, /* mount option from ext2/3 */
2866 {Opt_removed, "journal=%u"}, /* mount option from ext2/3 */
d337f35e
JR
2867+ {Opt_tag, "tag"},
2868+ {Opt_notag, "notag"},
2869+ {Opt_tagid, "tagid=%u"},
d337f35e 2870 {Opt_err, NULL},
d337f35e 2871 };
2380c486 2872
927ca606
AM
2873@@ -1492,6 +1496,20 @@ static int handle_mount_opt(struct super
2874 case Opt_nolazytime:
2875 sb->s_flags &= ~MS_LAZYTIME;
1e8b8f9b 2876 return 1;
d337f35e 2877+#ifndef CONFIG_TAGGING_NONE
1e8b8f9b
AM
2878+ case Opt_tag:
2879+ set_opt(sb, TAGGED);
2880+ return 1;
2881+ case Opt_notag:
2882+ clear_opt(sb, TAGGED);
2883+ return 1;
d337f35e
JR
2884+#endif
2885+#ifdef CONFIG_PROPAGATE
1e8b8f9b
AM
2886+ case Opt_tagid:
2887+ /* use args[0] */
2888+ set_opt(sb, TAGGED);
2889+ return 1;
d337f35e 2890+#endif
1e8b8f9b
AM
2891 }
2892
b00e13aa 2893 for (m = ext4_mount_opts; m->token != Opt_err; m++)
927ca606
AM
2894@@ -3379,6 +3397,9 @@ static int ext4_fill_super(struct super_
2895 sb->s_iflags |= SB_I_CGROUPWB;
f6c5ef8b 2896 }
d337f35e
JR
2897
2898+ if (EXT4_SB(sb)->s_mount_opt & EXT4_MOUNT_TAGGED)
2899+ sb->s_flags |= MS_TAGGED;
2900+
2901 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
78865d5b 2902 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
d337f35e 2903
927ca606 2904@@ -4727,6 +4748,14 @@ static int ext4_remount(struct super_blo
ec22aa5c 2905 if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED)
93de0823 2906 ext4_abort(sb, "Abort forced by user");
2380c486 2907
d337f35e
JR
2908+ if ((sbi->s_mount_opt & EXT4_MOUNT_TAGGED) &&
2909+ !(sb->s_flags & MS_TAGGED)) {
2910+ printk("EXT4-fs: %s: tagging not permitted on remount.\n",
2911+ sb->s_id);
d4263eb0
JR
2912+ err = -EINVAL;
2913+ goto restore_opts;
d337f35e 2914+ }
2380c486 2915+
d337f35e 2916 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
78865d5b 2917 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
d337f35e 2918
8de2f54c 2919diff -NurpP --minimal linux-4.4.111/fs/fcntl.c linux-4.4.111-vs2.3.9.5/fs/fcntl.c
f19bd705 2920--- linux-4.4.111/fs/fcntl.c 2018-01-11 07:57:44.000000000 +0000
8de2f54c 2921+++ linux-4.4.111-vs2.3.9.5/fs/fcntl.c 2018-01-09 16:36:32.000000000 +0000
bb20add7 2922@@ -22,6 +22,7 @@
2380c486 2923 #include <linux/pid_namespace.h>
92598135 2924 #include <linux/user_namespace.h>
bb20add7 2925 #include <linux/shmem_fs.h>
d337f35e
JR
2926+#include <linux/vs_limit.h>
2927
2928 #include <asm/poll.h>
2929 #include <asm/siginfo.h>
bb20add7 2930@@ -385,6 +386,8 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, f
d337f35e 2931
537831f9 2932 if (!f.file)
2380c486
JR
2933 goto out;
2934+ if (!vx_files_avail(1))
2935+ goto out;
2936
537831f9 2937 if (unlikely(f.file->f_mode & FMODE_PATH)) {
42bc425c 2938 if (!check_fcntl_cmd(cmd))
8de2f54c 2939diff -NurpP --minimal linux-4.4.111/fs/file.c linux-4.4.111-vs2.3.9.5/fs/file.c
f19bd705 2940--- linux-4.4.111/fs/file.c 2016-07-05 04:15:07.000000000 +0000
8de2f54c 2941+++ linux-4.4.111-vs2.3.9.5/fs/file.c 2018-01-09 16:36:32.000000000 +0000
537831f9 2942@@ -22,6 +22,7 @@
2380c486
JR
2943 #include <linux/spinlock.h>
2944 #include <linux/rcupdate.h>
2945 #include <linux/workqueue.h>
2946+#include <linux/vs_limit.h>
2947
09be7631
JR
2948 int sysctl_nr_open __read_mostly = 1024*1024;
2949 int sysctl_nr_open_min = BITS_PER_LONG;
927ca606 2950@@ -356,6 +357,8 @@ struct files_struct *dup_fd(struct files
2380c486
JR
2951 struct file *f = *old_fds++;
2952 if (f) {
2953 get_file(f);
2954+ /* TODO: sum it first for check and performance */
2955+ vx_openfd_inc(open_files - i);
2956 } else {
2957 /*
2958 * The fd may be claimed in the fd bitmap but not yet
927ca606 2959@@ -405,9 +408,11 @@ static struct fdtable *close_files(struc
537831f9 2960 filp_close(file, files);
bb20add7 2961 cond_resched_rcu_qs();
537831f9
AM
2962 }
2963+ vx_openfd_dec(i);
2964 }
2965 i++;
2966 set >>= 1;
2967+ cond_resched();
2968 }
2969 }
bb20add7 2970
927ca606 2971@@ -538,6 +543,7 @@ repeat:
2380c486 2972 else
1e8b8f9b 2973 __clear_close_on_exec(fd, fdt);
2380c486
JR
2974 error = fd;
2975+ vx_openfd_inc(fd);
2976 #if 1
2977 /* Sanity check */
bb20add7 2978 if (rcu_access_pointer(fdt->fd[fd]) != NULL) {
927ca606 2979@@ -568,6 +574,7 @@ static void __put_unused_fd(struct files
537831f9
AM
2980 __clear_open_fd(fd, fdt);
2981 if (fd < files->next_fd)
2982 files->next_fd = fd;
2983+ vx_openfd_dec(fd);
2984 }
2985
2986 void put_unused_fd(unsigned int fd)
927ca606 2987@@ -850,6 +857,8 @@ __releases(&files->file_lock)
537831f9
AM
2988
2989 if (tofree)
2990 filp_close(tofree, files);
2991+ else
2992+ vx_openfd_inc(fd); /* fd was unused */
2993
2994 return fd;
2995
8de2f54c 2996diff -NurpP --minimal linux-4.4.111/fs/file_table.c linux-4.4.111-vs2.3.9.5/fs/file_table.c
f19bd705 2997--- linux-4.4.111/fs/file_table.c 2015-10-29 09:21:35.000000000 +0000
8de2f54c 2998+++ linux-4.4.111-vs2.3.9.5/fs/file_table.c 2018-01-09 17:25:51.000000000 +0000
92598135 2999@@ -26,6 +26,8 @@
92598135 3000 #include <linux/task_work.h>
2bf5ad28 3001 #include <linux/ima.h>
927ca606 3002 #include <linux/swap.h>
d337f35e
JR
3003+#include <linux/vs_limit.h>
3004+#include <linux/vs_context.h>
3005
a168f21d 3006 #include <linux/atomic.h>
d337f35e 3007
c2e5f7c8 3008@@ -137,6 +139,8 @@ struct file *get_empty_filp(void)
bb20add7 3009 mutex_init(&f->f_pos_lock);
d337f35e
JR
3010 eventpoll_init_file(f);
3011 /* f->f_version: 0 */
3012+ f->f_xid = vx_current_xid();
3013+ vx_files_inc(f);
3014 return f;
3015
3016 over:
bb20add7 3017@@ -219,6 +223,8 @@ static void __fput(struct file *file)
265de2f7
JR
3018 put_write_access(inode);
3019 __mnt_drop_write(mnt);
3020 }
d337f35e
JR
3021+ vx_files_dec(file);
3022+ file->f_xid = 0;
92598135
AM
3023 file->f_path.dentry = NULL;
3024 file->f_path.mnt = NULL;
b00e13aa 3025 file->f_inode = NULL;
bb20add7 3026@@ -305,6 +311,8 @@ void put_filp(struct file *file)
d337f35e 3027 {
2380c486 3028 if (atomic_long_dec_and_test(&file->f_count)) {
d337f35e
JR
3029 security_file_free(file);
3030+ vx_files_dec(file);
3031+ file->f_xid = 0;
d337f35e
JR
3032 file_free(file);
3033 }
c2e5f7c8 3034 }
8de2f54c 3035diff -NurpP --minimal linux-4.4.111/fs/fs_struct.c linux-4.4.111-vs2.3.9.5/fs/fs_struct.c
f19bd705 3036--- linux-4.4.111/fs/fs_struct.c 2015-04-12 22:12:50.000000000 +0000
8de2f54c 3037+++ linux-4.4.111-vs2.3.9.5/fs/fs_struct.c 2018-01-09 16:36:32.000000000 +0000
ec22aa5c
AM
3038@@ -4,6 +4,7 @@
3039 #include <linux/path.h>
3040 #include <linux/slab.h>
3041 #include <linux/fs_struct.h>
3042+#include <linux/vserver/global.h>
d33d7b00 3043 #include "internal.h"
ec22aa5c 3044
92598135
AM
3045 /*
3046@@ -87,6 +88,7 @@ void free_fs_struct(struct fs_struct *fs
ec22aa5c 3047 {
92598135
AM
3048 path_put(&fs->root);
3049 path_put(&fs->pwd);
ec22aa5c
AM
3050+ atomic_dec(&vs_global_fs);
3051 kmem_cache_free(fs_cachep, fs);
3052 }
3053
537831f9 3054@@ -124,6 +126,7 @@ struct fs_struct *copy_fs_struct(struct
d33d7b00 3055 fs->pwd = old->pwd;
92598135 3056 path_get(&fs->pwd);
d33d7b00 3057 spin_unlock(&old->lock);
ec22aa5c
AM
3058+ atomic_inc(&vs_global_fs);
3059 }
3060 return fs;
3061 }
8de2f54c 3062diff -NurpP --minimal linux-4.4.111/fs/gfs2/file.c linux-4.4.111-vs2.3.9.5/fs/gfs2/file.c
f19bd705 3063--- linux-4.4.111/fs/gfs2/file.c 2018-01-11 07:57:44.000000000 +0000
8de2f54c 3064+++ linux-4.4.111-vs2.3.9.5/fs/gfs2/file.c 2018-01-09 17:23:53.000000000 +0000
927ca606 3065@@ -137,6 +137,9 @@ static const u32 fsflags_to_gfs2[32] = {
e22b5178
AM
3066 [12] = GFS2_DIF_EXHASH,
3067 [14] = GFS2_DIF_INHERIT_JDATA,
92598135 3068 [17] = GFS2_DIF_TOPDIR,
e22b5178
AM
3069+ [27] = GFS2_DIF_IXUNLINK,
3070+ [26] = GFS2_DIF_BARRIER,
3071+ [29] = GFS2_DIF_COW,
3072 };
3073
3074 static const u32 gfs2_to_fsflags[32] = {
927ca606 3075@@ -147,6 +150,9 @@ static const u32 gfs2_to_fsflags[32] = {
e22b5178 3076 [gfs2fl_ExHash] = FS_INDEX_FL,
92598135 3077 [gfs2fl_TopLevel] = FS_TOPDIR_FL,
e22b5178
AM
3078 [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL,
3079+ [gfs2fl_IXUnlink] = FS_IXUNLINK_FL,
3080+ [gfs2fl_Barrier] = FS_BARRIER_FL,
3081+ [gfs2fl_Cow] = FS_COW_FL,
3082 };
3083
3084 static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
927ca606 3085@@ -177,12 +183,17 @@ void gfs2_set_inode_flags(struct inode *
e22b5178
AM
3086 {
3087 struct gfs2_inode *ip = GFS2_I(inode);
3088 unsigned int flags = inode->i_flags;
3089+ unsigned int vflags = inode->i_vflags;
e22b5178 3090
a168f21d 3091- flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_NOSEC);
927ca606
AM
3092+ flags &= ~(S_IMMUTABLE | S_IXUNLINK |
3093+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC | S_NOSEC);
3094+
a168f21d 3095 if ((ip->i_eattr == 0) && !is_sxid(inode->i_mode))
927ca606 3096 flags |= S_NOSEC;
e22b5178
AM
3097 if (ip->i_diskflags & GFS2_DIF_IMMUTABLE)
3098 flags |= S_IMMUTABLE;
3099+ if (ip->i_diskflags & GFS2_DIF_IXUNLINK)
3100+ flags |= S_IXUNLINK;
e22b5178
AM
3101 if (ip->i_diskflags & GFS2_DIF_APPENDONLY)
3102 flags |= S_APPEND;
3103 if (ip->i_diskflags & GFS2_DIF_NOATIME)
927ca606 3104@@ -190,6 +201,43 @@ void gfs2_set_inode_flags(struct inode *
e22b5178
AM
3105 if (ip->i_diskflags & GFS2_DIF_SYNC)
3106 flags |= S_SYNC;
3107 inode->i_flags = flags;
3108+
3109+ vflags &= ~(V_BARRIER | V_COW);
3110+
3111+ if (ip->i_diskflags & GFS2_DIF_BARRIER)
3112+ vflags |= V_BARRIER;
3113+ if (ip->i_diskflags & GFS2_DIF_COW)
3114+ vflags |= V_COW;
3115+ inode->i_vflags = vflags;
3116+}
3117+
3118+void gfs2_get_inode_flags(struct inode *inode)
3119+{
3120+ struct gfs2_inode *ip = GFS2_I(inode);
3121+ unsigned int flags = inode->i_flags;
3122+ unsigned int vflags = inode->i_vflags;
3123+
3124+ ip->i_diskflags &= ~(GFS2_DIF_APPENDONLY |
3125+ GFS2_DIF_NOATIME | GFS2_DIF_SYNC |
3126+ GFS2_DIF_IMMUTABLE | GFS2_DIF_IXUNLINK |
3127+ GFS2_DIF_BARRIER | GFS2_DIF_COW);
3128+
3129+ if (flags & S_IMMUTABLE)
3130+ ip->i_diskflags |= GFS2_DIF_IMMUTABLE;
3131+ if (flags & S_IXUNLINK)
3132+ ip->i_diskflags |= GFS2_DIF_IXUNLINK;
3133+
3134+ if (flags & S_APPEND)
3135+ ip->i_diskflags |= GFS2_DIF_APPENDONLY;
3136+ if (flags & S_NOATIME)
3137+ ip->i_diskflags |= GFS2_DIF_NOATIME;
3138+ if (flags & S_SYNC)
3139+ ip->i_diskflags |= GFS2_DIF_SYNC;
3140+
3141+ if (vflags & V_BARRIER)
3142+ ip->i_diskflags |= GFS2_DIF_BARRIER;
3143+ if (vflags & V_COW)
3144+ ip->i_diskflags |= GFS2_DIF_COW;
3145 }
3146
3147 /* Flags that can be set by user space */
927ca606 3148@@ -305,6 +353,37 @@ static int gfs2_set_flags(struct file *f
e22b5178
AM
3149 return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_JDATA);
3150 }
3151
3152+int gfs2_sync_flags(struct inode *inode, int flags, int vflags)
3153+{
3154+ struct gfs2_inode *ip = GFS2_I(inode);
3155+ struct gfs2_sbd *sdp = GFS2_SB(inode);
3156+ struct buffer_head *bh;
3157+ struct gfs2_holder gh;
3158+ int error;
3159+
3160+ error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
3161+ if (error)
3162+ return error;
3163+ error = gfs2_trans_begin(sdp, RES_DINODE, 0);
3164+ if (error)
3165+ goto out;
3166+ error = gfs2_meta_inode_buffer(ip, &bh);
3167+ if (error)
3168+ goto out_trans_end;
b00e13aa 3169+ gfs2_trans_add_meta(ip->i_gl, bh);
e22b5178
AM
3170+ inode->i_flags = flags;
3171+ inode->i_vflags = vflags;
3172+ gfs2_get_inode_flags(inode);
3173+ gfs2_dinode_out(ip, bh->b_data);
3174+ brelse(bh);
3175+ gfs2_set_aops(inode);
3176+out_trans_end:
3177+ gfs2_trans_end(sdp);
3178+out:
3179+ gfs2_glock_dq_uninit(&gh);
3180+ return error;
3181+}
3182+
3183 static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
3184 {
3185 switch(cmd) {
8de2f54c 3186diff -NurpP --minimal linux-4.4.111/fs/gfs2/inode.h linux-4.4.111-vs2.3.9.5/fs/gfs2/inode.h
f19bd705 3187--- linux-4.4.111/fs/gfs2/inode.h 2015-04-12 22:12:50.000000000 +0000
8de2f54c 3188+++ linux-4.4.111-vs2.3.9.5/fs/gfs2/inode.h 2018-01-09 16:36:32.000000000 +0000
c2e5f7c8 3189@@ -118,6 +118,7 @@ extern const struct file_operations gfs2
e22b5178
AM
3190 extern const struct file_operations gfs2_dir_fops_nolock;
3191
3192 extern void gfs2_set_inode_flags(struct inode *inode);
3193+extern int gfs2_sync_flags(struct inode *inode, int flags, int vflags);
3194
3195 #ifdef CONFIG_GFS2_FS_LOCKING_DLM
3196 extern const struct file_operations gfs2_file_fops;
8de2f54c 3197diff -NurpP --minimal linux-4.4.111/fs/hostfs/hostfs.h linux-4.4.111-vs2.3.9.5/fs/hostfs/hostfs.h
f19bd705 3198--- linux-4.4.111/fs/hostfs/hostfs.h 2015-07-06 20:41:42.000000000 +0000
8de2f54c 3199+++ linux-4.4.111-vs2.3.9.5/fs/hostfs/hostfs.h 2018-01-09 16:36:32.000000000 +0000
537831f9
AM
3200@@ -42,6 +42,7 @@ struct hostfs_iattr {
3201 unsigned short ia_mode;
3202 uid_t ia_uid;
3203 gid_t ia_gid;
61333608 3204+ vtag_t ia_tag;
537831f9
AM
3205 loff_t ia_size;
3206 struct timespec ia_atime;
3207 struct timespec ia_mtime;
8de2f54c 3208diff -NurpP --minimal linux-4.4.111/fs/inode.c linux-4.4.111-vs2.3.9.5/fs/inode.c
f19bd705 3209--- linux-4.4.111/fs/inode.c 2018-01-11 07:57:45.000000000 +0000
8de2f54c 3210+++ linux-4.4.111-vs2.3.9.5/fs/inode.c 2018-01-09 16:36:32.000000000 +0000
c2e5f7c8 3211@@ -18,6 +18,7 @@
763640ca 3212 #include <linux/buffer_head.h> /* for inode_has_buffers */
db55b927 3213 #include <linux/ratelimit.h>
c2e5f7c8 3214 #include <linux/list_lru.h>
76514441 3215+#include <linux/vs_tag.h>
927ca606 3216 #include <trace/events/writeback.h>
763640ca 3217 #include "internal.h"
76514441 3218
927ca606 3219@@ -133,6 +134,8 @@ int inode_init_always(struct super_block
ec22aa5c
AM
3220 struct address_space *const mapping = &inode->i_data;
3221
3222 inode->i_sb = sb;
3223+
3224+ /* essential because of inode slab reuse */
ec22aa5c
AM
3225 inode->i_blkbits = sb->s_blocksize_bits;
3226 inode->i_flags = 0;
3227 atomic_set(&inode->i_count, 1);
927ca606 3228@@ -142,6 +145,7 @@ int inode_init_always(struct super_block
537831f9
AM
3229 inode->i_opflags = 0;
3230 i_uid_write(inode, 0);
3231 i_gid_write(inode, 0);
3232+ i_tag_write(inode, 0);
3233 atomic_set(&inode->i_writecount, 0);
3234 inode->i_size = 0;
3235 inode->i_blocks = 0;
927ca606 3236@@ -152,6 +156,7 @@ int inode_init_always(struct super_block
ec22aa5c 3237 inode->i_cdev = NULL;
927ca606 3238 inode->i_link = NULL;
ec22aa5c
AM
3239 inode->i_rdev = 0;
3240+ inode->i_mdev = 0;
3241 inode->dirtied_when = 0;
3242
3243 if (security_inode_alloc(inode))
927ca606 3244@@ -469,6 +474,8 @@ void __insert_inode_hash(struct inode *i
d337f35e 3245 }
763640ca 3246 EXPORT_SYMBOL(__insert_inode_hash);
d337f35e
JR
3247
3248+EXPORT_SYMBOL_GPL(__iget);
3249+
3250 /**
a168f21d 3251 * __remove_inode_hash - remove an inode from the hash
ab30d09f 3252 * @inode: inode to unhash
927ca606 3253@@ -1911,9 +1918,11 @@ void init_special_inode(struct inode *in
2380c486
JR
3254 if (S_ISCHR(mode)) {
3255 inode->i_fop = &def_chr_fops;
3256 inode->i_rdev = rdev;
3257+ inode->i_mdev = rdev;
3258 } else if (S_ISBLK(mode)) {
3259 inode->i_fop = &def_blk_fops;
3260 inode->i_rdev = rdev;
3261+ inode->i_mdev = rdev;
3262 } else if (S_ISFIFO(mode))
09be7631 3263 inode->i_fop = &pipefifo_fops;
2380c486 3264 else if (S_ISSOCK(mode))
927ca606 3265@@ -1942,6 +1951,7 @@ void inode_init_owner(struct inode *inod
76514441
AM
3266 } else
3267 inode->i_gid = current_fsgid();
3268 inode->i_mode = mode;
8ce283e1 3269+ i_tag_write(inode, dx_current_fstag(inode->i_sb));
76514441
AM
3270 }
3271 EXPORT_SYMBOL(inode_init_owner);
763640ca 3272
8de2f54c 3273diff -NurpP --minimal linux-4.4.111/fs/ioctl.c linux-4.4.111-vs2.3.9.5/fs/ioctl.c
f19bd705 3274--- linux-4.4.111/fs/ioctl.c 2015-04-12 22:12:50.000000000 +0000
8de2f54c 3275+++ linux-4.4.111-vs2.3.9.5/fs/ioctl.c 2018-01-09 16:36:32.000000000 +0000
ab30d09f 3276@@ -15,6 +15,9 @@
ec22aa5c
AM
3277 #include <linux/writeback.h>
3278 #include <linux/buffer_head.h>
3279 #include <linux/falloc.h>
d337f35e
JR
3280+#include <linux/proc_fs.h>
3281+#include <linux/vserver/inode.h>
3282+#include <linux/vs_tag.h>
3283
d337f35e
JR
3284 #include <asm/ioctls.h>
3285
8de2f54c 3286diff -NurpP --minimal linux-4.4.111/fs/jfs/file.c linux-4.4.111-vs2.3.9.5/fs/jfs/file.c
f19bd705 3287--- linux-4.4.111/fs/jfs/file.c 2016-07-05 04:12:33.000000000 +0000
8de2f54c 3288+++ linux-4.4.111-vs2.3.9.5/fs/jfs/file.c 2018-01-09 16:36:32.000000000 +0000
927ca606
AM
3289@@ -113,7 +113,8 @@ int jfs_setattr(struct dentry *dentry, s
3290 return rc;
3291 }
537831f9
AM
3292 if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) ||
3293- (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) {
3294+ (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid)) ||
3295+ (iattr->ia_valid & ATTR_TAG && !tag_eq(iattr->ia_tag, inode->i_tag))) {
78865d5b
AM
3296 rc = dquot_transfer(inode, iattr);
3297 if (rc)
3298 return rc;
927ca606 3299@@ -149,6 +150,7 @@ const struct inode_operations jfs_file_i
a168f21d 3300 .get_acl = jfs_get_acl,
bb20add7 3301 .set_acl = jfs_set_acl,
d337f35e
JR
3302 #endif
3303+ .sync_flags = jfs_sync_flags,
3304 };
3305
3306 const struct file_operations jfs_file_operations = {
8de2f54c 3307diff -NurpP --minimal linux-4.4.111/fs/jfs/ioctl.c linux-4.4.111-vs2.3.9.5/fs/jfs/ioctl.c
f19bd705 3308--- linux-4.4.111/fs/jfs/ioctl.c 2015-10-29 09:21:36.000000000 +0000
8de2f54c 3309+++ linux-4.4.111-vs2.3.9.5/fs/jfs/ioctl.c 2018-01-09 16:36:32.000000000 +0000
537831f9 3310@@ -12,6 +12,7 @@
d337f35e 3311 #include <linux/time.h>
2380c486 3312 #include <linux/sched.h>
537831f9 3313 #include <linux/blkdev.h>
d337f35e
JR
3314+#include <linux/mount.h>
3315 #include <asm/current.h>
3316 #include <asm/uaccess.h>
3317
537831f9 3318@@ -56,6 +57,16 @@ static long jfs_map_ext2(unsigned long f
d4263eb0
JR
3319 }
3320
3321
3322+int jfs_sync_flags(struct inode *inode, int flags, int vflags)
3323+{
3324+ inode->i_flags = flags;
3325+ inode->i_vflags = vflags;
3326+ jfs_get_inode_flags(JFS_IP(inode));
3327+ inode->i_ctime = CURRENT_TIME_SEC;
3328+ mark_inode_dirty(inode);
3329+ return 0;
3330+}
3331+
3332 long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
3333 {
b00e13aa 3334 struct inode *inode = file_inode(filp);
537831f9 3335@@ -89,6 +100,11 @@ long jfs_ioctl(struct file *filp, unsign
2380c486
JR
3336 if (!S_ISDIR(inode->i_mode))
3337 flags &= ~JFS_DIRSYNC_FL;
d337f35e 3338
2380c486
JR
3339+ if (IS_BARRIER(inode)) {
3340+ vxwprintk_task(1, "messing with the barrier.");
3341+ return -EACCES;
3342+ }
3343+
3344 /* Is it quota file? Do not allow user to mess with it */
3345 if (IS_NOQUOTA(inode)) {
3346 err = -EPERM;
537831f9 3347@@ -106,8 +122,8 @@ long jfs_ioctl(struct file *filp, unsign
d337f35e
JR
3348 * the relevant capability.
3349 */
3350 if ((oldflags & JFS_IMMUTABLE_FL) ||
3351- ((flags ^ oldflags) &
3352- (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
3353+ ((flags ^ oldflags) & (JFS_APPEND_FL |
2380c486
JR
3354+ JFS_IMMUTABLE_FL | JFS_IXUNLINK_FL))) {
3355 if (!capable(CAP_LINUX_IMMUTABLE)) {
3356 mutex_unlock(&inode->i_mutex);
3357 err = -EPERM;
537831f9 3358@@ -115,7 +131,7 @@ long jfs_ioctl(struct file *filp, unsign
d4263eb0
JR
3359 }
3360 }
3361
3362- flags = flags & JFS_FL_USER_MODIFIABLE;
3363+ flags &= JFS_FL_USER_MODIFIABLE;
3364 flags |= oldflags & ~JFS_FL_USER_MODIFIABLE;
3365 jfs_inode->mode2 = flags;
3366
8de2f54c 3367diff -NurpP --minimal linux-4.4.111/fs/jfs/jfs_dinode.h linux-4.4.111-vs2.3.9.5/fs/jfs/jfs_dinode.h
f19bd705 3368--- linux-4.4.111/fs/jfs/jfs_dinode.h 2015-04-12 22:12:50.000000000 +0000
8de2f54c 3369+++ linux-4.4.111-vs2.3.9.5/fs/jfs/jfs_dinode.h 2018-01-09 16:36:32.000000000 +0000
2380c486
JR
3370@@ -161,9 +161,13 @@ struct dinode {
3371
d337f35e
JR
3372 #define JFS_APPEND_FL 0x01000000 /* writes to file may only append */
3373 #define JFS_IMMUTABLE_FL 0x02000000 /* Immutable file */
2380c486 3374+#define JFS_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */
d337f35e
JR
3375
3376-#define JFS_FL_USER_VISIBLE 0x03F80000
2380c486 3377-#define JFS_FL_USER_MODIFIABLE 0x03F80000
d337f35e 3378+#define JFS_BARRIER_FL 0x04000000 /* Barrier for chroot() */
2380c486 3379+#define JFS_COW_FL 0x20000000 /* Copy on Write marker */
d337f35e 3380+
2380c486
JR
3381+#define JFS_FL_USER_VISIBLE 0x07F80000
3382+#define JFS_FL_USER_MODIFIABLE 0x07F80000
3383 #define JFS_FL_INHERIT 0x03C80000
d337f35e
JR
3384
3385 /* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */
8de2f54c 3386diff -NurpP --minimal linux-4.4.111/fs/jfs/jfs_filsys.h linux-4.4.111-vs2.3.9.5/fs/jfs/jfs_filsys.h
f19bd705 3387--- linux-4.4.111/fs/jfs/jfs_filsys.h 2015-04-12 22:12:50.000000000 +0000
8de2f54c 3388+++ linux-4.4.111-vs2.3.9.5/fs/jfs/jfs_filsys.h 2018-01-09 16:36:32.000000000 +0000
537831f9 3389@@ -266,6 +266,7 @@
ec22aa5c
AM
3390 #define JFS_NAME_MAX 255
3391 #define JFS_PATH_MAX BPSIZE
bd427b06 3392
ec22aa5c 3393+#define JFS_TAGGED 0x00800000 /* Context Tagging */
bd427b06 3394
ec22aa5c
AM
3395 /*
3396 * file system state (superblock state)
8de2f54c 3397diff -NurpP --minimal linux-4.4.111/fs/jfs/jfs_imap.c linux-4.4.111-vs2.3.9.5/fs/jfs/jfs_imap.c
f19bd705 3398--- linux-4.4.111/fs/jfs/jfs_imap.c 2015-04-12 22:12:50.000000000 +0000
8de2f54c 3399+++ linux-4.4.111-vs2.3.9.5/fs/jfs/jfs_imap.c 2018-01-09 16:36:32.000000000 +0000
78865d5b 3400@@ -46,6 +46,7 @@
ec22aa5c
AM
3401 #include <linux/pagemap.h>
3402 #include <linux/quotaops.h>
78865d5b 3403 #include <linux/slab.h>
ec22aa5c 3404+#include <linux/vs_tag.h>
bd427b06 3405
ec22aa5c
AM
3406 #include "jfs_incore.h"
3407 #include "jfs_inode.h"
c2e5f7c8 3408@@ -3047,6 +3048,8 @@ static int copy_from_dinode(struct dinod
ec22aa5c
AM
3409 {
3410 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3411 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
a4a22af8
AM
3412+ kuid_t kuid;
3413+ kgid_t kgid;
bd427b06 3414
ec22aa5c
AM
3415 jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
3416 jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
c2e5f7c8 3417@@ -3067,14 +3070,18 @@ static int copy_from_dinode(struct dinod
d337f35e 3418 }
f6c5ef8b 3419 set_nlink(ip, le32_to_cpu(dip->di_nlink));
bd427b06 3420
537831f9 3421- jfs_ip->saved_uid = make_kuid(&init_user_ns, le32_to_cpu(dip->di_uid));
a4a22af8
AM
3422+ kuid = make_kuid(&init_user_ns, le32_to_cpu(dip->di_uid));
3423+ kgid = make_kgid(&init_user_ns, le32_to_cpu(dip->di_gid));
3424+ ip->i_tag = INOTAG_KTAG(DX_TAG(ip), kuid, kgid, GLOBAL_ROOT_TAG);
ec22aa5c 3425+
a4a22af8 3426+ jfs_ip->saved_uid = INOTAG_KUID(DX_TAG(ip), kuid, kgid);
537831f9 3427 if (!uid_valid(sbi->uid))
ec22aa5c
AM
3428 ip->i_uid = jfs_ip->saved_uid;
3429 else {
3430 ip->i_uid = sbi->uid;
bd427b06
AM
3431 }
3432
537831f9 3433- jfs_ip->saved_gid = make_kgid(&init_user_ns, le32_to_cpu(dip->di_gid));
a4a22af8 3434+ jfs_ip->saved_gid = INOTAG_KGID(DX_TAG(ip), kuid, kgid);
537831f9 3435 if (!gid_valid(sbi->gid))
d337f35e
JR
3436 ip->i_gid = jfs_ip->saved_gid;
3437 else {
c2e5f7c8 3438@@ -3139,16 +3146,14 @@ static void copy_to_dinode(struct dinode
d337f35e
JR
3439 dip->di_size = cpu_to_le64(ip->i_size);
3440 dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
3441 dip->di_nlink = cpu_to_le32(ip->i_nlink);
537831f9
AM
3442- if (!uid_valid(sbi->uid))
3443- dip->di_uid = cpu_to_le32(i_uid_read(ip));
d337f35e 3444- else
537831f9
AM
3445- dip->di_uid =cpu_to_le32(from_kuid(&init_user_ns,
3446- jfs_ip->saved_uid));
3447- if (!gid_valid(sbi->gid))
3448- dip->di_gid = cpu_to_le32(i_gid_read(ip));
d337f35e 3449- else
537831f9
AM
3450- dip->di_gid = cpu_to_le32(from_kgid(&init_user_ns,
3451- jfs_ip->saved_gid));
3452+ dip->di_uid = cpu_to_le32(from_kuid(&init_user_ns,
a4a22af8 3453+ TAGINO_KUID(DX_TAG(ip),
537831f9
AM
3454+ !uid_valid(sbi->uid) ? ip->i_uid : jfs_ip->saved_uid,
3455+ ip->i_tag)));
a4a22af8
AM
3456+ dip->di_gid = cpu_to_le32(from_kgid(&init_user_ns,
3457+ TAGINO_KGID(DX_TAG(ip),
537831f9
AM
3458+ !gid_valid(sbi->gid) ? ip->i_gid : jfs_ip->saved_gid,
3459+ ip->i_tag)));
2380c486 3460 jfs_get_inode_flags(jfs_ip);
d337f35e
JR
3461 /*
3462 * mode2 is only needed for storing the higher order bits.
8de2f54c 3463diff -NurpP --minimal linux-4.4.111/fs/jfs/jfs_inode.c linux-4.4.111-vs2.3.9.5/fs/jfs/jfs_inode.c
f19bd705 3464--- linux-4.4.111/fs/jfs/jfs_inode.c 2016-07-05 04:12:33.000000000 +0000
8de2f54c 3465+++ linux-4.4.111-vs2.3.9.5/fs/jfs/jfs_inode.c 2018-01-14 06:39:51.000000000 +0000
e22b5178
AM
3466@@ -18,6 +18,7 @@
3467
3468 #include <linux/fs.h>
3469 #include <linux/quotaops.h>
3470+#include <linux/vs_tag.h>
3471 #include "jfs_incore.h"
3472 #include "jfs_inode.h"
3473 #include "jfs_filsys.h"
8de2f54c 3474@@ -33,6 +34,9 @@ void jfs_set_inode_flags(struct inode *i
d337f35e
JR
3475
3476 if (flags & JFS_IMMUTABLE_FL)
bb20add7 3477 new_fl |= S_IMMUTABLE;
2380c486 3478+ if (flags & JFS_IXUNLINK_FL)
8de2f54c 3479+ new_fl |= S_IXUNLINK;
d337f35e 3480+
d337f35e 3481 if (flags & JFS_APPEND_FL)
bb20add7 3482 new_fl |= S_APPEND;
d337f35e 3483 if (flags & JFS_NOATIME_FL)
8de2f54c 3484@@ -41,18 +45,35 @@ void jfs_set_inode_flags(struct inode *i
bb20add7 3485 new_fl |= S_DIRSYNC;
8de2f54c
AM
3486 if (flags & JFS_SYNC_FL)
3487 new_fl |= S_SYNC;
bb20add7 3488- inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND | S_NOATIME |
8de2f54c
AM
3489- S_DIRSYNC | S_SYNC);
3490+
3491+ inode_set_flags(inode, new_fl, S_IMMUTABLE | S_IXUNLINK |
3492+ S_APPEND | S_NOATIME | S_DIRSYNC | S_SYNC);
2380c486 3493+
bb20add7 3494+ new_fl = 0;
2380c486 3495+ if (flags & JFS_BARRIER_FL)
bb20add7 3496+ new_fl |= V_BARRIER;
2380c486 3497+ if (flags & JFS_COW_FL)
bb20add7
AM
3498+ new_fl |= V_COW;
3499+
3500+ set_mask_bits(&inode->i_vflags,
3501+ V_BARRIER | V_COW, new_fl);
2380c486
JR
3502 }
3503
3504 void jfs_get_inode_flags(struct jfs_inode_info *jfs_ip)
3505 {
3506 unsigned int flags = jfs_ip->vfs_inode.i_flags;
3507+ unsigned int vflags = jfs_ip->vfs_inode.i_vflags;
3508+
3509+ jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_IXUNLINK_FL |
3510+ JFS_APPEND_FL | JFS_NOATIME_FL |
3511+ JFS_DIRSYNC_FL | JFS_SYNC_FL |
3512+ JFS_BARRIER_FL | JFS_COW_FL);
3513
3514- jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_APPEND_FL | JFS_NOATIME_FL |
3515- JFS_DIRSYNC_FL | JFS_SYNC_FL);
3516 if (flags & S_IMMUTABLE)
3517 jfs_ip->mode2 |= JFS_IMMUTABLE_FL;
3518+ if (flags & S_IXUNLINK)
3519+ jfs_ip->mode2 |= JFS_IXUNLINK_FL;
3520+
3521 if (flags & S_APPEND)
3522 jfs_ip->mode2 |= JFS_APPEND_FL;
3523 if (flags & S_NOATIME)
8de2f54c 3524@@ -61,6 +82,11 @@ void jfs_get_inode_flags(struct jfs_inod
2380c486
JR
3525 jfs_ip->mode2 |= JFS_DIRSYNC_FL;
3526 if (flags & S_SYNC)
3527 jfs_ip->mode2 |= JFS_SYNC_FL;
3528+
3529+ if (vflags & V_BARRIER)
3530+ jfs_ip->mode2 |= JFS_BARRIER_FL;
3531+ if (vflags & V_COW)
3532+ jfs_ip->mode2 |= JFS_COW_FL;
d337f35e
JR
3533 }
3534
3535 /*
8de2f54c 3536diff -NurpP --minimal linux-4.4.111/fs/jfs/jfs_inode.h linux-4.4.111-vs2.3.9.5/fs/jfs/jfs_inode.h
f19bd705 3537--- linux-4.4.111/fs/jfs/jfs_inode.h 2015-04-12 22:12:50.000000000 +0000
8de2f54c 3538+++ linux-4.4.111-vs2.3.9.5/fs/jfs/jfs_inode.h 2018-01-09 16:36:32.000000000 +0000
2380c486
JR
3539@@ -39,6 +39,7 @@ extern struct dentry *jfs_fh_to_dentry(s
3540 extern struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
3541 int fh_len, int fh_type);
d337f35e 3542 extern void jfs_set_inode_flags(struct inode *);
d4263eb0 3543+extern int jfs_sync_flags(struct inode *, int, int);
d337f35e 3544 extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
78865d5b 3545 extern int jfs_setattr(struct dentry *, struct iattr *);
d337f35e 3546
8de2f54c 3547diff -NurpP --minimal linux-4.4.111/fs/jfs/namei.c linux-4.4.111-vs2.3.9.5/fs/jfs/namei.c
f19bd705 3548--- linux-4.4.111/fs/jfs/namei.c 2016-07-05 04:15:08.000000000 +0000
8de2f54c 3549+++ linux-4.4.111-vs2.3.9.5/fs/jfs/namei.c 2018-01-09 16:36:32.000000000 +0000
d33d7b00 3550@@ -22,6 +22,7 @@
d337f35e
JR
3551 #include <linux/ctype.h>
3552 #include <linux/quotaops.h>
2380c486 3553 #include <linux/exportfs.h>
d337f35e
JR
3554+#include <linux/vs_tag.h>
3555 #include "jfs_incore.h"
3556 #include "jfs_superblock.h"
3557 #include "jfs_inode.h"
927ca606 3558@@ -1480,6 +1481,7 @@ static struct dentry *jfs_lookup(struct
a168f21d 3559 jfs_err("jfs_lookup: iget failed on inum %d", (uint)inum);
d337f35e
JR
3560 }
3561
3562+ dx_propagate_tag(nd, ip);
d33d7b00
AM
3563 return d_splice_alias(ip, dentry);
3564 }
d337f35e 3565
927ca606 3566@@ -1545,6 +1547,7 @@ const struct inode_operations jfs_dir_in
a168f21d 3567 .get_acl = jfs_get_acl,
bb20add7 3568 .set_acl = jfs_set_acl,
d337f35e
JR
3569 #endif
3570+ .sync_flags = jfs_sync_flags,
3571 };
3572
3573 const struct file_operations jfs_dir_operations = {
8de2f54c 3574diff -NurpP --minimal linux-4.4.111/fs/jfs/super.c linux-4.4.111-vs2.3.9.5/fs/jfs/super.c
f19bd705 3575--- linux-4.4.111/fs/jfs/super.c 2018-01-11 07:57:45.000000000 +0000
8de2f54c 3576+++ linux-4.4.111-vs2.3.9.5/fs/jfs/super.c 2018-01-09 16:36:32.000000000 +0000
927ca606 3577@@ -206,7 +206,8 @@ enum {
d337f35e
JR
3578 Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
3579 Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
537831f9
AM
3580 Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask,
3581- Opt_discard, Opt_nodiscard, Opt_discard_minblk
3582+ Opt_discard, Opt_nodiscard, Opt_discard_minblk,
d337f35e
JR
3583+ Opt_tag, Opt_notag, Opt_tagid
3584 };
3585
ec22aa5c 3586 static const match_table_t tokens = {
927ca606 3587@@ -216,6 +217,10 @@ static const match_table_t tokens = {
d337f35e
JR
3588 {Opt_resize, "resize=%u"},
3589 {Opt_resize_nosize, "resize"},
3590 {Opt_errors, "errors=%s"},
3591+ {Opt_tag, "tag"},
3592+ {Opt_notag, "notag"},
3593+ {Opt_tagid, "tagid=%u"},
3594+ {Opt_tag, "tagxid"},
3595 {Opt_ignore, "noquota"},
3596 {Opt_ignore, "quota"},
3597 {Opt_usrquota, "usrquota"},
927ca606 3598@@ -405,7 +410,20 @@ static int parse_options(char *options,
bb20add7 3599 pr_err("JFS: discard option not supported on device\n");
d337f35e
JR
3600 break;
3601 }
537831f9 3602-
d337f35e
JR
3603+#ifndef CONFIG_TAGGING_NONE
3604+ case Opt_tag:
3605+ *flag |= JFS_TAGGED;
3606+ break;
3607+ case Opt_notag:
3608+ *flag &= JFS_TAGGED;
3609+ break;
3610+#endif
3611+#ifdef CONFIG_PROPAGATE
3612+ case Opt_tagid:
3613+ /* use args[0] */
3614+ *flag |= JFS_TAGGED;
3615+ break;
3616+#endif
3617 default:
bb20add7
AM
3618 printk("jfs: Unrecognized mount option \"%s\" or missing value\n",
3619 p);
927ca606 3620@@ -437,6 +455,12 @@ static int jfs_remount(struct super_bloc
bb20add7 3621 if (!parse_options(data, sb, &newLVSize, &flag))
d337f35e 3622 return -EINVAL;
ab30d09f 3623
d337f35e
JR
3624+ if ((flag & JFS_TAGGED) && !(sb->s_flags & MS_TAGGED)) {
3625+ printk(KERN_ERR "JFS: %s: tagging not permitted on remount.\n",
3626+ sb->s_id);
3627+ return -EINVAL;
3628+ }
3629+
3630 if (newLVSize) {
3631 if (sb->s_flags & MS_RDONLY) {
bb20add7
AM
3632 pr_err("JFS: resize requires volume to be mounted read-write\n");
3633@@ -517,6 +541,9 @@ static int jfs_fill_super(struct super_b
d337f35e
JR
3634 #ifdef CONFIG_JFS_POSIX_ACL
3635 sb->s_flags |= MS_POSIXACL;
3636 #endif
3637+ /* map mount option tagxid */
3638+ if (sbi->flag & JFS_TAGGED)
3639+ sb->s_flags |= MS_TAGGED;
3640
3641 if (newLVSize) {
537831f9 3642 pr_err("resize option for remount only\n");
8de2f54c 3643diff -NurpP --minimal linux-4.4.111/fs/libfs.c linux-4.4.111-vs2.3.9.5/fs/libfs.c
f19bd705 3644--- linux-4.4.111/fs/libfs.c 2016-07-05 04:12:33.000000000 +0000
8de2f54c 3645+++ linux-4.4.111-vs2.3.9.5/fs/libfs.c 2018-01-09 16:36:32.000000000 +0000
927ca606 3646@@ -141,13 +141,14 @@ static inline unsigned char dt_type(stru
d337f35e
JR
3647 * both impossible due to the lock on directory.
3648 */
3649
c2e5f7c8 3650-int dcache_readdir(struct file *file, struct dir_context *ctx)
2380c486 3651+static inline int do_dcache_readdir_filter(struct file *filp,
c2e5f7c8 3652+ struct dir_context *ctx, int (*filter)(struct dentry *dentry))
d337f35e 3653 {
c2e5f7c8
JR
3654- struct dentry *dentry = file->f_path.dentry;
3655- struct dentry *cursor = file->private_data;
3656+ struct dentry *dentry = filp->f_path.dentry;
3657+ struct dentry *cursor = filp->private_data;
bb20add7 3658 struct list_head *p, *q = &cursor->d_child;
c2e5f7c8
JR
3659
3660- if (!dir_emit_dots(file, ctx))
3661+ if (!dir_emit_dots(filp, ctx))
3662 return 0;
3663 spin_lock(&dentry->d_lock);
3664 if (ctx->pos == 2)
927ca606 3665@@ -155,6 +156,8 @@ int dcache_readdir(struct file *file, st
c2e5f7c8
JR
3666
3667 for (p = q->next; p != &dentry->d_subdirs; p = p->next) {
bb20add7 3668 struct dentry *next = list_entry(p, struct dentry, d_child);
c2e5f7c8
JR
3669+ if (filter && !filter(next))
3670+ continue;
3671 spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
3672 if (!simple_positive(next)) {
3673 spin_unlock(&next->d_lock);
927ca606 3674@@ -177,8 +180,22 @@ int dcache_readdir(struct file *file, st
c2e5f7c8 3675 spin_unlock(&dentry->d_lock);
d337f35e
JR
3676 return 0;
3677 }
c2e5f7c8
JR
3678+
3679 EXPORT_SYMBOL(dcache_readdir);
d337f35e 3680
c2e5f7c8 3681+int dcache_readdir(struct file *filp, struct dir_context *ctx)
d337f35e 3682+{
c2e5f7c8 3683+ return do_dcache_readdir_filter(filp, ctx, NULL);
d337f35e
JR
3684+}
3685+
c2e5f7c8
JR
3686+EXPORT_SYMBOL(dcache_readdir_filter);
3687+
3688+int dcache_readdir_filter(struct file *filp, struct dir_context *ctx,
d337f35e
JR
3689+ int (*filter)(struct dentry *))
3690+{
c2e5f7c8 3691+ return do_dcache_readdir_filter(filp, ctx, filter);
d337f35e 3692+}
d337f35e
JR
3693+
3694 ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
3695 {
3696 return -EISDIR;
8de2f54c 3697diff -NurpP --minimal linux-4.4.111/fs/locks.c linux-4.4.111-vs2.3.9.5/fs/locks.c
f19bd705 3698--- linux-4.4.111/fs/locks.c 2018-01-11 07:57:45.000000000 +0000
8de2f54c 3699+++ linux-4.4.111-vs2.3.9.5/fs/locks.c 2018-01-09 16:36:32.000000000 +0000
c2e5f7c8
JR
3700@@ -129,6 +129,8 @@
3701 #include <linux/hashtable.h>
3702 #include <linux/percpu.h>
3703 #include <linux/lglock.h>
d337f35e
JR
3704+#include <linux/vs_base.h>
3705+#include <linux/vs_limit.h>
3706
bb20add7
AM
3707 #define CREATE_TRACE_POINTS
3708 #include <trace/events/filelock.h>
927ca606 3709@@ -255,11 +257,15 @@ static void locks_init_lock_heads(struct
d337f35e 3710 /* Allocate an empty lock structure. */
ab30d09f 3711 struct file_lock *locks_alloc_lock(void)
d337f35e 3712 {
a168f21d 3713- struct file_lock *fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
a0a3e0cf 3714+ struct file_lock *fl;
a168f21d
AM
3715
3716- if (fl)
3717- locks_init_lock_heads(fl);
a168f21d 3718+ fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
927ca606 3719
a168f21d
AM
3720+ if (fl) {
3721+ locks_init_lock_heads(fl);
927ca606 3722+ vx_locks_inc(fl);
a168f21d
AM
3723+ fl->fl_xid = -1;
3724+ }
3725 return fl;
3726 }
3727 EXPORT_SYMBOL_GPL(locks_alloc_lock);
927ca606 3728@@ -311,6 +317,7 @@ void locks_init_lock(struct file_lock *f
a168f21d
AM
3729 {
3730 memset(fl, 0, sizeof(struct file_lock));
3731 locks_init_lock_heads(fl);
3732+ fl->fl_xid = -1;
3733 }
3734
3735 EXPORT_SYMBOL(locks_init_lock);
927ca606 3736@@ -328,6 +335,7 @@ void locks_copy_conflock(struct file_loc
bb20add7
AM
3737 new->fl_start = fl->fl_start;
3738 new->fl_end = fl->fl_end;
d337f35e
JR
3739 new->fl_lmops = fl->fl_lmops;
3740+ new->fl_xid = fl->fl_xid;
bb20add7 3741 new->fl_ops = NULL;
d337f35e 3742
bb20add7 3743 if (fl->fl_lmops) {
927ca606 3744@@ -389,7 +397,10 @@ flock_make_lock(struct file *filp, unsig
d337f35e
JR
3745 fl->fl_flags = FL_FLOCK;
3746 fl->fl_type = type;
3747 fl->fl_end = OFFSET_MAX;
927ca606 3748-
d337f35e
JR
3749+
3750+ vxd_assert(filp->f_xid == vx_current_xid(),
3751+ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
3752+ fl->fl_xid = filp->f_xid;
bb20add7
AM
3753 return fl;
3754 }
927ca606
AM
3755
3756@@ -511,6 +522,7 @@ static int lease_init(struct file *filp,
d337f35e 3757
bb20add7 3758 fl->fl_owner = filp;
d337f35e
JR
3759 fl->fl_pid = current->tgid;
3760+ fl->fl_xid = vx_current_xid();
3761
3762 fl->fl_file = filp;
3763 fl->fl_flags = FL_LEASE;
927ca606 3764@@ -530,6 +542,10 @@ static struct file_lock *lease_alloc(str
d337f35e 3765 if (fl == NULL)
2380c486 3766 return ERR_PTR(error);
d337f35e
JR
3767
3768+ fl->fl_xid = vx_current_xid();
3769+ if (filp)
3770+ vxd_assert(filp->f_xid == fl->fl_xid,
3771+ "f_xid(%d) == fl_xid(%d)", filp->f_xid, fl->fl_xid);
d337f35e
JR
3772 error = lease_init(filp, type, fl);
3773 if (error) {
3774 locks_free_lock(fl);
927ca606
AM
3775@@ -908,6 +924,7 @@ static int flock_lock_inode(struct inode
3776 goto out;
ab30d09f 3777 }
2380c486
JR
3778
3779+ new_fl->fl_xid = -1;
3780 find_conflict:
927ca606
AM
3781 list_for_each_entry(fl, &ctx->flc_flock, fl_list) {
3782 if (!flock_locks_conflict(request, fl))
3783@@ -934,7 +951,8 @@ out:
d337f35e
JR
3784 return error;
3785 }
3786
2380c486
JR
3787-static int __posix_lock_file(struct inode *inode, struct file_lock *request, struct file_lock *conflock)
3788+static int __posix_lock_file(struct inode *inode, struct file_lock *request,
61333608 3789+ struct file_lock *conflock, vxid_t xid)
d337f35e 3790 {
927ca606 3791 struct file_lock *fl, *tmp;
d337f35e 3792 struct file_lock *new_fl = NULL;
927ca606
AM
3793@@ -950,6 +968,9 @@ static int __posix_lock_file(struct inod
3794 if (!ctx)
3795 return (request->fl_type == F_UNLCK) ? 0 : -ENOMEM;
d337f35e 3796
927ca606
AM
3797+ if (xid)
3798+ vxd_assert(xid == vx_current_xid(),
3799+ "xid(%d) == current(%d)", xid, vx_current_xid());
d337f35e
JR
3800 /*
3801 * We may need two file_lock structures for this operation,
3802 * so we get them in advance to avoid races.
927ca606 3803@@ -960,7 +981,11 @@ static int __posix_lock_file(struct inod
d337f35e
JR
3804 (request->fl_type != F_UNLCK ||
3805 request->fl_start != 0 || request->fl_end != OFFSET_MAX)) {
3806 new_fl = locks_alloc_lock();
3807+ new_fl->fl_xid = xid;
927ca606 3808+ // vx_locks_inc(new_fl);
d337f35e
JR
3809 new_fl2 = locks_alloc_lock();
3810+ new_fl2->fl_xid = xid;
927ca606 3811+ // vx_locks_inc(new_fl2);
d337f35e
JR
3812 }
3813
927ca606
AM
3814 spin_lock(&ctx->flc_lock);
3815@@ -1162,7 +1187,8 @@ static int __posix_lock_file(struct inod
2380c486 3816 int posix_lock_file(struct file *filp, struct file_lock *fl,
d337f35e
JR
3817 struct file_lock *conflock)
3818 {
b00e13aa
AM
3819- return __posix_lock_file(file_inode(filp), fl, conflock);
3820+ return __posix_lock_file(file_inode(filp),
d337f35e
JR
3821+ fl, conflock, filp->f_xid);
3822 }
2380c486 3823 EXPORT_SYMBOL(posix_lock_file);
d337f35e 3824
927ca606
AM
3825@@ -1178,7 +1204,7 @@ static int posix_lock_inode_wait(struct
3826 int error;
3827 might_sleep ();
3828 for (;;) {
3829- error = __posix_lock_file(inode, fl, NULL);
3830+ error = __posix_lock_file(inode, fl, NULL, 0);
3831 if (error != FILE_LOCK_DEFERRED)
3832 break;
3833 error = wait_event_interruptible(fl->fl_wait, !fl->fl_next);
3834@@ -1257,10 +1283,13 @@ int locks_mandatory_area(int read_write,
3835 fl.fl_end = offset + count - 1;
3836
3837 for (;;) {
3838+ vxid_t f_xid = 0;
3839+
ca5d134c 3840 if (filp) {
bb20add7 3841 fl.fl_owner = filp;
ca5d134c
JR
3842 fl.fl_flags &= ~FL_SLEEP;
3843- error = __posix_lock_file(inode, &fl, NULL);
927ca606
AM
3844+ f_xid = filp->f_xid;
3845+ error = __posix_lock_file(inode, &fl, NULL, f_xid);
ca5d134c
JR
3846 if (!error)
3847 break;
3848 }
927ca606 3849@@ -1268,7 +1297,7 @@ int locks_mandatory_area(int read_write,
ca5d134c
JR
3850 if (sleep)
3851 fl.fl_flags |= FL_SLEEP;
3852 fl.fl_owner = current->files;
2380c486 3853- error = __posix_lock_file(inode, &fl, NULL);
927ca606 3854+ error = __posix_lock_file(inode, &fl, NULL, f_xid);
2380c486 3855 if (error != FILE_LOCK_DEFERRED)
d337f35e 3856 break;
2380c486 3857 error = wait_event_interruptible(fl.fl_wait, !fl.fl_next);
927ca606 3858@@ -2165,6 +2194,11 @@ int fcntl_setlk(unsigned int fd, struct
d337f35e
JR
3859 if (file_lock == NULL)
3860 return -ENOLCK;
3861
3862+ vxd_assert(filp->f_xid == vx_current_xid(),
3863+ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
3864+ file_lock->fl_xid = filp->f_xid;
927ca606 3865+ // vx_locks_inc(file_lock);
d337f35e
JR
3866+
3867 /*
3868 * This might block, so we do it before checking the inode.
3869 */
927ca606 3870@@ -2307,6 +2341,11 @@ int fcntl_setlk64(unsigned int fd, struc
d337f35e
JR
3871 if (file_lock == NULL)
3872 return -ENOLCK;
3873
3874+ vxd_assert(filp->f_xid == vx_current_xid(),
3875+ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
3876+ file_lock->fl_xid = filp->f_xid;
927ca606 3877+ // vx_locks_inc(file_lock);
d337f35e
JR
3878+
3879 /*
3880 * This might block, so we do it before checking the inode.
3881 */
927ca606 3882@@ -2620,8 +2659,11 @@ static int locks_show(struct seq_file *f
2380c486 3883
c2e5f7c8 3884 lock_get_status(f, fl, iter->li_pos, "");
2380c486
JR
3885
3886- list_for_each_entry(bfl, &fl->fl_block, fl_block)
3887+ list_for_each_entry(bfl, &fl->fl_block, fl_block) {
3888+ if (!vx_check(fl->fl_xid, VS_WATCH_P | VS_IDENT))
d337f35e 3889+ continue;
bb20add7 3890 lock_get_status(f, bfl, iter->li_pos, " ->");
2380c486 3891+ }
d337f35e 3892
2380c486 3893 return 0;
ab30d09f 3894 }
8de2f54c 3895diff -NurpP --minimal linux-4.4.111/fs/mount.h linux-4.4.111-vs2.3.9.5/fs/mount.h
f19bd705 3896--- linux-4.4.111/fs/mount.h 2018-01-11 07:57:45.000000000 +0000
8de2f54c 3897+++ linux-4.4.111-vs2.3.9.5/fs/mount.h 2018-01-09 16:36:32.000000000 +0000
927ca606 3898@@ -68,6 +68,7 @@ struct mount {
bb20add7 3899 struct hlist_head mnt_pins;
927ca606
AM
3900 struct fs_pin mnt_umount;
3901 struct dentry *mnt_ex_mountpoint;
61333608 3902+ vtag_t mnt_tag; /* tagging used for vfsmount */
db55b927
AM
3903 };
3904
92598135 3905 #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
8de2f54c 3906diff -NurpP --minimal linux-4.4.111/fs/namei.c linux-4.4.111-vs2.3.9.5/fs/namei.c
f19bd705 3907--- linux-4.4.111/fs/namei.c 2018-01-11 07:57:45.000000000 +0000
8de2f54c 3908+++ linux-4.4.111-vs2.3.9.5/fs/namei.c 2018-01-13 03:11:55.000000000 +0000
bb20add7 3909@@ -34,10 +34,20 @@
2380c486 3910 #include <linux/device_cgroup.h>
ec22aa5c 3911 #include <linux/fs_struct.h>
a168f21d 3912 #include <linux/posix_acl.h>
d337f35e 3913+#include <linux/proc_fs.h>
09be7631 3914+#include <linux/magic.h>
d337f35e
JR
3915+#include <linux/vserver/inode.h>
3916+#include <linux/vs_base.h>
3917+#include <linux/vs_tag.h>
3918+#include <linux/vs_cowbl.h>
2380c486
JR
3919+#include <linux/vs_device.h>
3920+#include <linux/vs_context.h>
3921+#include <linux/pid_namespace.h>
bb20add7 3922 #include <linux/hash.h>
d337f35e
JR
3923 #include <asm/uaccess.h>
3924
2bf5ad28 3925 #include "internal.h"
09be7631
JR
3926+#include "proc/internal.h"
3927 #include "mount.h"
3928
3929 /* [Feb-1997 T. Schoebel-Theuer]
927ca606 3930@@ -283,6 +293,93 @@ static int check_acl(struct inode *inode
a168f21d
AM
3931 return -EAGAIN;
3932 }
d337f35e 3933
7e46296a 3934+static inline int dx_barrier(const struct inode *inode)
d337f35e 3935+{
2380c486
JR
3936+ if (IS_BARRIER(inode) && !vx_check(0, VS_ADMIN | VS_WATCH)) {
3937+ vxwprintk_task(1, "did hit the barrier.");
d337f35e
JR
3938+ return 1;
3939+ }
3940+ return 0;
3941+}
3942+
7e46296a 3943+static int __dx_permission(const struct inode *inode, int mask)
d337f35e
JR
3944+{
3945+ if (dx_barrier(inode))
3946+ return -EACCES;
d337f35e 3947+
2380c486
JR
3948+ if (inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) {
3949+ /* devpts is xid tagged */
3950+ if (S_ISDIR(inode->i_mode) ||
61333608 3951+ vx_check((vxid_t)i_tag_read(inode), VS_IDENT | VS_WATCH_P))
2380c486 3952+ return 0;
ba86f833 3953+
adc1caaa 3954+ /* just pretend we didn't find anything */
ba86f833 3955+ return -ENOENT;
2380c486
JR
3956+ }
3957+ else if (inode->i_sb->s_magic == PROC_SUPER_MAGIC) {
3958+ struct proc_dir_entry *de = PDE(inode);
3959+
bb20add7
AM
3960+ if (de && !vx_hide_check(0, de->vx_flags)) {
3961+ vxdprintk(VXD_CBIT(misc, 9),
3962+ VS_Q("%*s") " hidden by _dx_permission",
3963+ de->namelen, de->name);
2380c486 3964+ goto out;
bb20add7 3965+ }
2380c486
JR
3966+
3967+ if ((mask & (MAY_WRITE | MAY_APPEND))) {
3968+ struct pid *pid;
3969+ struct task_struct *tsk;
3970+
3971+ if (vx_check(0, VS_ADMIN | VS_WATCH_P) ||
3972+ vx_flags(VXF_STATE_SETUP, 0))
3973+ return 0;
3974+
3975+ pid = PROC_I(inode)->pid;
3976+ if (!pid)
3977+ goto out;
3978+
c6ceaf95 3979+ rcu_read_lock();
2380c486
JR
3980+ tsk = pid_task(pid, PIDTYPE_PID);
3981+ vxdprintk(VXD_CBIT(tag, 0), "accessing %p[#%u]",
3982+ tsk, (tsk ? vx_task_xid(tsk) : 0));
c6ceaf95
AM
3983+ if (tsk &&
3984+ vx_check(vx_task_xid(tsk), VS_IDENT | VS_WATCH_P)) {
3985+ rcu_read_unlock();
2380c486 3986+ return 0;
c6ceaf95
AM
3987+ }
3988+ rcu_read_unlock();
2380c486
JR
3989+ }
3990+ else {
3991+ /* FIXME: Should we block some entries here? */
3992+ return 0;
3993+ }
3994+ }
3995+ else {
3996+ if (dx_notagcheck(inode->i_sb) ||
61333608 3997+ dx_check((vxid_t)i_tag_read(inode),
537831f9 3998+ DX_HOSTID | DX_ADMIN | DX_WATCH | DX_IDENT))
2380c486
JR
3999+ return 0;
4000+ }
4001+
4002+out:
d337f35e
JR
4003+ return -EACCES;
4004+}
4005+
7e46296a 4006+int dx_permission(const struct inode *inode, int mask)
2380c486
JR
4007+{
4008+ int ret = __dx_permission(inode, mask);
4009+ if (unlikely(ret)) {
ba86f833
AM
4010+#ifndef CONFIG_VSERVER_WARN_DEVPTS
4011+ if (inode->i_sb->s_magic != DEVPTS_SUPER_MAGIC)
4012+#endif
4013+ vxwprintk_task(1,
4014+ "denied [0x%x] access to inode %s:%p[#%d,%lu]",
8ce283e1
AM
4015+ mask, inode->i_sb->s_id, inode,
4016+ i_tag_read(inode), inode->i_ino);
2380c486
JR
4017+ }
4018+ return ret;
4019+}
4020+
7e46296a 4021 /*
f6c5ef8b 4022 * This does the basic permission checking
7e46296a 4023 */
927ca606 4024@@ -407,10 +504,14 @@ int __inode_permission(struct inode *ino
d337f35e
JR
4025 /*
4026 * Nobody gets write access to an immutable file.
4027 */
4028- if (IS_IMMUTABLE(inode))
4029+ if (IS_IMMUTABLE(inode) && !IS_COW(inode))
4030 return -EACCES;
4031 }
4032
2380c486
JR
4033+ retval = dx_permission(inode, mask);
4034+ if (retval)
d337f35e 4035+ return retval;
2380c486 4036+
a168f21d
AM
4037 retval = do_inode_permission(inode, mask);
4038 if (retval)
4039 return retval;
927ca606
AM
4040@@ -1583,6 +1684,9 @@ static int lookup_fast(struct nameidata
4041 */
4042 if (negative)
4043 return -ENOENT;
be261992
AM
4044+
4045+ /* FIXME: check dx permission */
4046+
4047 path->mnt = mnt;
4048 path->dentry = dentry;
927ca606
AM
4049 if (likely(__follow_mount_rcu(nd, path, inode, seqp)))
4050@@ -1613,6 +1717,8 @@ unlazy:
4051 dput(dentry);
4052 return -ENOENT;
be261992 4053 }
be261992 4054+
927ca606 4055+ /* FIXME: check dx permission */
be261992
AM
4056 path->mnt = mnt;
4057 path->dentry = dentry;
927ca606
AM
4058 err = follow_managed(path, nd);
4059@@ -2571,7 +2677,7 @@ static int may_delete(struct inode *dir,
d337f35e 4060 return -EPERM;
c2e5f7c8
JR
4061
4062 if (check_sticky(dir, inode) || IS_APPEND(inode) ||
4063- IS_IMMUTABLE(inode) || IS_SWAPFILE(inode))
4064+ IS_IXORUNLINK(inode) || IS_SWAPFILE(inode))
d337f35e
JR
4065 return -EPERM;
4066 if (isdir) {
bb20add7 4067 if (!d_is_dir(victim))
927ca606 4068@@ -2653,19 +2759,25 @@ int vfs_create(struct inode *dir, struct
92598135 4069 bool want_excl)
a168f21d
AM
4070 {
4071 int error = may_create(dir, dentry);
a168f21d
AM
4072- if (error)
4073+ if (error) {
4074+ vxdprintk(VXD_CBIT(misc, 3), "may_create failed with %d", error);
537831f9 4075 return error;
a168f21d
AM
4076+ }
4077
4078 if (!dir->i_op->create)
4079 return -EACCES; /* shouldn't it be ENOSYS? */
4080 mode &= S_IALLUGO;
4081 mode |= S_IFREG;
4082 error = security_inode_create(dir, dentry, mode);
4083- if (error)
4084+ if (error) {
4085+ vxdprintk(VXD_CBIT(misc, 3), "security_inode_create failed with %d", error);
537831f9 4086 return error;
a168f21d 4087+ }
92598135 4088 error = dir->i_op->create(dir, dentry, mode, want_excl);
a168f21d
AM
4089 if (!error)
4090 fsnotify_create(dir, dentry);
4091+ else
4092+ vxdprintk(VXD_CBIT(misc, 3), "i_op->create failed with %d", error);
4093 return error;
4094 }
bb20add7 4095 EXPORT_SYMBOL(vfs_create);
927ca606 4096@@ -2701,6 +2813,15 @@ static int may_open(struct path *path, i
ec22aa5c 4097 break;
2380c486 4098 }
d337f35e
JR
4099
4100+#ifdef CONFIG_VSERVER_COWBL
763640ca
JR
4101+ if (IS_COW(inode) &&
4102+ ((flag & O_ACCMODE) != O_RDONLY)) {
d337f35e
JR
4103+ if (IS_COW_LINK(inode))
4104+ return -EMLINK;
2380c486 4105+ inode->i_flags &= ~(S_IXUNLINK|S_IMMUTABLE);
d337f35e
JR
4106+ mark_inode_dirty(inode);
4107+ }
4108+#endif
ec22aa5c 4109 error = inode_permission(inode, acc_mode);
d337f35e
JR
4110 if (error)
4111 return error;
927ca606 4112@@ -3178,6 +3299,16 @@ finish_open:
7b17263b 4113 }
92598135 4114 finish_open_created:
7b17263b
AM
4115 error = may_open(&nd->path, acc_mode, open_flag);
4116+#ifdef CONFIG_VSERVER_COWBL
4117+ if (error == -EMLINK) {
4118+ struct dentry *dentry;
f19bd705 4119+ dentry = cow_break_link(nd->name->name);
7b17263b
AM
4120+ if (IS_ERR(dentry))
4121+ error = PTR_ERR(dentry);
4122+ else
4123+ dput(dentry);
4124+ }
4125+#endif
4126 if (error)
92598135 4127 goto out;
bb20add7 4128
927ca606 4129@@ -3302,6 +3433,9 @@ static struct file *path_openat(struct n
92598135 4130 int opened = 0;
7b17263b
AM
4131 int error;
4132
927ca606 4133+#ifdef CONFIG_VSERVER_COWBL
7b17263b 4134+restart:
927ca606 4135+#endif
92598135 4136 file = get_empty_filp();
b00e13aa
AM
4137 if (IS_ERR(file))
4138 return file;
f19bd705
AM
4139@@ -3328,6 +3462,12 @@ static struct file *path_openat(struct n
4140 }
4141 }
4142 terminate_walk(nd);
4143+#ifdef CONFIG_VSERVER_COWBL
4144+ if (error == -EMLINK) {
4145+ // path_cleanup(nd);
4146+ goto restart;
4147+ }
4148+#endif
4149 out2:
4150 if (!(opened & FILE_OPENED)) {
4151 BUG_ON(!error);
4152@@ -3448,6 +3588,11 @@ static struct dentry *filename_create(in
a168f21d
AM
4153 goto fail;
4154 }
927ca606
AM
4155 putname(name);
4156+ vxdprintk(VXD_CBIT(misc, 3), "filename_create path.dentry = %p (%.*s), dentry = %p (%.*s), d_inode = %p",
a168f21d
AM
4157+ path->dentry, path->dentry->d_name.len,
4158+ path->dentry->d_name.name, dentry,
4159+ dentry->d_name.len, dentry->d_name.name,
4160+ path->dentry->d_inode);
4161 return dentry;
92598135 4162 fail:
a168f21d 4163 dput(dentry);
f19bd705 4164@@ -3564,6 +3709,7 @@ retry:
927ca606
AM
4165 error = vfs_mknod(path.dentry->d_inode,dentry,mode,0);
4166 break;
4167 }
4168+
927ca606
AM
4169 out:
4170 done_path_create(&path, dentry);
4171 if (retry_estale(error, lookup_flags)) {
4172@@ -4010,7 +4156,7 @@ int vfs_link(struct dentry *old_dentry,
d337f35e
JR
4173 /*
4174 * A link to an append-only or immutable file cannot be created.
4175 */
4176- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
4177+ if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
4178 return -EPERM;
ec22aa5c 4179 if (!dir->i_op->link)
d337f35e 4180 return -EPERM;
8de2f54c 4181@@ -4519,6 +4665,330 @@ int generic_readlink(struct dentry *dent
d337f35e 4182 }
bb20add7 4183 EXPORT_SYMBOL(generic_readlink);
d337f35e
JR
4184
4185+
4186+#ifdef CONFIG_VSERVER_COWBL
4187+
2380c486 4188+static inline
8de2f54c
AM
4189+void dump_path(const char *name, struct path *path)
4190+{
4191+ vxdprintk(VXD_CBIT(misc, 3),
4192+ "%s: path=%p mnt=%p dentry=%p", name, path,
4193+ path ? path->mnt : NULL,
4194+ path ? path->dentry : NULL);
4195+
4196+ if (path && path->mnt)
4197+ vxdprintk(VXD_CBIT(misc, 3),
4198+ "%s: path mnt_sb=%p[#%d,#%d] mnt_root=%p[#%d]", name,
4199+ path->mnt->mnt_sb,
4200+ path->mnt->mnt_sb ? path->mnt->mnt_sb->s_count : -1,
4201+ path->mnt->mnt_sb ? atomic_read(&path->mnt->mnt_sb->s_active) : -1,
4202+ path->mnt->mnt_root,
4203+ path->mnt->mnt_root ? path->mnt->mnt_root->d_lockref.count : -1);
4204+
4205+ if (path && path->dentry)
4206+ vxdprintk(VXD_CBIT(misc, 3),
4207+ "%s: path dentry=%p[#%d]", name,
4208+ path->dentry,
4209+ path->dentry ? path->dentry->d_lockref.count : -1);
4210+}
4211+
4212+static inline
2380c486
JR
4213+long do_cow_splice(struct file *in, struct file *out, size_t len)
4214+{
4215+ loff_t ppos = 0;
09be7631 4216+ loff_t opos = 0;
2380c486 4217+
09be7631 4218+ return do_splice_direct(in, &ppos, out, &opos, len, 0);
2380c486
JR
4219+}
4220+
d337f35e
JR
4221+struct dentry *cow_break_link(const char *pathname)
4222+{
b00e13aa 4223+ int ret, mode, pathlen, redo = 0, drop = 1;
8de2f54c 4224+ struct path old_path = {}, par_path = {}, dir_path = {}, *new_path = NULL;
a168f21d 4225+ struct dentry *dir, *old_dentry, *new_dentry = NULL;
d337f35e
JR
4226+ struct file *old_file;
4227+ struct file *new_file;
8de2f54c
AM
4228+ struct qstr new_qstr;
4229+ int new_type;
d337f35e
JR
4230+ char *to, *path, pad='\251';
4231+ loff_t size;
927ca606
AM
4232+ struct filename *filename = getname_kernel(pathname);
4233+ struct filename *to_filename;
d337f35e 4234+
ba86f833
AM
4235+ vxdprintk(VXD_CBIT(misc, 1),
4236+ "cow_break_link(" VS_Q("%s") ")", pathname);
e915af4e 4237+
d337f35e 4238+ path = kmalloc(PATH_MAX, GFP_KERNEL);
2380c486 4239+ ret = -ENOMEM;
927ca606 4240+ if (!path || IS_ERR(filename))
2380c486 4241+ goto out;
d337f35e 4242+
8de2f54c
AM
4243+ /* old_path will have refs to dentry and mnt */
4244+ ret = filename_lookup(AT_FDCWD, filename, LOOKUP_FOLLOW, &old_path, NULL);
a168f21d 4245+ vxdprintk(VXD_CBIT(misc, 2),
e915af4e 4246+ "do_path_lookup(old): %d", ret);
2380c486
JR
4247+ if (ret < 0)
4248+ goto out_free_path;
d337f35e 4249+
8de2f54c
AM
4250+ dump_path("cow (old)", &old_path);
4251+
e915af4e 4252+ /* no explicit reference for old_dentry here */
8de2f54c
AM
4253+ old_dentry = old_path.dentry;
4254+
4255+ /* speculative put */
4256+ // dput(old_dentry);
2380c486 4257+
e915af4e 4258+ mode = old_dentry->d_inode->i_mode;
8de2f54c 4259+ to = d_path(&old_path, path, PATH_MAX-2);
d337f35e 4260+ pathlen = strlen(to);
ba86f833 4261+ vxdprintk(VXD_CBIT(misc, 2),
a168f21d
AM
4262+ "old path " VS_Q("%s") " [%p:" VS_Q("%.*s") ":%d]", to,
4263+ old_dentry,
4264+ old_dentry->d_name.len, old_dentry->d_name.name,
4265+ old_dentry->d_name.len);
d337f35e 4266+
2380c486 4267+ to[pathlen + 1] = 0;
d337f35e 4268+retry:
a168f21d 4269+ new_dentry = NULL;
d337f35e 4270+ to[pathlen] = pad--;
a168f21d 4271+ ret = -ELOOP;
d337f35e
JR
4272+ if (pad <= '\240')
4273+ goto out_rel_old;
4274+
ba86f833 4275+ vxdprintk(VXD_CBIT(misc, 1), "temp copy " VS_Q("%s"), to);
e915af4e 4276+
8de2f54c 4277+ /* dir_path will have refs to dentry and mnt */
927ca606 4278+ to_filename = getname_kernel(to);
8de2f54c
AM
4279+ to_filename = filename_parentat(AT_FDCWD, to_filename,
4280+ LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE, &par_path, &new_qstr, &new_type);
4281+ vxdprintk(VXD_CBIT(misc, 2), "filename_parentat(new): %p", to_filename);
4282+ dump_path("cow (par)", &par_path);
4283+ if (IS_ERR(to_filename))
2380c486
JR
4284+ goto retry;
4285+
8de2f54c
AM
4286+ vxdprintk(VXD_CBIT(misc, 2), "to_filename refcnt=%d", to_filename->refcnt);
4287+ // putname(to_filename);
4288+
e915af4e
AM
4289+ /* this puppy downs the dir inode mutex if successful.
4290+ dir_path will hold refs to dentry and mnt and
b00e13aa 4291+ we'll have write access to the mnt */
8de2f54c 4292+ new_dentry = filename_create(AT_FDCWD, to_filename, &dir_path, 0);
a168f21d 4293+ if (!new_dentry || IS_ERR(new_dentry)) {
8de2f54c 4294+ path_put(&par_path);
a168f21d 4295+ vxdprintk(VXD_CBIT(misc, 2),
8de2f54c 4296+ "filename_create(new) failed with %ld",
a168f21d 4297+ PTR_ERR(new_dentry));
d337f35e
JR
4298+ goto retry;
4299+ }
2380c486 4300+ vxdprintk(VXD_CBIT(misc, 2),
8de2f54c 4301+ "filename_create(new): %p [" VS_Q("%.*s") ":%d]",
a168f21d
AM
4302+ new_dentry,
4303+ new_dentry->d_name.len, new_dentry->d_name.name,
4304+ new_dentry->d_name.len);
4305+
8de2f54c
AM
4306+ dump_path("cow (dir)", &dir_path);
4307+
e915af4e
AM
4308+ /* take a reference on new_dentry */
4309+ dget(new_dentry);
4310+
4311+ /* dentry/mnt refs handed over to new_path */
4312+ new_path = &dir_path;
4313+
4314+ /* dentry for old/new dir */
8de2f54c 4315+ dir = par_path.dentry;
d337f35e 4316+
e915af4e
AM
4317+ /* give up reference on dir */
4318+ dput(new_path->dentry);
4319+
4320+ /* new_dentry already has a reference */
4321+ new_path->dentry = new_dentry;
4322+
4323+ ret = vfs_create(dir->d_inode, new_dentry, mode, 1);
d337f35e
JR
4324+ vxdprintk(VXD_CBIT(misc, 2),
4325+ "vfs_create(new): %d", ret);
4326+ if (ret == -EEXIST) {
8de2f54c 4327+ path_put(&par_path);
b00e13aa 4328+ mutex_unlock(&dir->d_inode->i_mutex);
e915af4e
AM
4329+ mnt_drop_write(new_path->mnt);
4330+ path_put(new_path);
4331+ new_dentry = NULL;
d337f35e
JR
4332+ goto retry;
4333+ }
2380c486
JR
4334+ else if (ret < 0)
4335+ goto out_unlock_new;
4336+
927ca606 4337+ /* the old file went away */
2380c486 4338+ ret = -ENOENT;
a168f21d 4339+ if ((redo = d_unhashed(old_dentry)))
2380c486
JR
4340+ goto out_unlock_new;
4341+
e915af4e 4342+ /* doesn't change refs for old_path */
8de2f54c 4343+ old_file = dentry_open(&old_path, O_RDONLY, current_cred());
d337f35e
JR
4344+ vxdprintk(VXD_CBIT(misc, 2),
4345+ "dentry_open(old): %p", old_file);
a168f21d
AM
4346+ if (IS_ERR(old_file)) {
4347+ ret = PTR_ERR(old_file);
2380c486
JR
4348+ goto out_unlock_new;
4349+ }
d337f35e 4350+
e915af4e
AM
4351+ /* doesn't change refs for new_path */
4352+ new_file = dentry_open(new_path, O_WRONLY, current_cred());
d337f35e
JR
4353+ vxdprintk(VXD_CBIT(misc, 2),
4354+ "dentry_open(new): %p", new_file);
a168f21d
AM
4355+ if (IS_ERR(new_file)) {
4356+ ret = PTR_ERR(new_file);
d337f35e 4357+ goto out_fput_old;
a168f21d 4358+ }
d337f35e 4359+
8de2f54c 4360+ /* unlock the inode mutex from filename_create() */
b00e13aa
AM
4361+ mutex_unlock(&dir->d_inode->i_mutex);
4362+
4363+ /* drop write access to mnt */
4364+ mnt_drop_write(new_path->mnt);
4365+
4366+ drop = 0;
4367+
927ca606 4368+ size = i_size_read(old_file->f_path.dentry->d_inode);
2380c486
JR
4369+ ret = do_cow_splice(old_file, new_file, size);
4370+ vxdprintk(VXD_CBIT(misc, 2), "do_splice_direct: %d", ret);
4371+ if (ret < 0) {
d337f35e 4372+ goto out_fput_both;
2380c486
JR
4373+ } else if (ret < size) {
4374+ ret = -ENOSPC;
4375+ goto out_fput_both;
4376+ } else {
a168f21d
AM
4377+ struct inode *old_inode = old_dentry->d_inode;
4378+ struct inode *new_inode = new_dentry->d_inode;
2380c486
JR
4379+ struct iattr attr = {
4380+ .ia_uid = old_inode->i_uid,
4381+ .ia_gid = old_inode->i_gid,
4382+ .ia_valid = ATTR_UID | ATTR_GID
4383+ };
4384+
93de0823
AM
4385+ setattr_copy(new_inode, &attr);
4386+ mark_inode_dirty(new_inode);
2380c486 4387+ }
d337f35e 4388+
e915af4e 4389+ /* lock rename mutex */
a168f21d 4390+ mutex_lock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
2380c486
JR
4391+
4392+ /* drop out late */
4393+ ret = -ENOENT;
a168f21d 4394+ if ((redo = d_unhashed(old_dentry)))
2380c486
JR
4395+ goto out_unlock;
4396+
4397+ vxdprintk(VXD_CBIT(misc, 2),
ba86f833 4398+ "vfs_rename: [" VS_Q("%*s") ":%d] -> [" VS_Q("%*s") ":%d]",
a168f21d
AM
4399+ new_dentry->d_name.len, new_dentry->d_name.name,
4400+ new_dentry->d_name.len,
4401+ old_dentry->d_name.len, old_dentry->d_name.name,
4402+ old_dentry->d_name.len);
8de2f54c 4403+ ret = vfs_rename(par_path.dentry->d_inode, new_dentry,
eafa5b1d 4404+ old_dentry->d_parent->d_inode, old_dentry, NULL, 0);
d337f35e 4405+ vxdprintk(VXD_CBIT(misc, 2), "vfs_rename: %d", ret);
2380c486
JR
4406+
4407+out_unlock:
a168f21d 4408+ mutex_unlock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
d337f35e
JR
4409+
4410+out_fput_both:
4411+ vxdprintk(VXD_CBIT(misc, 3),
2380c486 4412+ "fput(new_file=%p[#%ld])", new_file,
4a036bed 4413+ atomic_long_read(&new_file->f_count));
d337f35e
JR
4414+ fput(new_file);
4415+
4416+out_fput_old:
4417+ vxdprintk(VXD_CBIT(misc, 3),
2380c486 4418+ "fput(old_file=%p[#%ld])", old_file,
4a036bed 4419+ atomic_long_read(&old_file->f_count));
d337f35e
JR
4420+ fput(old_file);
4421+
2380c486 4422+out_unlock_new:
8de2f54c
AM
4423+ /* drop references from par_path */
4424+ path_put(&par_path);
e915af4e 4425+
b00e13aa 4426+ if (drop) {
8de2f54c 4427+ /* unlock the inode mutex from filename_create() */
b00e13aa
AM
4428+ mutex_unlock(&dir->d_inode->i_mutex);
4429+
4430+ /* drop write access to mnt */
4431+ mnt_drop_write(new_path->mnt);
4432+ }
e915af4e 4433+
2380c486
JR
4434+ if (!ret)
4435+ goto out_redo;
4436+
4437+ /* error path cleanup */
c2e5f7c8 4438+ vfs_unlink(dir->d_inode, new_dentry, NULL);
2380c486
JR
4439+
4440+out_redo:
4441+ if (!redo)
4442+ goto out_rel_both;
e915af4e
AM
4443+
4444+ /* lookup dentry once again
8de2f54c
AM
4445+ old_path will be freed as old_path in out_rel_old */
4446+ ret = filename_lookup(AT_FDCWD, filename, LOOKUP_FOLLOW, &old_path, NULL);
2380c486
JR
4447+ if (ret)
4448+ goto out_rel_both;
d337f35e 4449+
e915af4e 4450+ /* drop reference on new_dentry */
a168f21d 4451+ dput(new_dentry);
8de2f54c 4452+ new_dentry = old_path.dentry;
e915af4e 4453+ dget(new_dentry);
2380c486 4454+ vxdprintk(VXD_CBIT(misc, 2),
763640ca 4455+ "do_path_lookup(redo): %p [" VS_Q("%.*s") ":%d]",
a168f21d
AM
4456+ new_dentry,
4457+ new_dentry->d_name.len, new_dentry->d_name.name,
4458+ new_dentry->d_name.len);
2380c486
JR
4459+
4460+out_rel_both:
8de2f54c 4461+ dump_path("put (new)", new_path);
e915af4e
AM
4462+ if (new_path)
4463+ path_put(new_path);
d337f35e 4464+out_rel_old:
8de2f54c
AM
4465+ dump_path("put (old)", &old_path);
4466+ path_put(&old_path);
2380c486 4467+out_free_path:
d337f35e 4468+ kfree(path);
2380c486 4469+out:
a168f21d
AM
4470+ if (ret) {
4471+ dput(new_dentry);
4472+ new_dentry = ERR_PTR(ret);
4473+ }
8de2f54c
AM
4474+ // if (!IS_ERR(filename))
4475+ // putname(filename);
a168f21d 4476+ vxdprintk(VXD_CBIT(misc, 3),
e915af4e 4477+ "cow_break_link returning with %p", new_dentry);
a168f21d 4478+ return new_dentry;
d337f35e
JR
4479+}
4480+
4481+#endif
1e8b8f9b
AM
4482+
4483+int vx_info_mnt_namespace(struct mnt_namespace *ns, char *buffer)
4484+{
4485+ struct path path;
4486+ struct vfsmount *vmnt;
4487+ char *pstr, *root;
4488+ int length = 0;
4489+
4490+ pstr = kmalloc(PATH_MAX, GFP_KERNEL);
4491+ if (!pstr)
4492+ return 0;
4493+
4494+ vmnt = &ns->root->mnt;
4495+ path.mnt = vmnt;
4496+ path.dentry = vmnt->mnt_root;
4497+ root = d_path(&path, pstr, PATH_MAX - 2);
4498+ length = sprintf(buffer + length,
4499+ "Namespace:\t%p [#%u]\n"
4500+ "RootPath:\t%s\n",
4501+ ns, atomic_read(&ns->count),
4502+ root);
4503+ kfree(pstr);
4504+ return length;
4505+}
bb20add7 4506+
265de2f7 4507+EXPORT_SYMBOL(vx_info_mnt_namespace);
d337f35e
JR
4508+
4509 /* get the link contents into pagecache */
4510 static char *page_getlink(struct dentry * dentry, struct page **ppage)
4511 {
8de2f54c 4512diff -NurpP --minimal linux-4.4.111/fs/namespace.c linux-4.4.111-vs2.3.9.5/fs/namespace.c
f19bd705 4513--- linux-4.4.111/fs/namespace.c 2018-01-11 07:57:45.000000000 +0000
8de2f54c 4514+++ linux-4.4.111-vs2.3.9.5/fs/namespace.c 2018-01-09 16:36:32.000000000 +0000
978063ce 4515@@ -24,6 +24,11 @@
09be7631 4516 #include <linux/magic.h>
52afa9bd 4517 #include <linux/bootmem.h>
bb20add7 4518 #include <linux/task_work.h>
d337f35e 4519+#include <linux/vs_base.h>
d337f35e
JR
4520+#include <linux/vs_context.h>
4521+#include <linux/vs_tag.h>
2380c486
JR
4522+#include <linux/vserver/space.h>
4523+#include <linux/vserver/global.h>
d337f35e 4524 #include "pnode.h"
db55b927
AM
4525 #include "internal.h"
4526
927ca606 4527@@ -971,6 +976,10 @@ vfs_kern_mount(struct file_system_type *
be261992
AM
4528 if (!type)
4529 return ERR_PTR(-ENODEV);
4530
4531+ if ((type->fs_flags & FS_BINARY_MOUNTDATA) &&
4532+ !vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT))
4533+ return ERR_PTR(-EPERM);
4534+
4535 mnt = alloc_vfsmnt(name);
4536 if (!mnt)
4537 return ERR_PTR(-ENOMEM);
927ca606 4538@@ -1046,6 +1055,7 @@ static struct mount *clone_mnt(struct mo
92598135
AM
4539 mnt->mnt.mnt_root = dget(root);
4540 mnt->mnt_mountpoint = mnt->mnt.mnt_root;
4541 mnt->mnt_parent = mnt;
c2e5f7c8
JR
4542+ mnt->mnt_tag = old->mnt_tag;
4543 lock_mount_hash();
92598135 4544 list_add_tail(&mnt->mnt_instance, &sb->s_mounts);
c2e5f7c8 4545 unlock_mount_hash();
927ca606 4546@@ -1620,7 +1630,8 @@ out_unlock:
c2e5f7c8
JR
4547 */
4548 static inline bool may_mount(void)
4549 {
4550- return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN);
4551+ return vx_ns_capable(current->nsproxy->mnt_ns->user_ns,
4552+ CAP_SYS_ADMIN, VXC_SECURE_MOUNT);
4553 }
4554
4555 /*
927ca606 4556@@ -2121,6 +2132,7 @@ static int do_change_type(struct path *p
763640ca
JR
4557 if (err)
4558 goto out_unlock;
4559 }
4560+ // mnt->mnt_flags = mnt_flags;
4561
c2e5f7c8 4562 lock_mount_hash();
763640ca 4563 for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL))
927ca606 4564@@ -2149,12 +2161,14 @@ static bool has_locked_children(struct m
ec22aa5c 4565 * do loopback mount.
d337f35e 4566 */
537831f9 4567 static int do_loopback(struct path *path, const char *old_name,
2380c486 4568- int recurse)
61333608 4569+ vtag_t tag, unsigned long flags, int mnt_flags)
d337f35e 4570 {
ec22aa5c 4571 struct path old_path;
09be7631
JR
4572 struct mount *mnt = NULL, *old, *parent;
4573 struct mountpoint *mp;
d337f35e 4574+ int recurse = flags & MS_REC;
b00e13aa 4575 int err;
2380c486 4576+
d337f35e 4577 if (!old_name || !*old_name)
b00e13aa
AM
4578 return -EINVAL;
4579 err = kern_path(old_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path);
927ca606 4580@@ -2234,7 +2248,7 @@ static int change_mount_flags(struct vfs
ec22aa5c 4581 * on it - tough luck.
d337f35e 4582 */
ec22aa5c 4583 static int do_remount(struct path *path, int flags, int mnt_flags,
d337f35e 4584- void *data)
61333608 4585+ void *data, vxid_t xid)
d337f35e
JR
4586 {
4587 int err;
ec22aa5c 4588 struct super_block *sb = path->mnt->mnt_sb;
927ca606 4589@@ -2742,6 +2756,7 @@ long do_mount(const char *dev_name, cons
ec22aa5c 4590 struct path path;
d337f35e
JR
4591 int retval = 0;
4592 int mnt_flags = 0;
61333608 4593+ vtag_t tag = 0;
d337f35e
JR
4594
4595 /* Discard magic */
4596 if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
927ca606 4597@@ -2767,6 +2782,12 @@ long do_mount(const char *dev_name, cons
ec22aa5c
AM
4598 if (!(flags & MS_NOATIME))
4599 mnt_flags |= MNT_RELATIME;
d337f35e 4600
2380c486
JR
4601+ if (dx_parse_tag(data_page, &tag, 1, &mnt_flags, &flags)) {
4602+ /* FIXME: bind and re-mounts get the tag flag? */
d337f35e
JR
4603+ if (flags & (MS_BIND|MS_REMOUNT))
4604+ flags |= MS_TAGID;
4605+ }
d337f35e
JR
4606+
4607 /* Separate the per-mountpoint flags */
d337f35e
JR
4608 if (flags & MS_NOSUID)
4609 mnt_flags |= MNT_NOSUID;
927ca606 4610@@ -2791,15 +2812,17 @@ long do_mount(const char *dev_name, cons
bb20add7
AM
4611 mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK;
4612 }
d337f35e 4613
b00e13aa 4614+ if (!vx_capable(CAP_SYS_ADMIN, VXC_DEV_MOUNT))
d337f35e 4615+ mnt_flags |= MNT_NODEV;
c146dd73 4616 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN |
ec22aa5c
AM
4617 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
4618 MS_STRICTATIME);
d337f35e
JR
4619
4620 if (flags & MS_REMOUNT)
ec22aa5c 4621 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
d337f35e
JR
4622- data_page);
4623+ data_page, tag);
4624 else if (flags & MS_BIND)
ec22aa5c
AM
4625- retval = do_loopback(&path, dev_name, flags & MS_REC);
4626+ retval = do_loopback(&path, dev_name, tag, flags, mnt_flags);
d337f35e 4627 else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
ec22aa5c 4628 retval = do_change_type(&path, flags);
d337f35e 4629 else if (flags & MS_MOVE)
927ca606 4630@@ -2919,6 +2942,7 @@ struct mnt_namespace *copy_mnt_ns(unsign
c2e5f7c8 4631 p = next_mnt(p, old);
d337f35e 4632 }
09be7631 4633 namespace_unlock();
2380c486
JR
4634+ atomic_inc(&vs_global_mnt_ns);
4635
4636 if (rootmnt)
4637 mntput(rootmnt);
927ca606 4638@@ -3094,9 +3118,10 @@ SYSCALL_DEFINE2(pivot_root, const char _
db55b927
AM
4639 new_mnt = real_mount(new.mnt);
4640 root_mnt = real_mount(root.mnt);
09be7631
JR
4641 old_mnt = real_mount(old.mnt);
4642- if (IS_MNT_SHARED(old_mnt) ||
4643+ if ((IS_MNT_SHARED(old_mnt) ||
db55b927
AM
4644 IS_MNT_SHARED(new_mnt->mnt_parent) ||
4645- IS_MNT_SHARED(root_mnt->mnt_parent))
4646+ IS_MNT_SHARED(root_mnt->mnt_parent)) &&
50e68740 4647+ !vx_flags(VXF_STATE_SETUP, 0))
763640ca 4648 goto out4;
db55b927 4649 if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
763640ca 4650 goto out4;
927ca606 4651@@ -3234,6 +3259,7 @@ void put_mnt_ns(struct mnt_namespace *ns
c2e5f7c8
JR
4652 if (!atomic_dec_and_test(&ns->count))
4653 return;
4654 drop_collected_mounts(&ns->root->mnt);
2380c486 4655+ atomic_dec(&vs_global_mnt_ns);
b00e13aa 4656 free_mnt_ns(ns);
2380c486 4657 }
db55b927 4658
8de2f54c 4659diff -NurpP --minimal linux-4.4.111/fs/nfs/client.c linux-4.4.111-vs2.3.9.5/fs/nfs/client.c
f19bd705 4660--- linux-4.4.111/fs/nfs/client.c 2016-07-05 04:15:08.000000000 +0000
8de2f54c 4661+++ linux-4.4.111-vs2.3.9.5/fs/nfs/client.c 2018-01-09 16:36:32.000000000 +0000
927ca606 4662@@ -583,6 +583,9 @@ int nfs_init_server_rpcclient(struct nfs
2380c486
JR
4663 if (server->flags & NFS_MOUNT_SOFT)
4664 server->client->cl_softrtry = 1;
d337f35e
JR
4665
4666+ server->client->cl_tag = 0;
4667+ if (server->flags & NFS_MOUNT_TAGGED)
4668+ server->client->cl_tag = 1;
4669 return 0;
4670 }
92598135 4671 EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
927ca606 4672@@ -760,6 +763,10 @@ static void nfs_server_set_fsinfo(struct
d337f35e
JR
4673 server->acdirmin = server->acdirmax = 0;
4674 }
4675
4676+ /* FIXME: needs fsinfo
4677+ if (server->flags & NFS_MOUNT_TAGGED)
4678+ sb->s_flags |= MS_TAGGED; */
4679+
4680 server->maxfilesize = fsinfo->maxfilesize;
4681
ab30d09f 4682 server->time_delta = fsinfo->time_delta;
8de2f54c 4683diff -NurpP --minimal linux-4.4.111/fs/nfs/dir.c linux-4.4.111-vs2.3.9.5/fs/nfs/dir.c
f19bd705 4684--- linux-4.4.111/fs/nfs/dir.c 2018-01-11 07:57:45.000000000 +0000
8de2f54c 4685+++ linux-4.4.111-vs2.3.9.5/fs/nfs/dir.c 2018-01-09 16:36:32.000000000 +0000
c2e5f7c8 4686@@ -37,6 +37,7 @@
2380c486 4687 #include <linux/sched.h>
ab30d09f 4688 #include <linux/kmemleak.h>
d33d7b00 4689 #include <linux/xattr.h>
d337f35e
JR
4690+#include <linux/vs_tag.h>
4691
d337f35e 4692 #include "delegation.h"
ab30d09f 4693 #include "iostat.h"
927ca606 4694@@ -1396,6 +1397,7 @@ struct dentry *nfs_lookup(struct inode *
42bc425c
AM
4695 /* Success: notify readdir to use READDIRPLUS */
4696 nfs_advise_use_readdirplus(dir);
d337f35e
JR
4697
4698+ dx_propagate_tag(nd, inode);
4699 no_entry:
927ca606 4700 res = d_splice_alias(inode, dentry);
d337f35e 4701 if (res != NULL) {
8de2f54c 4702diff -NurpP --minimal linux-4.4.111/fs/nfs/inode.c linux-4.4.111-vs2.3.9.5/fs/nfs/inode.c
f19bd705 4703--- linux-4.4.111/fs/nfs/inode.c 2018-01-11 07:57:45.000000000 +0000
8de2f54c 4704+++ linux-4.4.111-vs2.3.9.5/fs/nfs/inode.c 2018-01-09 16:36:32.000000000 +0000
c2e5f7c8
JR
4705@@ -38,6 +38,7 @@
4706 #include <linux/slab.h>
d33d7b00 4707 #include <linux/compat.h>
db55b927 4708 #include <linux/freezer.h>
d337f35e
JR
4709+#include <linux/vs_tag.h>
4710
d337f35e 4711 #include <asm/uaccess.h>
1e8b8f9b 4712
927ca606 4713@@ -376,6 +377,8 @@ nfs_fhget(struct super_block *sb, struct
ec22aa5c
AM
4714 if (inode->i_state & I_NEW) {
4715 struct nfs_inode *nfsi = NFS_I(inode);
4716 unsigned long now = jiffies;
a4a22af8
AM
4717+ kuid_t kuid;
4718+ kgid_t kgid;
ec22aa5c
AM
4719
4720 /* We set i_ino for the few things that still rely on it,
4721 * such as stat(2) */
927ca606 4722@@ -419,8 +422,8 @@ nfs_fhget(struct super_block *sb, struct
f6c5ef8b 4723 inode->i_version = 0;
ec22aa5c 4724 inode->i_size = 0;
f6c5ef8b 4725 clear_nlink(inode);
b00e13aa
AM
4726- inode->i_uid = make_kuid(&init_user_ns, -2);
4727- inode->i_gid = make_kgid(&init_user_ns, -2);
a4a22af8
AM
4728+ kuid = make_kuid(&init_user_ns, -2);
4729+ kgid = make_kgid(&init_user_ns, -2);
ec22aa5c
AM
4730 inode->i_blocks = 0;
4731 memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
42bc425c 4732 nfsi->write_io = 0;
927ca606 4733@@ -455,11 +458,11 @@ nfs_fhget(struct super_block *sb, struct
7e46296a 4734 else if (nfs_server_capable(inode, NFS_CAP_NLINK))
bb20add7 4735 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
ec22aa5c
AM
4736 if (fattr->valid & NFS_ATTR_FATTR_OWNER)
4737- inode->i_uid = fattr->uid;
a4a22af8 4738+ kuid = fattr->uid;
7e46296a 4739 else if (nfs_server_capable(inode, NFS_CAP_OWNER))
bb20add7 4740 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
ec22aa5c
AM
4741 if (fattr->valid & NFS_ATTR_FATTR_GROUP)
4742- inode->i_gid = fattr->gid;
a4a22af8 4743+ kgid = fattr->gid;
7e46296a 4744 else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP))
bb20add7 4745 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
42bc425c 4746 if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
927ca606 4747@@ -470,6 +473,10 @@ nfs_fhget(struct super_block *sb, struct
ec22aa5c
AM
4748 */
4749 inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
4750 }
a4a22af8
AM
4751+ inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
4752+ inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
4753+ inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, GLOBAL_ROOT_TAG);
ec22aa5c 4754+ /* maybe fattr->xid someday */
c2e5f7c8
JR
4755
4756 nfs_setsecurity(inode, fattr, label);
4757
927ca606 4758@@ -611,6 +618,8 @@ void nfs_setattr_update_inode(struct ino
d337f35e
JR
4759 inode->i_uid = attr->ia_uid;
4760 if ((attr->ia_valid & ATTR_GID) != 0)
4761 inode->i_gid = attr->ia_gid;
4762+ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
4763+ inode->i_tag = attr->ia_tag;
bb20add7
AM
4764 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ACCESS
4765 | NFS_INO_INVALID_ACL);
927ca606
AM
4766 }
4767@@ -1235,7 +1244,9 @@ static int nfs_check_inode_attributes(st
d337f35e
JR
4768 struct nfs_inode *nfsi = NFS_I(inode);
4769 loff_t cur_size, new_isize;
2380c486 4770 unsigned long invalid = 0;
a4a22af8 4771-
b00e13aa
AM
4772+ kuid_t kuid;
4773+ kgid_t kgid;
4774+ ktag_t ktag;
d337f35e 4775
42bc425c 4776 if (nfs_have_delegated_attributes(inode))
a4a22af8 4777 return 0;
927ca606
AM
4778@@ -1262,13 +1273,18 @@ static int nfs_check_inode_attributes(st
4779 if (nfsi->nrequests != 0)
4780 invalid &= ~NFS_INO_REVAL_PAGECACHE;
d337f35e 4781
a4a22af8
AM
4782+ kuid = INOTAG_KUID(DX_TAG(inode), fattr->uid, fattr->gid);
4783+ kgid = INOTAG_KGID(DX_TAG(inode), fattr->uid, fattr->gid);
4784+ ktag = INOTAG_KTAG(DX_TAG(inode), fattr->uid, fattr->gid, GLOBAL_ROOT_TAG);
d337f35e
JR
4785+
4786 /* Have any file permissions changed? */
ec22aa5c 4787 if ((fattr->valid & NFS_ATTR_FATTR_MODE) && (inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO))
9474138d 4788 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
b00e13aa
AM
4789- if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, fattr->uid))
4790+ if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, kuid))
ec22aa5c 4791 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
b00e13aa
AM
4792- if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, fattr->gid))
4793+ if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, kgid))
ec22aa5c
AM
4794 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
4795+ /* maybe check for tag too? */
d337f35e
JR
4796
4797 /* Has the link count changed? */
ec22aa5c 4798 if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink)
927ca606 4799@@ -1642,6 +1658,9 @@ static int nfs_update_inode(struct inode
2380c486 4800 unsigned long now = jiffies;
7e46296a 4801 unsigned long save_cache_validity;
927ca606 4802 bool cache_revalidated = true;
a4a22af8
AM
4803+ kuid_t kuid;
4804+ kgid_t kgid;
4805+ ktag_t ktag;
d337f35e 4806
bb20add7 4807 dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n",
2380c486 4808 __func__, inode->i_sb->s_id, inode->i_ino,
927ca606
AM
4809@@ -1752,6 +1771,9 @@ static int nfs_update_inode(struct inode
4810 cache_revalidated = false;
4811 }
d337f35e 4812
a4a22af8
AM
4813+ kuid = TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag);
4814+ kgid = TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag);
4815+ ktag = TAGINO_KTAG(DX_TAG(inode), inode->i_tag);
ec22aa5c
AM
4816
4817 if (fattr->valid & NFS_ATTR_FATTR_ATIME)
4818 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
927ca606
AM
4819@@ -1806,6 +1828,10 @@ static int nfs_update_inode(struct inode
4820 cache_revalidated = false;
4821 }
ec22aa5c 4822
a4a22af8
AM
4823+ inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
4824+ inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
4825+ inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, ktag);
ec22aa5c
AM
4826+
4827 if (fattr->valid & NFS_ATTR_FATTR_NLINK) {
4828 if (inode->i_nlink != fattr->nlink) {
4829 invalid |= NFS_INO_INVALID_ATTR;
8de2f54c 4830diff -NurpP --minimal linux-4.4.111/fs/nfs/nfs3xdr.c linux-4.4.111-vs2.3.9.5/fs/nfs/nfs3xdr.c
f19bd705 4831--- linux-4.4.111/fs/nfs/nfs3xdr.c 2016-07-05 04:12:33.000000000 +0000
8de2f54c 4832+++ linux-4.4.111-vs2.3.9.5/fs/nfs/nfs3xdr.c 2018-01-09 17:17:07.000000000 +0000
78865d5b 4833@@ -20,6 +20,7 @@
d337f35e
JR
4834 #include <linux/nfs3.h>
4835 #include <linux/nfs_fs.h>
4836 #include <linux/nfsacl.h>
4837+#include <linux/vs_tag.h>
4838 #include "internal.h"
4839
4840 #define NFSDBG_FACILITY NFSDBG_XDR
b00e13aa 4841@@ -558,7 +559,8 @@ static __be32 *xdr_decode_nfstime3(__be3
d33d7b00
AM
4842 * set_mtime mtime;
4843 * };
4844 */
4845-static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
4846+static void encode_sattr3(struct xdr_stream *xdr,
4847+ const struct iattr *attr, int tag)
d337f35e 4848 {
d33d7b00
AM
4849 u32 nbytes;
4850 __be32 *p;
b00e13aa 4851@@ -590,15 +592,19 @@ static void encode_sattr3(struct xdr_str
d33d7b00 4852 } else
d337f35e 4853 *p++ = xdr_zero;
d33d7b00 4854
d337f35e
JR
4855- if (attr->ia_valid & ATTR_UID) {
4856+ if (attr->ia_valid & ATTR_UID ||
4857+ (tag && (attr->ia_valid & ATTR_TAG))) {
4858 *p++ = xdr_one;
b00e13aa 4859- *p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid));
a4a22af8
AM
4860+ *p++ = cpu_to_be32(from_kuid(&init_user_ns,
4861+ TAGINO_KUID(tag, attr->ia_uid, attr->ia_tag)));
d33d7b00 4862 } else
d337f35e 4863 *p++ = xdr_zero;
d33d7b00 4864
d337f35e
JR
4865- if (attr->ia_valid & ATTR_GID) {
4866+ if (attr->ia_valid & ATTR_GID ||
4867+ (tag && (attr->ia_valid & ATTR_TAG))) {
4868 *p++ = xdr_one;
b00e13aa 4869- *p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid));
a4a22af8
AM
4870+ *p++ = cpu_to_be32(from_kgid(&init_user_ns,
4871+ TAGINO_KGID(tag, attr->ia_gid, attr->ia_tag)));
d33d7b00 4872 } else
d337f35e 4873 *p++ = xdr_zero;
d33d7b00 4874
b00e13aa 4875@@ -887,7 +893,7 @@ static void nfs3_xdr_enc_setattr3args(st
d33d7b00 4876 const struct nfs3_sattrargs *args)
d337f35e 4877 {
d33d7b00
AM
4878 encode_nfs_fh3(xdr, args->fh);
4879- encode_sattr3(xdr, args->sattr);
4880+ encode_sattr3(xdr, args->sattr, req->rq_task->tk_client->cl_tag);
4881 encode_sattrguard3(xdr, args);
4882 }
d337f35e 4883
b00e13aa 4884@@ -1037,13 +1043,13 @@ static void nfs3_xdr_enc_write3args(stru
d33d7b00
AM
4885 * };
4886 */
4887 static void encode_createhow3(struct xdr_stream *xdr,
4888- const struct nfs3_createargs *args)
4889+ const struct nfs3_createargs *args, int tag)
d337f35e 4890 {
d33d7b00
AM
4891 encode_uint32(xdr, args->createmode);
4892 switch (args->createmode) {
4893 case NFS3_CREATE_UNCHECKED:
4894 case NFS3_CREATE_GUARDED:
4895- encode_sattr3(xdr, args->sattr);
4896+ encode_sattr3(xdr, args->sattr, tag);
4897 break;
4898 case NFS3_CREATE_EXCLUSIVE:
4899 encode_createverf3(xdr, args->verifier);
b00e13aa 4900@@ -1058,7 +1064,7 @@ static void nfs3_xdr_enc_create3args(str
d33d7b00
AM
4901 const struct nfs3_createargs *args)
4902 {
4903 encode_diropargs3(xdr, args->fh, args->name, args->len);
4904- encode_createhow3(xdr, args);
4905+ encode_createhow3(xdr, args, req->rq_task->tk_client->cl_tag);
4906 }
4907
4908 /*
b00e13aa 4909@@ -1074,7 +1080,7 @@ static void nfs3_xdr_enc_mkdir3args(stru
d33d7b00
AM
4910 const struct nfs3_mkdirargs *args)
4911 {
4912 encode_diropargs3(xdr, args->fh, args->name, args->len);
4913- encode_sattr3(xdr, args->sattr);
4914+ encode_sattr3(xdr, args->sattr, req->rq_task->tk_client->cl_tag);
d337f35e 4915 }
d33d7b00
AM
4916
4917 /*
b00e13aa 4918@@ -1091,9 +1097,9 @@ static void nfs3_xdr_enc_mkdir3args(stru
d33d7b00
AM
4919 * };
4920 */
4921 static void encode_symlinkdata3(struct xdr_stream *xdr,
4922- const struct nfs3_symlinkargs *args)
4923+ const struct nfs3_symlinkargs *args, int tag)
4924 {
4925- encode_sattr3(xdr, args->sattr);
4926+ encode_sattr3(xdr, args->sattr, tag);
4927 encode_nfspath3(xdr, args->pages, args->pathlen);
4928 }
4929
b00e13aa 4930@@ -1102,7 +1108,7 @@ static void nfs3_xdr_enc_symlink3args(st
d33d7b00
AM
4931 const struct nfs3_symlinkargs *args)
4932 {
4933 encode_diropargs3(xdr, args->fromfh, args->fromname, args->fromlen);
4934- encode_symlinkdata3(xdr, args);
4935+ encode_symlinkdata3(xdr, args, req->rq_task->tk_client->cl_tag);
927ca606 4936 xdr->buf->flags |= XDRBUF_WRITE;
d33d7b00
AM
4937 }
4938
927ca606 4939@@ -1131,24 +1137,24 @@ static void nfs3_xdr_enc_symlink3args(st
d33d7b00
AM
4940 * };
4941 */
4942 static void encode_devicedata3(struct xdr_stream *xdr,
4943- const struct nfs3_mknodargs *args)
4944+ const struct nfs3_mknodargs *args, int tag)
4945 {
4946- encode_sattr3(xdr, args->sattr);
4947+ encode_sattr3(xdr, args->sattr, tag);
4948 encode_specdata3(xdr, args->rdev);
4949 }
4950
4951 static void encode_mknoddata3(struct xdr_stream *xdr,
4952- const struct nfs3_mknodargs *args)
4953+ const struct nfs3_mknodargs *args, int tag)
4954 {
4955 encode_ftype3(xdr, args->type);
4956 switch (args->type) {
4957 case NF3CHR:
4958 case NF3BLK:
4959- encode_devicedata3(xdr, args);
4960+ encode_devicedata3(xdr, args, tag);
4961 break;
4962 case NF3SOCK:
4963 case NF3FIFO:
4964- encode_sattr3(xdr, args->sattr);
4965+ encode_sattr3(xdr, args->sattr, tag);
4966 break;
4967 case NF3REG:
4968 case NF3DIR:
927ca606 4969@@ -1163,7 +1169,7 @@ static void nfs3_xdr_enc_mknod3args(stru
d33d7b00 4970 const struct nfs3_mknodargs *args)
d337f35e 4971 {
d33d7b00
AM
4972 encode_diropargs3(xdr, args->fh, args->name, args->len);
4973- encode_mknoddata3(xdr, args);
4974+ encode_mknoddata3(xdr, args, req->rq_task->tk_client->cl_tag);
4975 }
4976
4977 /*
8de2f54c 4978diff -NurpP --minimal linux-4.4.111/fs/nfs/super.c linux-4.4.111-vs2.3.9.5/fs/nfs/super.c
f19bd705 4979--- linux-4.4.111/fs/nfs/super.c 2018-01-11 07:57:45.000000000 +0000
8de2f54c 4980+++ linux-4.4.111-vs2.3.9.5/fs/nfs/super.c 2018-01-09 16:36:32.000000000 +0000
927ca606 4981@@ -54,6 +54,7 @@
b00e13aa 4982 #include <linux/parser.h>
1e8b8f9b
AM
4983 #include <linux/nsproxy.h>
4984 #include <linux/rcupdate.h>
d337f35e
JR
4985+#include <linux/vs_tag.h>
4986
d337f35e 4987 #include <asm/uaccess.h>
1e8b8f9b 4988
927ca606 4989@@ -102,6 +103,7 @@ enum {
1e8b8f9b 4990 Opt_mountport,
ab30d09f 4991 Opt_mountvers,
ab30d09f
AM
4992 Opt_minorversion,
4993+ Opt_tagid,
4994
4995 /* Mount options that take string arguments */
1e8b8f9b 4996 Opt_nfsvers,
927ca606 4997@@ -114,6 +116,9 @@ enum {
537831f9
AM
4998 /* Special mount options */
4999 Opt_userspace, Opt_deprecated, Opt_sloppy,
5000
5001+ /* Linux-VServer tagging options */
5002+ Opt_tag, Opt_notag,
5003+
5004 Opt_err
5005 };
5006
927ca606 5007@@ -183,6 +188,10 @@ static const match_table_t nfs_mount_opt
537831f9
AM
5008 { Opt_fscache_uniq, "fsc=%s" },
5009 { Opt_local_lock, "local_lock=%s" },
ab30d09f
AM
5010
5011+ { Opt_tag, "tag" },
5012+ { Opt_notag, "notag" },
5013+ { Opt_tagid, "tagid=%u" },
5014+
537831f9
AM
5015 /* The following needs to be listed after all other options */
5016 { Opt_nfsvers, "v%s" },
ab30d09f 5017
927ca606 5018@@ -642,6 +651,7 @@ static void nfs_show_mount_options(struc
2380c486 5019 { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
ec22aa5c
AM
5020 { NFS_MOUNT_UNSHARED, ",nosharecache", "" },
5021 { NFS_MOUNT_NORESVPORT, ",noresvport", "" },
d337f35e
JR
5022+ { NFS_MOUNT_TAGGED, ",tag", "" },
5023 { 0, NULL, NULL }
5024 };
5025 const struct proc_nfs_info *nfs_infop;
927ca606 5026@@ -1324,6 +1334,14 @@ static int nfs_parse_mount_options(char
537831f9 5027 case Opt_nomigration:
927ca606 5028 mnt->options &= ~NFS_OPTION_MIGRATION;
ab30d09f
AM
5029 break;
5030+#ifndef CONFIG_TAGGING_NONE
5031+ case Opt_tag:
5032+ mnt->flags |= NFS_MOUNT_TAGGED;
5033+ break;
5034+ case Opt_notag:
5035+ mnt->flags &= ~NFS_MOUNT_TAGGED;
5036+ break;
5037+#endif
5038
5039 /*
5040 * options that take numeric values
927ca606 5041@@ -1410,6 +1428,12 @@ static int nfs_parse_mount_options(char
ab30d09f
AM
5042 goto out_invalid_value;
5043 mnt->minorversion = option;
5044 break;
5045+#ifdef CONFIG_PROPAGATE
5046+ case Opt_tagid:
5047+ /* use args[0] */
5048+ nfs_data.flags |= NFS_MOUNT_TAGGED;
5049+ break;
5050+#endif
5051
5052 /*
5053 * options that take text values
8de2f54c 5054diff -NurpP --minimal linux-4.4.111/fs/nfsd/auth.c linux-4.4.111-vs2.3.9.5/fs/nfsd/auth.c
f19bd705 5055--- linux-4.4.111/fs/nfsd/auth.c 2018-01-11 07:57:45.000000000 +0000
8de2f54c 5056+++ linux-4.4.111-vs2.3.9.5/fs/nfsd/auth.c 2018-01-11 08:03:00.000000000 +0000
bb20add7
AM
5057@@ -1,6 +1,7 @@
5058 /* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */
2bf5ad28
AM
5059
5060 #include <linux/sched.h>
d337f35e 5061+#include <linux/vs_tag.h>
2bf5ad28 5062 #include "nfsd.h"
2380c486 5063 #include "auth.h"
d337f35e 5064
bb20add7 5065@@ -35,6 +36,9 @@ int nfsd_setuser(struct svc_rqst *rqstp,
d337f35e 5066
ec22aa5c
AM
5067 new->fsuid = rqstp->rq_cred.cr_uid;
5068 new->fsgid = rqstp->rq_cred.cr_gid;
5069+ /* FIXME: this desperately needs a tag :)
61333608 5070+ new->xid = (vxid_t)INOTAG_TAG(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid, 0);
ec22aa5c 5071+ */
d337f35e 5072
ec22aa5c
AM
5073 rqgi = rqstp->rq_cred.cr_group_info;
5074
8de2f54c 5075diff -NurpP --minimal linux-4.4.111/fs/nfsd/nfs3xdr.c linux-4.4.111-vs2.3.9.5/fs/nfsd/nfs3xdr.c
f19bd705 5076--- linux-4.4.111/fs/nfsd/nfs3xdr.c 2018-01-11 07:57:45.000000000 +0000
8de2f54c 5077+++ linux-4.4.111-vs2.3.9.5/fs/nfsd/nfs3xdr.c 2018-01-09 16:36:32.000000000 +0000
b00e13aa 5078@@ -8,6 +8,7 @@
2bf5ad28
AM
5079
5080 #include <linux/namei.h>
b00e13aa 5081 #include <linux/sunrpc/svc_xprt.h>
d337f35e 5082+#include <linux/vs_tag.h>
2bf5ad28 5083 #include "xdr3.h"
2380c486 5084 #include "auth.h"
b00e13aa
AM
5085 #include "netns.h"
5086@@ -98,6 +99,8 @@ static __be32 *
d337f35e
JR
5087 decode_sattr3(__be32 *p, struct iattr *iap)
5088 {
5089 u32 tmp;
a4a22af8
AM
5090+ kuid_t kuid = GLOBAL_ROOT_UID;
5091+ kgid_t kgid = GLOBAL_ROOT_GID;
d337f35e
JR
5092
5093 iap->ia_valid = 0;
5094
b00e13aa
AM
5095@@ -106,15 +109,18 @@ decode_sattr3(__be32 *p, struct iattr *i
5096 iap->ia_mode = ntohl(*p++);
d337f35e
JR
5097 }
5098 if (*p++) {
b00e13aa 5099- iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++));
a4a22af8 5100+ kuid = make_kuid(&init_user_ns, ntohl(*p++));
b00e13aa
AM
5101 if (uid_valid(iap->ia_uid))
5102 iap->ia_valid |= ATTR_UID;
d337f35e
JR
5103 }
5104 if (*p++) {
b00e13aa 5105- iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++));
a4a22af8 5106+ kgid = make_kgid(&init_user_ns, ntohl(*p++));
b00e13aa
AM
5107 if (gid_valid(iap->ia_gid))
5108 iap->ia_valid |= ATTR_GID;
d337f35e 5109 }
a4a22af8
AM
5110+ iap->ia_uid = INOTAG_KUID(DX_TAG_NFSD, kuid, kgid);
5111+ iap->ia_gid = INOTAG_KGID(DX_TAG_NFSD, kuid, kgid);
5112+ iap->ia_tag = INOTAG_KTAG(DX_TAG_NFSD, kuid, kgid, GLOBAL_ROOT_TAG);
d337f35e
JR
5113 if (*p++) {
5114 u64 newsize;
5115
bb20add7 5116@@ -167,8 +173,12 @@ encode_fattr3(struct svc_rqst *rqstp, __
d337f35e 5117 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
bb20add7 5118 *p++ = htonl((u32) (stat->mode & S_IALLUGO));
d337f35e 5119 *p++ = htonl((u32) stat->nlink);
b00e13aa
AM
5120- *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
5121- *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
5122+ *p++ = htonl((u32) from_kuid(&init_user_ns,
a4a22af8 5123+ TAGINO_KUID(0 /* FIXME: DX_TAG(dentry->d_inode) */,
2380c486 5124+ stat->uid, stat->tag)));
b00e13aa 5125+ *p++ = htonl((u32) from_kgid(&init_user_ns,
a4a22af8 5126+ TAGINO_KGID(0 /* FIXME: DX_TAG(dentry->d_inode) */,
2380c486 5127+ stat->gid, stat->tag)));
d337f35e
JR
5128 if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
5129 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
5130 } else {
8de2f54c 5131diff -NurpP --minimal linux-4.4.111/fs/nfsd/nfs4xdr.c linux-4.4.111-vs2.3.9.5/fs/nfsd/nfs4xdr.c
f19bd705 5132--- linux-4.4.111/fs/nfsd/nfs4xdr.c 2018-01-11 07:57:45.000000000 +0000
8de2f54c 5133+++ linux-4.4.111-vs2.3.9.5/fs/nfsd/nfs4xdr.c 2018-01-09 16:36:32.000000000 +0000
927ca606 5134@@ -40,6 +40,7 @@
d33d7b00 5135 #include <linux/utsname.h>
a168f21d 5136 #include <linux/pagemap.h>
2380c486 5137 #include <linux/sunrpc/svcauth_gss.h>
d337f35e
JR
5138+#include <linux/vs_tag.h>
5139
d33d7b00
AM
5140 #include "idmap.h"
5141 #include "acl.h"
927ca606 5142@@ -2637,12 +2638,16 @@ out_acl:
bb20add7 5143 *p++ = cpu_to_be32(stat.nlink);
d337f35e
JR
5144 }
5145 if (bmval1 & FATTR4_WORD1_OWNER) {
bb20add7
AM
5146- status = nfsd4_encode_user(xdr, rqstp, stat.uid);
5147+ status = nfsd4_encode_user(xdr, rqstp,
a4a22af8 5148+ TAGINO_KUID(DX_TAG(dentry->d_inode),
bb20add7 5149+ stat.uid, stat.tag));
d337f35e
JR
5150 if (status)
5151 goto out;
5152 }
5153 if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
bb20add7
AM
5154- status = nfsd4_encode_group(xdr, rqstp, stat.gid);
5155+ status = nfsd4_encode_group(xdr, rqstp,
a4a22af8 5156+ TAGINO_KGID(DX_TAG(dentry->d_inode),
bb20add7 5157+ stat.gid, stat.tag));
d337f35e 5158 if (status)
f15949f2
JR
5159 goto out;
5160 }
8de2f54c 5161diff -NurpP --minimal linux-4.4.111/fs/nfsd/nfsxdr.c linux-4.4.111-vs2.3.9.5/fs/nfsd/nfsxdr.c
f19bd705 5162--- linux-4.4.111/fs/nfsd/nfsxdr.c 2018-01-11 07:57:45.000000000 +0000
8de2f54c 5163+++ linux-4.4.111-vs2.3.9.5/fs/nfsd/nfsxdr.c 2018-01-09 16:36:32.000000000 +0000
b00e13aa
AM
5164@@ -7,6 +7,7 @@
5165 #include "vfs.h"
2bf5ad28 5166 #include "xdr.h"
2380c486 5167 #include "auth.h"
2bf5ad28 5168+#include <linux/vs_tag.h>
d337f35e
JR
5169
5170 #define NFSDDBG_FACILITY NFSDDBG_XDR
2bf5ad28 5171
b00e13aa 5172@@ -89,6 +90,8 @@ static __be32 *
d337f35e
JR
5173 decode_sattr(__be32 *p, struct iattr *iap)
5174 {
5175 u32 tmp, tmp1;
a4a22af8
AM
5176+ kuid_t kuid = GLOBAL_ROOT_UID;
5177+ kgid_t kgid = GLOBAL_ROOT_GID;
d337f35e
JR
5178
5179 iap->ia_valid = 0;
5180
b00e13aa
AM
5181@@ -101,15 +104,18 @@ decode_sattr(__be32 *p, struct iattr *ia
5182 iap->ia_mode = tmp;
d337f35e
JR
5183 }
5184 if ((tmp = ntohl(*p++)) != (u32)-1) {
b00e13aa 5185- iap->ia_uid = make_kuid(&init_user_ns, tmp);
a4a22af8 5186+ kuid = make_kuid(&init_user_ns, tmp);
b00e13aa
AM
5187 if (uid_valid(iap->ia_uid))
5188 iap->ia_valid |= ATTR_UID;
d337f35e
JR
5189 }
5190 if ((tmp = ntohl(*p++)) != (u32)-1) {
b00e13aa 5191- iap->ia_gid = make_kgid(&init_user_ns, tmp);
a4a22af8 5192+ kgid = make_kgid(&init_user_ns, tmp);
b00e13aa
AM
5193 if (gid_valid(iap->ia_gid))
5194 iap->ia_valid |= ATTR_GID;
d337f35e 5195 }
a4a22af8
AM
5196+ iap->ia_uid = INOTAG_KUID(DX_TAG_NFSD, kuid, kgid);
5197+ iap->ia_gid = INOTAG_KGID(DX_TAG_NFSD, kuid, kgid);
5198+ iap->ia_tag = INOTAG_KTAG(DX_TAG_NFSD, kuid, kgid, GLOBAL_ROOT_TAG);
d337f35e
JR
5199 if ((tmp = ntohl(*p++)) != (u32)-1) {
5200 iap->ia_valid |= ATTR_SIZE;
5201 iap->ia_size = tmp;
b00e13aa 5202@@ -154,8 +160,10 @@ encode_fattr(struct svc_rqst *rqstp, __b
d337f35e
JR
5203 *p++ = htonl(nfs_ftypes[type >> 12]);
5204 *p++ = htonl((u32) stat->mode);
5205 *p++ = htonl((u32) stat->nlink);
b00e13aa
AM
5206- *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
5207- *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
5208+ *p++ = htonl((u32) from_kuid(&init_user_ns,
a4a22af8 5209+ TAGINO_KUID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
b00e13aa 5210+ *p++ = htonl((u32) from_kgid(&init_user_ns,
a4a22af8 5211+ TAGINO_KGID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
d337f35e
JR
5212
5213 if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
5214 *p++ = htonl(NFS_MAXPATHLEN);
8de2f54c 5215diff -NurpP --minimal linux-4.4.111/fs/ocfs2/dlmglue.c linux-4.4.111-vs2.3.9.5/fs/ocfs2/dlmglue.c
f19bd705 5216--- linux-4.4.111/fs/ocfs2/dlmglue.c 2018-01-11 07:57:46.000000000 +0000
8de2f54c 5217+++ linux-4.4.111-vs2.3.9.5/fs/ocfs2/dlmglue.c 2018-01-09 16:36:32.000000000 +0000
927ca606 5218@@ -2128,6 +2128,7 @@ static void __ocfs2_stuff_meta_lvb(struc
d337f35e 5219 lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters);
b00e13aa
AM
5220 lvb->lvb_iuid = cpu_to_be32(i_uid_read(inode));
5221 lvb->lvb_igid = cpu_to_be32(i_gid_read(inode));
a4a22af8 5222+ lvb->lvb_itag = cpu_to_be16(i_tag_read(inode));
d337f35e
JR
5223 lvb->lvb_imode = cpu_to_be16(inode->i_mode);
5224 lvb->lvb_inlink = cpu_to_be16(inode->i_nlink);
5225 lvb->lvb_iatime_packed =
927ca606 5226@@ -2178,6 +2179,7 @@ static void ocfs2_refresh_inode_from_lvb
d337f35e 5227
b00e13aa
AM
5228 i_uid_write(inode, be32_to_cpu(lvb->lvb_iuid));
5229 i_gid_write(inode, be32_to_cpu(lvb->lvb_igid));
5230+ i_tag_write(inode, be16_to_cpu(lvb->lvb_itag));
d337f35e 5231 inode->i_mode = be16_to_cpu(lvb->lvb_imode);
f6c5ef8b 5232 set_nlink(inode, be16_to_cpu(lvb->lvb_inlink));
d337f35e 5233 ocfs2_unpack_timespec(&inode->i_atime,
8de2f54c 5234diff -NurpP --minimal linux-4.4.111/fs/ocfs2/dlmglue.h linux-4.4.111-vs2.3.9.5/fs/ocfs2/dlmglue.h
f19bd705 5235--- linux-4.4.111/fs/ocfs2/dlmglue.h 2018-01-11 07:57:46.000000000 +0000
8de2f54c 5236+++ linux-4.4.111-vs2.3.9.5/fs/ocfs2/dlmglue.h 2018-01-09 16:36:32.000000000 +0000
2380c486
JR
5237@@ -46,7 +46,8 @@ struct ocfs2_meta_lvb {
5238 __be16 lvb_inlink;
5239 __be32 lvb_iattr;
5240 __be32 lvb_igeneration;
5241- __be32 lvb_reserved2;
d337f35e 5242+ __be16 lvb_itag;
2380c486
JR
5243+ __be16 lvb_reserved2;
5244 };
5245
ec22aa5c 5246 #define OCFS2_QINFO_LVB_VERSION 1
8de2f54c 5247diff -NurpP --minimal linux-4.4.111/fs/ocfs2/file.c linux-4.4.111-vs2.3.9.5/fs/ocfs2/file.c
f19bd705 5248--- linux-4.4.111/fs/ocfs2/file.c 2018-01-11 07:57:46.000000000 +0000
8de2f54c 5249+++ linux-4.4.111-vs2.3.9.5/fs/ocfs2/file.c 2018-01-09 16:36:32.000000000 +0000
927ca606 5250@@ -1151,7 +1151,7 @@ int ocfs2_setattr(struct dentry *dentry,
763640ca 5251 attr->ia_valid &= ~ATTR_SIZE;
d337f35e
JR
5252
5253 #define OCFS2_VALID_ATTRS (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_SIZE \
5254- | ATTR_GID | ATTR_UID | ATTR_MODE)
5255+ | ATTR_GID | ATTR_UID | ATTR_TAG | ATTR_MODE)
763640ca 5256 if (!(attr->ia_valid & OCFS2_VALID_ATTRS))
d337f35e 5257 return 0;
763640ca 5258
8de2f54c 5259diff -NurpP --minimal linux-4.4.111/fs/ocfs2/inode.c linux-4.4.111-vs2.3.9.5/fs/ocfs2/inode.c
f19bd705 5260--- linux-4.4.111/fs/ocfs2/inode.c 2016-07-05 04:12:34.000000000 +0000
8de2f54c 5261+++ linux-4.4.111-vs2.3.9.5/fs/ocfs2/inode.c 2018-01-09 16:36:32.000000000 +0000
78865d5b 5262@@ -28,6 +28,7 @@
d337f35e
JR
5263 #include <linux/highmem.h>
5264 #include <linux/pagemap.h>
ec22aa5c 5265 #include <linux/quotaops.h>
d337f35e
JR
5266+#include <linux/vs_tag.h>
5267
5268 #include <asm/byteorder.h>
5269
537831f9 5270@@ -78,11 +79,13 @@ void ocfs2_set_inode_flags(struct inode
2380c486
JR
5271 {
5272 unsigned int flags = OCFS2_I(inode)->ip_attr;
5273
5274- inode->i_flags &= ~(S_IMMUTABLE |
5275+ inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK |
5276 S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
d337f35e
JR
5277
5278 if (flags & OCFS2_IMMUTABLE_FL)
5279 inode->i_flags |= S_IMMUTABLE;
2380c486
JR
5280+ if (flags & OCFS2_IXUNLINK_FL)
5281+ inode->i_flags |= S_IXUNLINK;
d337f35e
JR
5282
5283 if (flags & OCFS2_SYNC_FL)
5284 inode->i_flags |= S_SYNC;
537831f9 5285@@ -92,25 +95,44 @@ void ocfs2_set_inode_flags(struct inode
2380c486
JR
5286 inode->i_flags |= S_NOATIME;
5287 if (flags & OCFS2_DIRSYNC_FL)
d337f35e 5288 inode->i_flags |= S_DIRSYNC;
2380c486
JR
5289+
5290+ inode->i_vflags &= ~(V_BARRIER | V_COW);
5291+
5292+ if (flags & OCFS2_BARRIER_FL)
5293+ inode->i_vflags |= V_BARRIER;
5294+ if (flags & OCFS2_COW_FL)
5295+ inode->i_vflags |= V_COW;
d337f35e
JR
5296 }
5297
2380c486
JR
5298 /* Propagate flags from i_flags to OCFS2_I(inode)->ip_attr */
5299 void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi)
5300 {
5301 unsigned int flags = oi->vfs_inode.i_flags;
5302+ unsigned int vflags = oi->vfs_inode.i_vflags;
5303+
5304+ oi->ip_attr &= ~(OCFS2_SYNC_FL | OCFS2_APPEND_FL |
5305+ OCFS2_IMMUTABLE_FL | OCFS2_IXUNLINK_FL |
5306+ OCFS2_NOATIME_FL | OCFS2_DIRSYNC_FL |
5307+ OCFS2_BARRIER_FL | OCFS2_COW_FL);
5308+
5309+ if (flags & S_IMMUTABLE)
5310+ oi->ip_attr |= OCFS2_IMMUTABLE_FL;
5311+ if (flags & S_IXUNLINK)
5312+ oi->ip_attr |= OCFS2_IXUNLINK_FL;
5313
5314- oi->ip_attr &= ~(OCFS2_SYNC_FL|OCFS2_APPEND_FL|
5315- OCFS2_IMMUTABLE_FL|OCFS2_NOATIME_FL|OCFS2_DIRSYNC_FL);
5316 if (flags & S_SYNC)
5317 oi->ip_attr |= OCFS2_SYNC_FL;
5318 if (flags & S_APPEND)
5319 oi->ip_attr |= OCFS2_APPEND_FL;
5320- if (flags & S_IMMUTABLE)
5321- oi->ip_attr |= OCFS2_IMMUTABLE_FL;
5322 if (flags & S_NOATIME)
5323 oi->ip_attr |= OCFS2_NOATIME_FL;
5324 if (flags & S_DIRSYNC)
5325 oi->ip_attr |= OCFS2_DIRSYNC_FL;
5326+
5327+ if (vflags & V_BARRIER)
5328+ oi->ip_attr |= OCFS2_BARRIER_FL;
5329+ if (vflags & V_COW)
5330+ oi->ip_attr |= OCFS2_COW_FL;
2380c486
JR
5331 }
5332
ec22aa5c 5333 struct inode *ocfs2_ilookup(struct super_block *sb, u64 blkno)
bb20add7 5334@@ -268,6 +290,8 @@ void ocfs2_populate_inode(struct inode *
d337f35e
JR
5335 struct super_block *sb;
5336 struct ocfs2_super *osb;
ec22aa5c 5337 int use_plocks = 1;
d337f35e
JR
5338+ uid_t uid;
5339+ gid_t gid;
5340
763640ca
JR
5341 sb = inode->i_sb;
5342 osb = OCFS2_SB(sb);
bb20add7 5343@@ -296,8 +320,12 @@ void ocfs2_populate_inode(struct inode *
d337f35e
JR
5344 inode->i_generation = le32_to_cpu(fe->i_generation);
5345 inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
5346 inode->i_mode = le16_to_cpu(fe->i_mode);
b00e13aa
AM
5347- i_uid_write(inode, le32_to_cpu(fe->i_uid));
5348- i_gid_write(inode, le32_to_cpu(fe->i_gid));
d337f35e
JR
5349+ uid = le32_to_cpu(fe->i_uid);
5350+ gid = le32_to_cpu(fe->i_gid);
b00e13aa
AM
5351+ i_uid_write(inode, INOTAG_UID(DX_TAG(inode), uid, gid));
5352+ i_gid_write(inode, INOTAG_GID(DX_TAG(inode), uid, gid));
5353+ i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), uid, gid,
5354+ /* le16_to_cpu(raw_inode->i_raw_tag) */ 0));
d337f35e
JR
5355
5356 /* Fast symlinks will have i_size but no allocated clusters. */
42bc425c 5357 if (S_ISLNK(inode->i_mode) && !fe->i_clusters) {
8de2f54c 5358diff -NurpP --minimal linux-4.4.111/fs/ocfs2/inode.h linux-4.4.111-vs2.3.9.5/fs/ocfs2/inode.h
f19bd705 5359--- linux-4.4.111/fs/ocfs2/inode.h 2016-07-05 04:15:08.000000000 +0000
8de2f54c 5360+++ linux-4.4.111-vs2.3.9.5/fs/ocfs2/inode.h 2018-01-09 16:36:32.000000000 +0000
927ca606 5361@@ -161,6 +161,7 @@ struct buffer_head *ocfs2_bread(struct i
d337f35e
JR
5362
5363 void ocfs2_set_inode_flags(struct inode *inode);
2380c486 5364 void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi);
d4263eb0 5365+int ocfs2_sync_flags(struct inode *inode, int, int);
d337f35e 5366
2380c486
JR
5367 static inline blkcnt_t ocfs2_inode_sector_count(struct inode *inode)
5368 {
8de2f54c 5369diff -NurpP --minimal linux-4.4.111/fs/ocfs2/ioctl.c linux-4.4.111-vs2.3.9.5/fs/ocfs2/ioctl.c
f19bd705 5370--- linux-4.4.111/fs/ocfs2/ioctl.c 2015-10-29 09:21:37.000000000 +0000
8de2f54c 5371+++ linux-4.4.111-vs2.3.9.5/fs/ocfs2/ioctl.c 2018-01-09 16:36:32.000000000 +0000
1e8b8f9b 5372@@ -76,7 +76,41 @@ static int ocfs2_get_inode_attr(struct i
d337f35e
JR
5373 return status;
5374 }
5375
5376-static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
d4263eb0
JR
5377+int ocfs2_sync_flags(struct inode *inode, int flags, int vflags)
5378+{
5379+ struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
5380+ struct buffer_head *bh = NULL;
5381+ handle_t *handle = NULL;
5382+ int status;
5383+
5384+ status = ocfs2_inode_lock(inode, &bh, 1);
5385+ if (status < 0) {
5386+ mlog_errno(status);
5387+ return status;
5388+ }
5389+ handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
5390+ if (IS_ERR(handle)) {
5391+ status = PTR_ERR(handle);
5392+ mlog_errno(status);
5393+ goto bail_unlock;
5394+ }
5395+
5396+ inode->i_flags = flags;
5397+ inode->i_vflags = vflags;
5398+ ocfs2_get_inode_flags(OCFS2_I(inode));
5399+
5400+ status = ocfs2_mark_inode_dirty(handle, inode, bh);
5401+ if (status < 0)
5402+ mlog_errno(status);
5403+
5404+ ocfs2_commit_trans(osb, handle);
5405+bail_unlock:
5406+ ocfs2_inode_unlock(inode, 1);
5407+ brelse(bh);
5408+ return status;
5409+}
5410+
d337f35e
JR
5411+int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
5412 unsigned mask)
5413 {
5414 struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
09be7631
JR
5415@@ -116,6 +150,11 @@ static int ocfs2_set_inode_attr(struct i
5416 goto bail_unlock;
5417 }
2380c486
JR
5418
5419+ if (IS_BARRIER(inode)) {
5420+ vxwprintk_task(1, "messing with the barrier.");
5421+ goto bail_unlock;
5422+ }
5423+
5424 handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
5425 if (IS_ERR(handle)) {
5426 status = PTR_ERR(handle);
bb20add7 5427@@ -841,6 +880,7 @@ bail:
d4263eb0
JR
5428 return status;
5429 }
d337f35e 5430
d337f35e 5431+
d4263eb0
JR
5432 long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
5433 {
b00e13aa 5434 struct inode *inode = file_inode(filp);
8de2f54c 5435diff -NurpP --minimal linux-4.4.111/fs/ocfs2/namei.c linux-4.4.111-vs2.3.9.5/fs/ocfs2/namei.c
f19bd705 5436--- linux-4.4.111/fs/ocfs2/namei.c 2018-01-11 07:57:46.000000000 +0000
8de2f54c 5437+++ linux-4.4.111-vs2.3.9.5/fs/ocfs2/namei.c 2018-01-09 16:36:32.000000000 +0000
ec22aa5c 5438@@ -41,6 +41,7 @@
d337f35e
JR
5439 #include <linux/slab.h>
5440 #include <linux/highmem.h>
ec22aa5c 5441 #include <linux/quotaops.h>
d337f35e
JR
5442+#include <linux/vs_tag.h>
5443
d337f35e 5444 #include <cluster/masklog.h>
763640ca 5445
927ca606 5446@@ -516,6 +517,7 @@ static int __ocfs2_mknod_locked(struct i
93de0823 5447 struct ocfs2_extent_list *fel;
ec22aa5c 5448 u16 feat;
265de2f7 5449 struct ocfs2_inode_info *oi = OCFS2_I(inode);
a4a22af8 5450+ ktag_t ktag;
d337f35e 5451
7e46296a
AM
5452 *new_fe_bh = NULL;
5453
927ca606 5454@@ -553,8 +555,13 @@ static int __ocfs2_mknod_locked(struct i
76514441 5455 fe->i_suballoc_loc = cpu_to_le64(suballoc_loc);
d337f35e 5456 fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
2380c486 5457 fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot);
b00e13aa
AM
5458- fe->i_uid = cpu_to_le32(i_uid_read(inode));
5459- fe->i_gid = cpu_to_le32(i_gid_read(inode));
d337f35e 5460+
a4a22af8
AM
5461+ ktag = make_ktag(&init_user_ns, dx_current_fstag(osb->sb));
5462+ fe->i_uid = cpu_to_le32(from_kuid(&init_user_ns,
5463+ TAGINO_KUID(DX_TAG(inode), inode->i_uid, ktag)));
5464+ fe->i_gid = cpu_to_le32(from_kgid(&init_user_ns,
5465+ TAGINO_KGID(DX_TAG(inode), inode->i_gid, ktag)));
5466+ inode->i_tag = ktag; /* is this correct? */
ec22aa5c
AM
5467 fe->i_mode = cpu_to_le16(inode->i_mode);
5468 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
d337f35e 5469 fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
8de2f54c 5470diff -NurpP --minimal linux-4.4.111/fs/ocfs2/ocfs2.h linux-4.4.111-vs2.3.9.5/fs/ocfs2/ocfs2.h
f19bd705 5471--- linux-4.4.111/fs/ocfs2/ocfs2.h 2018-01-11 07:57:46.000000000 +0000
8de2f54c 5472+++ linux-4.4.111-vs2.3.9.5/fs/ocfs2/ocfs2.h 2018-01-09 17:21:54.000000000 +0000
927ca606
AM
5473@@ -289,6 +289,7 @@ enum ocfs2_mount_options
5474 OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT = 1 << 15, /* Journal Async Commit */
5475 OCFS2_MOUNT_ERRORS_CONT = 1 << 16, /* Return EIO to the calling process on error */
5476 OCFS2_MOUNT_ERRORS_ROFS = 1 << 17, /* Change filesystem to read-only on error */
5477+ OCFS2_MOUNT_TAGGED = 1 << 18, /* use tagging */
d33d7b00
AM
5478 };
5479
bb20add7 5480 #define OCFS2_OSB_SOFT_RO 0x0001
8de2f54c 5481diff -NurpP --minimal linux-4.4.111/fs/ocfs2/ocfs2_fs.h linux-4.4.111-vs2.3.9.5/fs/ocfs2/ocfs2_fs.h
f19bd705 5482--- linux-4.4.111/fs/ocfs2/ocfs2_fs.h 2016-07-05 04:12:34.000000000 +0000
8de2f54c 5483+++ linux-4.4.111-vs2.3.9.5/fs/ocfs2/ocfs2_fs.h 2018-01-09 16:36:32.000000000 +0000
927ca606 5484@@ -275,6 +275,11 @@
93de0823
AM
5485 #define OCFS2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/
5486 #define OCFS2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */
2380c486 5487
93de0823
AM
5488+#define OCFS2_IXUNLINK_FL FS_IXUNLINK_FL /* Immutable invert on unlink */
5489+
5490+#define OCFS2_BARRIER_FL FS_BARRIER_FL /* Barrier for chroot() */
5491+#define OCFS2_COW_FL FS_COW_FL /* Copy on Write marker */
5492+
5493 #define OCFS2_FL_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */
5494 #define OCFS2_FL_MODIFIABLE FS_FL_USER_MODIFIABLE /* User modifiable flags */
5495
8de2f54c 5496diff -NurpP --minimal linux-4.4.111/fs/ocfs2/super.c linux-4.4.111-vs2.3.9.5/fs/ocfs2/super.c
f19bd705 5497--- linux-4.4.111/fs/ocfs2/super.c 2016-07-05 04:12:34.000000000 +0000
8de2f54c 5498+++ linux-4.4.111-vs2.3.9.5/fs/ocfs2/super.c 2018-01-09 17:22:51.000000000 +0000
927ca606 5499@@ -193,6 +193,7 @@ enum {
76514441 5500 Opt_dir_resv_level,
927ca606
AM
5501 Opt_journal_async_commit,
5502 Opt_err_cont,
d337f35e
JR
5503+ Opt_tag, Opt_notag, Opt_tagid,
5504 Opt_err,
5505 };
5506
927ca606 5507@@ -226,6 +227,9 @@ static const match_table_t tokens = {
76514441 5508 {Opt_dir_resv_level, "dir_resv_level=%u"},
927ca606
AM
5509 {Opt_journal_async_commit, "journal_async_commit"},
5510 {Opt_err_cont, "errors=continue"},
d337f35e 5511+ {Opt_tag, "tag"},
d337f35e
JR
5512+ {Opt_notag, "notag"},
5513+ {Opt_tagid, "tagid=%u"},
5514 {Opt_err, NULL}
5515 };
5516
927ca606 5517@@ -677,6 +681,13 @@ static int ocfs2_remount(struct super_bl
d337f35e
JR
5518 goto out;
5519 }
5520
d4263eb0
JR
5521+ if ((osb->s_mount_opt & OCFS2_MOUNT_TAGGED) !=
5522+ (parsed_options.mount_opt & OCFS2_MOUNT_TAGGED)) {
d337f35e
JR
5523+ ret = -EINVAL;
5524+ mlog(ML_ERROR, "Cannot change tagging on remount\n");
5525+ goto out;
5526+ }
5527+
ab30d09f
AM
5528 /* We're going to/from readonly mode. */
5529 if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
5530 /* Disable quota accounting before remounting RO */
927ca606 5531@@ -1166,6 +1177,9 @@ static int ocfs2_fill_super(struct super
d337f35e
JR
5532
5533 ocfs2_complete_mount_recovery(osb);
5534
5535+ if (osb->s_mount_opt & OCFS2_MOUNT_TAGGED)
5536+ sb->s_flags |= MS_TAGGED;
5537+
2380c486
JR
5538 if (ocfs2_mount_local(osb))
5539 snprintf(nodestr, sizeof(nodestr), "local");
5540 else
927ca606
AM
5541@@ -1486,6 +1500,20 @@ static int ocfs2_parse_options(struct su
5542 case Opt_journal_async_commit:
5543 mopt->mount_opt |= OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT;
d337f35e
JR
5544 break;
5545+#ifndef CONFIG_TAGGING_NONE
5546+ case Opt_tag:
2380c486 5547+ mopt->mount_opt |= OCFS2_MOUNT_TAGGED;
d337f35e
JR
5548+ break;
5549+ case Opt_notag:
2380c486 5550+ mopt->mount_opt &= ~OCFS2_MOUNT_TAGGED;
d337f35e
JR
5551+ break;
5552+#endif
5553+#ifdef CONFIG_PROPAGATE
5554+ case Opt_tagid:
5555+ /* use args[0] */
2380c486 5556+ mopt->mount_opt |= OCFS2_MOUNT_TAGGED;
d337f35e
JR
5557+ break;
5558+#endif
5559 default:
5560 mlog(ML_ERROR,
5561 "Unrecognized mount option \"%s\" "
8de2f54c 5562diff -NurpP --minimal linux-4.4.111/fs/open.c linux-4.4.111-vs2.3.9.5/fs/open.c
f19bd705 5563--- linux-4.4.111/fs/open.c 2018-01-11 07:57:46.000000000 +0000
8de2f54c 5564+++ linux-4.4.111-vs2.3.9.5/fs/open.c 2018-01-09 16:36:32.000000000 +0000
b00e13aa 5565@@ -31,6 +31,11 @@
2bf5ad28 5566 #include <linux/ima.h>
93de0823 5567 #include <linux/dnotify.h>
b00e13aa 5568 #include <linux/compat.h>
d337f35e
JR
5569+#include <linux/vs_base.h>
5570+#include <linux/vs_limit.h>
d337f35e
JR
5571+#include <linux/vs_tag.h>
5572+#include <linux/vs_cowbl.h>
78865d5b 5573+#include <linux/vserver/dlimit.h>
d337f35e 5574
2bf5ad28
AM
5575 #include "internal.h"
5576
927ca606 5577@@ -70,6 +75,11 @@ long vfs_truncate(struct path *path, lof
b00e13aa
AM
5578 struct inode *inode;
5579 long error;
5580
76514441 5581+#ifdef CONFIG_VSERVER_COWBL
b00e13aa 5582+ error = cow_check_and_break(path);
d337f35e 5583+ if (error)
b00e13aa 5584+ goto out;
76514441 5585+#endif
b00e13aa 5586 inode = path->dentry->d_inode;
d337f35e 5587
a168f21d 5588 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
927ca606 5589@@ -548,6 +558,13 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons
b00e13aa
AM
5590 unsigned int lookup_flags = LOOKUP_FOLLOW;
5591 retry:
5592 error = user_path_at(dfd, filename, lookup_flags, &path);
a168f21d 5593+#ifdef CONFIG_VSERVER_COWBL
b00e13aa 5594+ if (!error) {
a168f21d 5595+ error = cow_check_and_break(&path);
b00e13aa
AM
5596+ if (error)
5597+ path_put(&path);
5598+ }
a168f21d 5599+#endif
b00e13aa 5600 if (!error) {
a168f21d
AM
5601 error = chmod_common(&path, mode);
5602 path_put(&path);
927ca606 5603@@ -582,13 +599,15 @@ retry_deleg:
42bc425c
AM
5604 if (!uid_valid(uid))
5605 return -EINVAL;
d337f35e 5606 newattrs.ia_valid |= ATTR_UID;
42bc425c 5607- newattrs.ia_uid = uid;
8ce283e1
AM
5608+ newattrs.ia_uid = make_kuid(&init_user_ns,
5609+ dx_map_uid(user));
d337f35e
JR
5610 }
5611 if (group != (gid_t) -1) {
42bc425c
AM
5612 if (!gid_valid(gid))
5613 return -EINVAL;
d337f35e 5614 newattrs.ia_valid |= ATTR_GID;
42bc425c 5615- newattrs.ia_gid = gid;
8ce283e1
AM
5616+ newattrs.ia_gid = make_kgid(&init_user_ns,
5617+ dx_map_gid(group));
d337f35e
JR
5618 }
5619 if (!S_ISDIR(inode->i_mode))
2380c486 5620 newattrs.ia_valid |=
927ca606 5621@@ -626,6 +645,10 @@ retry:
2380c486 5622 error = mnt_want_write(path.mnt);
d337f35e 5623 if (error)
2380c486 5624 goto out_release;
d337f35e 5625+#ifdef CONFIG_VSERVER_COWBL
2380c486 5626+ error = cow_check_and_break(&path);
d337f35e 5627+ if (!error)
d337f35e 5628+#endif
2bf5ad28 5629 error = chown_common(&path, user, group);
2380c486
JR
5630 mnt_drop_write(path.mnt);
5631 out_release:
8de2f54c 5632diff -NurpP --minimal linux-4.4.111/fs/proc/array.c linux-4.4.111-vs2.3.9.5/fs/proc/array.c
f19bd705 5633--- linux-4.4.111/fs/proc/array.c 2018-01-11 07:57:46.000000000 +0000
8de2f54c 5634+++ linux-4.4.111-vs2.3.9.5/fs/proc/array.c 2018-01-09 17:30:44.000000000 +0000
927ca606 5635@@ -83,6 +83,8 @@
2380c486 5636 #include <linux/tracehook.h>
927ca606 5637 #include <linux/string_helpers.h>
42bc425c 5638 #include <linux/user_namespace.h>
d337f35e
JR
5639+#include <linux/vs_context.h>
5640+#include <linux/vs_network.h>
5641
d337f35e 5642 #include <asm/pgtable.h>
2380c486 5643 #include <asm/processor.h>
927ca606 5644@@ -154,6 +156,9 @@ static inline void task_state(struct seq
2380c486
JR
5645 ppid = pid_alive(p) ?
5646 task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
927ca606 5647
2380c486
JR
5648+ if (unlikely(vx_current_initpid(p->pid)))
5649+ ppid = 0;
5650+
927ca606
AM
5651 tracer = ptrace_parent(p);
5652 if (tracer)
5653 tpid = task_pid_nr_ns(tracer, ns);
5654@@ -292,8 +297,8 @@ static inline void task_sig(struct seq_f
bb20add7 5655 render_sigset_t(m, "SigCgt:\t", &caught);
2380c486
JR
5656 }
5657
bb20add7 5658-static void render_cap_t(struct seq_file *m, const char *header,
2380c486 5659- kernel_cap_t *a)
bb20add7 5660+void render_cap_t(struct seq_file *m, const char *header,
2380c486 5661+ struct vx_info *vxi, kernel_cap_t *a)
d337f35e 5662 {
2380c486
JR
5663 unsigned __capi;
5664
927ca606
AM
5665@@ -320,11 +325,12 @@ static inline void task_cap(struct seq_f
5666 cap_ambient = cred->cap_ambient;
bb20add7 5667 rcu_read_unlock();
2380c486 5668
ec22aa5c
AM
5669- render_cap_t(m, "CapInh:\t", &cap_inheritable);
5670- render_cap_t(m, "CapPrm:\t", &cap_permitted);
5671- render_cap_t(m, "CapEff:\t", &cap_effective);
5672- render_cap_t(m, "CapBnd:\t", &cap_bset);
927ca606 5673- render_cap_t(m, "CapAmb:\t", &cap_ambient);
ec22aa5c
AM
5674+ /* FIXME: maybe move the p->vx_info masking to __task_cred() ? */
5675+ render_cap_t(m, "CapInh:\t", p->vx_info, &cap_inheritable);
5676+ render_cap_t(m, "CapPrm:\t", p->vx_info, &cap_permitted);
5677+ render_cap_t(m, "CapEff:\t", p->vx_info, &cap_effective);
5678+ render_cap_t(m, "CapBnd:\t", p->vx_info, &cap_bset);
927ca606 5679+ render_cap_t(m, "CapAmb:\t", p->vx_info, &cap_ambient);
d337f35e
JR
5680 }
5681
b00e13aa 5682 static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
927ca606
AM
5683@@ -351,6 +357,43 @@ static void task_cpus_allowed(struct seq
5684 cpumask_pr_args(&task->cpus_allowed));
2380c486
JR
5685 }
5686
5687+int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
5688+ struct pid *pid, struct task_struct *task)
5689+{
5690+ seq_printf(m, "Proxy:\t%p(%c)\n"
5691+ "Count:\t%u\n"
5692+ "uts:\t%p(%c)\n"
5693+ "ipc:\t%p(%c)\n"
5694+ "mnt:\t%p(%c)\n"
5695+ "pid:\t%p(%c)\n"
5696+ "net:\t%p(%c)\n",
5697+ task->nsproxy,
5698+ (task->nsproxy == init_task.nsproxy ? 'I' : '-'),
5699+ atomic_read(&task->nsproxy->count),
5700+ task->nsproxy->uts_ns,
5701+ (task->nsproxy->uts_ns == init_task.nsproxy->uts_ns ? 'I' : '-'),
5702+ task->nsproxy->ipc_ns,
5703+ (task->nsproxy->ipc_ns == init_task.nsproxy->ipc_ns ? 'I' : '-'),
5704+ task->nsproxy->mnt_ns,
5705+ (task->nsproxy->mnt_ns == init_task.nsproxy->mnt_ns ? 'I' : '-'),
c2e5f7c8
JR
5706+ task->nsproxy->pid_ns_for_children,
5707+ (task->nsproxy->pid_ns_for_children ==
5708+ init_task.nsproxy->pid_ns_for_children ? 'I' : '-'),
2380c486
JR
5709+ task->nsproxy->net_ns,
5710+ (task->nsproxy->net_ns == init_task.nsproxy->net_ns ? 'I' : '-'));
5711+ return 0;
5712+}
d337f35e 5713+
2380c486
JR
5714+void task_vs_id(struct seq_file *m, struct task_struct *task)
5715+{
d337f35e 5716+ if (task_vx_flags(task, VXF_HIDE_VINFO, 0))
2380c486
JR
5717+ return;
5718+
bb20add7
AM
5719+ seq_printf(m, "VxID:\t%d\n", vx_task_xid(task));
5720+ seq_printf(m, "NxID:\t%d\n", nx_task_nid(task));
2380c486
JR
5721+}
5722+
5723+
5724 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
5725 struct pid *pid, struct task_struct *task)
5726 {
927ca606 5727@@ -368,6 +411,7 @@ int proc_pid_status(struct seq_file *m,
b00e13aa 5728 task_seccomp(m, task);
2bf5ad28 5729 task_cpus_allowed(m, task);
2380c486
JR
5730 cpuset_task_status_allowed(m, task);
5731+ task_vs_id(m, task);
152aeb71
JR
5732 task_context_switch_counts(m, task);
5733 return 0;
5734 }
927ca606 5735@@ -471,6 +515,17 @@ static int do_task_stat(struct seq_file
d337f35e 5736 /* convert nsec -> ticks */
bb20add7 5737 start_time = nsec_to_clock_t(task->real_start_time);
d337f35e
JR
5738
5739+ /* fixup start time for virt uptime */
5740+ if (vx_flags(VXF_VIRT_UPTIME, 0)) {
5741+ unsigned long long bias =
5742+ current->vx_info->cvirt.bias_clock;
5743+
5744+ if (start_time > bias)
5745+ start_time -= bias;
5746+ else
5747+ start_time = 0;
5748+ }
5749+
1e8b8f9b
AM
5750 seq_printf(m, "%d (%s) %c", pid_nr_ns(pid, ns), tcomm, state);
5751 seq_put_decimal_ll(m, ' ', ppid);
5752 seq_put_decimal_ll(m, ' ', pgid);
8de2f54c 5753diff -NurpP --minimal linux-4.4.111/fs/proc/base.c linux-4.4.111-vs2.3.9.5/fs/proc/base.c
f19bd705 5754--- linux-4.4.111/fs/proc/base.c 2018-01-11 07:57:46.000000000 +0000
8de2f54c 5755+++ linux-4.4.111-vs2.3.9.5/fs/proc/base.c 2018-01-09 16:36:32.000000000 +0000
09be7631 5756@@ -87,6 +87,8 @@
78865d5b 5757 #include <linux/slab.h>
db55b927 5758 #include <linux/flex_array.h>
09be7631 5759 #include <linux/posix-timers.h>
d337f35e
JR
5760+#include <linux/vs_context.h>
5761+#include <linux/vs_network.h>
763640ca
JR
5762 #ifdef CONFIG_HARDWALL
5763 #include <asm/hardwall.h>
5764 #endif
927ca606 5765@@ -1097,11 +1099,15 @@ static ssize_t oom_adj_write(struct file
537831f9 5766 oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
7e46296a 5767
537831f9
AM
5768 if (oom_adj < task->signal->oom_score_adj &&
5769- !capable(CAP_SYS_RESOURCE)) {
5770+ !vx_capable(CAP_SYS_RESOURCE, VXC_OOM_ADJUST)) {
ab30d09f
AM
5771 err = -EACCES;
5772 goto err_sighand;
4a036bed 5773 }
7e46296a 5774
4a036bed 5775+ /* prevent guest processes from circumventing the oom killer */
537831f9
AM
5776+ if (vx_current_xid() && (oom_adj == OOM_DISABLE))
5777+ oom_adj = OOM_ADJUST_MIN;
7e46296a 5778+
f6c5ef8b 5779 /*
537831f9
AM
5780 * /proc/pid/oom_adj is provided for legacy purposes, ask users to use
5781 * /proc/pid/oom_score_adj instead.
927ca606 5782@@ -1666,6 +1672,8 @@ struct inode *proc_pid_make_inode(struct
ec22aa5c
AM
5783 inode->i_gid = cred->egid;
5784 rcu_read_unlock();
d337f35e
JR
5785 }
5786+ /* procfs is xid tagged */
61333608 5787+ i_tag_write(inode, (vtag_t)vx_task_xid(task));
d337f35e
JR
5788 security_task_to_inode(task, inode);
5789
5790 out:
927ca606 5791@@ -1711,6 +1719,8 @@ int pid_getattr(struct vfsmount *mnt, st
d33d7b00
AM
5792
5793 /* dentry stuff */
5794
bb20add7 5795+// static unsigned name_to_int(struct dentry *dentry);
d33d7b00
AM
5796+
5797 /*
5798 * Exceptional case: normally we are not allowed to unhash a busy
5799 * directory. In this case, however, we can do it - no aliasing problems
927ca606 5800@@ -1739,6 +1749,19 @@ int pid_revalidate(struct dentry *dentry
d33d7b00
AM
5801 task = get_proc_task(inode);
5802
5803 if (task) {
bb20add7
AM
5804+ unsigned pid = name_to_int(&dentry->d_name);
5805+
5806+ if (pid != ~0U && pid != vx_map_pid(task->pid) &&
5807+ pid != __task_pid_nr_ns(task, PIDTYPE_PID,
5808+ task_active_pid_ns(task))) {
5809+ vxdprintk(VXD_CBIT(misc, 10),
5810+ VS_Q("%*s") " dropped by pid_revalidate(%d!=%d)",
5811+ dentry->d_name.len, dentry->d_name.name,
5812+ pid, vx_map_pid(task->pid));
d33d7b00 5813+ put_task_struct(task);
bb20add7
AM
5814+ d_drop(dentry);
5815+ return 0;
d33d7b00
AM
5816+ }
5817 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
5818 task_dumpable(task)) {
5819 rcu_read_lock();
927ca606 5820@@ -2283,6 +2306,13 @@ static struct dentry *proc_pident_lookup
d337f35e
JR
5821 if (!task)
5822 goto out_no_task;
5823
2380c486 5824+ /* TODO: maybe we can come up with a generic approach? */
d337f35e
JR
5825+ if (task_vx_flags(task, VXF_HIDE_VINFO, 0) &&
5826+ (dentry->d_name.len == 5) &&
5827+ (!memcmp(dentry->d_name.name, "vinfo", 5) ||
5828+ !memcmp(dentry->d_name.name, "ninfo", 5)))
5829+ goto out;
5830+
5831 /*
5832 * Yes, it does not scale. And it should not. Don't add
5833 * new entries into /proc/<tgid>/ without very good reasons.
927ca606 5834@@ -2725,6 +2755,11 @@ static int proc_pid_personality(struct s
2380c486
JR
5835 static const struct file_operations proc_task_operations;
5836 static const struct inode_operations proc_task_inode_operations;
d337f35e 5837
bb20add7
AM
5838+extern int proc_pid_vx_info(struct seq_file *,
5839+ struct pid_namespace *, struct pid *, struct task_struct *);
5840+extern int proc_pid_nx_info(struct seq_file *,
5841+ struct pid_namespace *, struct pid *, struct task_struct *);
d337f35e 5842+
2380c486 5843 static const struct pid_entry tgid_base_stuff[] = {
ec22aa5c
AM
5844 DIR("task", S_IRUGO|S_IXUGO, proc_task_inode_operations, proc_task_operations),
5845 DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
927ca606 5846@@ -2789,6 +2824,8 @@ static const struct pid_entry tgid_base_
2380c486 5847 #ifdef CONFIG_CGROUPS
bb20add7 5848 ONE("cgroup", S_IRUGO, proc_cgroup_show),
d337f35e 5849 #endif
bb20add7
AM
5850+ ONE("vinfo", S_IRUGO, proc_pid_vx_info),
5851+ ONE("ninfo", S_IRUGO, proc_pid_nx_info),
5852 ONE("oom_score", S_IRUGO, proc_oom_score),
537831f9 5853 REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
93de0823 5854 REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
927ca606 5855@@ -3003,7 +3040,7 @@ retry:
2380c486
JR
5856 iter.task = NULL;
5857 pid = find_ge_pid(iter.tgid, ns);
5858 if (pid) {
5859- iter.tgid = pid_nr_ns(pid, ns);
5860+ iter.tgid = pid_unmapped_nr_ns(pid, ns);
5861 iter.task = pid_task(pid, PIDTYPE_PID);
5862 /* What we to know is if the pid we have find is the
5863 * pid of a thread_group_leader. Testing for task
927ca606 5864@@ -3063,8 +3100,10 @@ int proc_pid_readdir(struct file *file,
c2e5f7c8
JR
5865 if (!has_pid_permissions(ns, iter.task, 2))
5866 continue;
db55b927 5867
c2e5f7c8
JR
5868- len = snprintf(name, sizeof(name), "%d", iter.tgid);
5869+ len = snprintf(name, sizeof(name), "%d", vx_map_tgid(iter.tgid));
5870 ctx->pos = iter.tgid + TGID_OFFSET;
2380c486 5871+ if (!vx_proc_task_visible(iter.task))
d337f35e 5872+ continue;
c2e5f7c8
JR
5873 if (!proc_fill_cache(file, ctx, name, len,
5874 proc_pid_instantiate, iter.task, NULL)) {
2380c486 5875 put_task_struct(iter.task);
927ca606 5876@@ -3161,6 +3200,7 @@ static const struct pid_entry tid_base_s
09be7631 5877 REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
bb20add7 5878 REG("setgroups", S_IRUGO|S_IWUSR, proc_setgroups_operations),
09be7631
JR
5879 #endif
5880+ ONE("nsproxy", S_IRUGO, proc_pid_nsproxy),
5881 };
5882
c2e5f7c8 5883 static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx)
927ca606 5884@@ -3227,6 +3267,8 @@ static struct dentry *proc_task_lookup(s
bb20add7 5885 tid = name_to_int(&dentry->d_name);
d337f35e
JR
5886 if (tid == ~0U)
5887 goto out;
5888+ if (vx_current_initpid(tid))
5889+ goto out;
5890
2380c486 5891 ns = dentry->d_sb->s_fs_info;
d337f35e 5892 rcu_read_lock();
8de2f54c 5893diff -NurpP --minimal linux-4.4.111/fs/proc/generic.c linux-4.4.111-vs2.3.9.5/fs/proc/generic.c
f19bd705 5894--- linux-4.4.111/fs/proc/generic.c 2018-01-11 07:57:46.000000000 +0000
8de2f54c 5895+++ linux-4.4.111-vs2.3.9.5/fs/proc/generic.c 2018-01-09 17:29:24.000000000 +0000
927ca606 5896@@ -22,6 +22,7 @@
d337f35e
JR
5897 #include <linux/bitops.h>
5898 #include <linux/spinlock.h>
2380c486 5899 #include <linux/completion.h>
d337f35e
JR
5900+#include <linux/vserver/inode.h>
5901 #include <asm/uaccess.h>
5902
5903 #include "internal.h"
927ca606
AM
5904@@ -66,8 +67,16 @@ static struct proc_dir_entry *pde_subdir
5905 node = node->rb_left;
5906 else if (result > 0)
5907 node = node->rb_right;
5908- else
5909+ else {
5910+ if (!vx_hide_check(0, de->vx_flags)) {
5911+ vxdprintk(VXD_CBIT(misc, 9),
5912+ VS_Q("%*s")
5913+ " hidden in pde_subdir_find()",
5914+ de->namelen, de->name);
5915+ return 0;
5916+ }
5917 return de;
bb20add7 5918+ }
927ca606
AM
5919 }
5920 return NULL;
5921 }
5922@@ -241,6 +250,8 @@ struct dentry *proc_lookup_de(struct pro
5923 return ERR_PTR(-ENOMEM);
5924 d_set_d_op(dentry, &simple_dentry_operations);
5925 d_add(dentry, inode);
ba86f833 5926+ /* generic proc entries belong to the host */
537831f9 5927+ i_tag_write(inode, 0);
927ca606 5928 return NULL;
2380c486 5929 }
927ca606
AM
5930 read_unlock(&proc_subdir_lock);
5931@@ -287,6 +298,12 @@ int proc_readdir_de(struct proc_dir_entr
c2e5f7c8
JR
5932 do {
5933 struct proc_dir_entry *next;
5934 pde_get(de);
bb20add7
AM
5935+ if (!vx_hide_check(0, de->vx_flags)) {
5936+ vxdprintk(VXD_CBIT(misc, 9),
5937+ VS_Q("%*s") " hidden in proc_readdir_de()",
5938+ de->namelen, de->name);
c2e5f7c8 5939+ goto skip;
bb20add7 5940+ }
927ca606 5941 read_unlock(&proc_subdir_lock);
c2e5f7c8
JR
5942 if (!dir_emit(ctx, de->name, de->namelen,
5943 de->low_ino, de->mode >> 12)) {
927ca606 5944@@ -294,6 +311,7 @@ int proc_readdir_de(struct proc_dir_entr
c2e5f7c8
JR
5945 return 0;
5946 }
927ca606 5947 read_lock(&proc_subdir_lock);
c2e5f7c8
JR
5948+ skip:
5949 ctx->pos++;
927ca606 5950 next = pde_subdir_next(de);
c2e5f7c8 5951 pde_put(de);
927ca606 5952@@ -387,6 +405,7 @@ static struct proc_dir_entry *__proc_cre
537831f9 5953 ent->mode = mode;
d337f35e 5954 ent->nlink = nlink;
927ca606 5955 ent->subdir = RB_ROOT;
d337f35e 5956+ ent->vx_flags = IATTR_PROC_DEFAULT;
537831f9 5957 atomic_set(&ent->count, 1);
2380c486 5958 spin_lock_init(&ent->pde_unload_lock);
2380c486 5959 INIT_LIST_HEAD(&ent->pde_openers);
927ca606 5960@@ -411,7 +430,8 @@ struct proc_dir_entry *proc_symlink(cons
d337f35e
JR
5961 kfree(ent->data);
5962 kfree(ent);
5963 ent = NULL;
5964- }
5965+ } else
5966+ ent->vx_flags = IATTR_PROC_SYMLINK;
5967 } else {
5968 kfree(ent);
5969 ent = NULL;
8de2f54c 5970diff -NurpP --minimal linux-4.4.111/fs/proc/inode.c linux-4.4.111-vs2.3.9.5/fs/proc/inode.c
f19bd705 5971--- linux-4.4.111/fs/proc/inode.c 2015-10-29 09:21:39.000000000 +0000
8de2f54c 5972+++ linux-4.4.111-vs2.3.9.5/fs/proc/inode.c 2018-01-09 16:36:32.000000000 +0000
927ca606 5973@@ -431,6 +431,8 @@ struct inode *proc_get_inode(struct supe
d337f35e
JR
5974 inode->i_uid = de->uid;
5975 inode->i_gid = de->gid;
5976 }
5977+ if (de->vx_flags)
5978+ PROC_I(inode)->vx_flags = de->vx_flags;
5979 if (de->size)
5980 inode->i_size = de->size;
5981 if (de->nlink)
8de2f54c 5982diff -NurpP --minimal linux-4.4.111/fs/proc/internal.h linux-4.4.111-vs2.3.9.5/fs/proc/internal.h
f19bd705 5983--- linux-4.4.111/fs/proc/internal.h 2015-10-29 09:21:39.000000000 +0000
8de2f54c 5984+++ linux-4.4.111-vs2.3.9.5/fs/proc/internal.h 2018-01-09 16:36:32.000000000 +0000
09be7631
JR
5985@@ -14,6 +14,7 @@
5986 #include <linux/spinlock.h>
5987 #include <linux/atomic.h>
b00e13aa 5988 #include <linux/binfmts.h>
d337f35e
JR
5989+#include <linux/vs_pid.h>
5990
09be7631
JR
5991 struct ctl_table_header;
5992 struct mempolicy;
927ca606 5993@@ -34,6 +35,7 @@ struct proc_dir_entry {
09be7631
JR
5994 nlink_t nlink;
5995 kuid_t uid;
5996 kgid_t gid;
5997+ int vx_flags;
5998 loff_t size;
5999 const struct inode_operations *proc_iops;
6000 const struct file_operations *proc_fops;
927ca606 6001@@ -51,15 +53,22 @@ struct proc_dir_entry {
09be7631
JR
6002 char name[];
6003 };
6004
6005+struct vx_info;
6006+struct nx_info;
2380c486 6007+
09be7631
JR
6008 union proc_op {
6009 int (*proc_get_link)(struct dentry *, struct path *);
09be7631
JR
6010 int (*proc_show)(struct seq_file *m,
6011 struct pid_namespace *ns, struct pid *pid,
6012 struct task_struct *task);
6013+ int (*proc_vs_read)(char *page);
6014+ int (*proc_vxi_read)(struct vx_info *vxi, char *page);
6015+ int (*proc_nxi_read)(struct nx_info *nxi, char *page);
6016 };
2380c486 6017
09be7631
JR
6018 struct proc_inode {
6019 struct pid *pid;
6020+ int vx_flags;
6021 int fd;
6022 union proc_op op;
6023 struct proc_dir_entry *pde;
927ca606 6024@@ -92,11 +101,16 @@ static inline struct pid *proc_pid(struc
d337f35e
JR
6025 return PROC_I(inode)->pid;
6026 }
6027
6028-static inline struct task_struct *get_proc_task(struct inode *inode)
6029+static inline struct task_struct *get_proc_task_real(struct inode *inode)
6030 {
6031 return get_pid_task(proc_pid(inode), PIDTYPE_PID);
6032 }
6033
6034+static inline struct task_struct *get_proc_task(struct inode *inode)
6035+{
6036+ return vx_get_proc_task(inode, proc_pid(inode));
6037+}
6038+
09be7631 6039 static inline int task_dumpable(struct task_struct *task)
d337f35e 6040 {
09be7631 6041 int dumpable = 0;
927ca606 6042@@ -155,6 +169,8 @@ extern int proc_pid_status(struct seq_fi
09be7631
JR
6043 struct pid *, struct task_struct *);
6044 extern int proc_pid_statm(struct seq_file *, struct pid_namespace *,
6045 struct pid *, struct task_struct *);
6046+extern int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
6047+ struct pid *pid, struct task_struct *task);
6048
6049 /*
6050 * base.c
8de2f54c 6051diff -NurpP --minimal linux-4.4.111/fs/proc/loadavg.c linux-4.4.111-vs2.3.9.5/fs/proc/loadavg.c
f19bd705 6052--- linux-4.4.111/fs/proc/loadavg.c 2015-04-12 22:12:50.000000000 +0000
8de2f54c 6053+++ linux-4.4.111-vs2.3.9.5/fs/proc/loadavg.c 2018-01-09 16:36:32.000000000 +0000
ec22aa5c 6054@@ -12,15 +12,27 @@
1bc743c0 6055
ec22aa5c 6056 static int loadavg_proc_show(struct seq_file *m, void *v)
1bc743c0
JR
6057 {
6058+ unsigned long running;
6059+ unsigned int threads;
ec22aa5c 6060 unsigned long avnrun[3];
1bc743c0 6061
ec22aa5c 6062 get_avenrun(avnrun, FIXED_1/200, 0);
bd427b06 6063
ec22aa5c 6064+ if (vx_flags(VXF_VIRT_LOAD, 0)) {
eab5a9a6 6065+ struct vx_info *vxi = current_vx_info();
ec22aa5c
AM
6066+
6067+ running = atomic_read(&vxi->cvirt.nr_running);
6068+ threads = atomic_read(&vxi->cvirt.nr_threads);
6069+ } else {
6070+ running = nr_running();
6071+ threads = nr_threads;
6072+ }
6073+
6074 seq_printf(m, "%lu.%02lu %lu.%02lu %lu.%02lu %ld/%d %d\n",
6075 LOAD_INT(avnrun[0]), LOAD_FRAC(avnrun[0]),
6076 LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]),
6077 LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]),
1bc743c0
JR
6078- nr_running(), nr_threads,
6079+ running, threads,
6080 task_active_pid_ns(current)->last_pid);
ec22aa5c 6081 return 0;
1bc743c0 6082 }
8de2f54c 6083diff -NurpP --minimal linux-4.4.111/fs/proc/meminfo.c linux-4.4.111-vs2.3.9.5/fs/proc/meminfo.c
f19bd705 6084--- linux-4.4.111/fs/proc/meminfo.c 2016-07-05 04:15:09.000000000 +0000
8de2f54c 6085+++ linux-4.4.111-vs2.3.9.5/fs/proc/meminfo.c 2018-01-12 18:43:53.000000000 +0000
927ca606 6086@@ -43,7 +43,8 @@ static int meminfo_proc_show(struct seq_
c2e5f7c8
JR
6087 si_swapinfo(&i);
6088 committed = percpu_counter_read_positive(&vm_committed_as);
e3afe727
AM
6089
6090- cached = global_page_state(NR_FILE_PAGES) -
6091+ cached = vx_flags(VXF_VIRT_MEM, 0) ?
6092+ vx_vsi_cached(&i) : global_page_state(NR_FILE_PAGES) -
b00e13aa 6093 total_swapcache_pages() - i.bufferram;
e3afe727 6094 if (cached < 0)
d337f35e 6095 cached = 0;
8de2f54c
AM
6096@@ -70,13 +71,16 @@ static int meminfo_proc_show(struct seq_
6097 */
6098 pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
6099 pagecache -= min(pagecache / 2, wmark_low);
6100- available += pagecache;
6101+
6102+ if (!vx_flags(VXF_VIRT_MEM, 0))
6103+ available += pagecache;
6104
6105 /*
6106 * Part of the reclaimable slab consists of items that are in use,
6107 * and cannot be freed. Cap this estimate at the low watermark.
6108 */
6109- available += global_page_state(NR_SLAB_RECLAIMABLE) -
6110+ if (!vx_flags(VXF_VIRT_MEM, 0))
6111+ available += global_page_state(NR_SLAB_RECLAIMABLE) -
6112 min(global_page_state(NR_SLAB_RECLAIMABLE) / 2, wmark_low);
6113
6114 if (available < 0)
6115diff -NurpP --minimal linux-4.4.111/fs/proc/root.c linux-4.4.111-vs2.3.9.5/fs/proc/root.c
f19bd705 6116--- linux-4.4.111/fs/proc/root.c 2018-01-11 07:57:46.000000000 +0000
8de2f54c 6117+++ linux-4.4.111-vs2.3.9.5/fs/proc/root.c 2018-01-09 16:36:32.000000000 +0000
b00e13aa 6118@@ -20,9 +20,14 @@
2380c486
JR
6119 #include <linux/mount.h>
6120 #include <linux/pid_namespace.h>
db55b927 6121 #include <linux/parser.h>
2380c486 6122+#include <linux/vserver/inode.h>
d337f35e 6123
2380c486 6124 #include "internal.h"
d337f35e 6125
d337f35e
JR
6126+struct proc_dir_entry *proc_virtual;
6127+
6128+extern void proc_vx_init(void);
2380c486
JR
6129+
6130 static int proc_test_super(struct super_block *sb, void *data)
6131 {
6132 return sb->s_fs_info == data;
927ca606
AM
6133@@ -113,7 +118,8 @@ static struct dentry *proc_mount(struct
6134 options = data;
c2e5f7c8
JR
6135
6136 /* Does the mounter have privilege over the pid namespace? */
6137- if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
6138+ if (!vx_ns_capable(ns->user_ns,
6139+ CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
6140 return ERR_PTR(-EPERM);
6141 }
6142
927ca606 6143@@ -196,6 +202,7 @@ void __init proc_root_init(void)
bb20add7 6144 proc_tty_init();
2380c486
JR
6145 proc_mkdir("bus", NULL);
6146 proc_sys_init();
d337f35e
JR
6147+ proc_vx_init();
6148 }
6149
6150 static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
927ca606 6151@@ -257,6 +264,7 @@ struct proc_dir_entry proc_root = {
2380c486
JR
6152 .proc_iops = &proc_root_inode_operations,
6153 .proc_fops = &proc_root_operations,
6154 .parent = &proc_root,
6155+ .vx_flags = IATTR_ADMIN | IATTR_WATCH,
927ca606 6156 .subdir = RB_ROOT,
a168f21d 6157 .name = "/proc",
2380c486 6158 };
8de2f54c 6159diff -NurpP --minimal linux-4.4.111/fs/proc/self.c linux-4.4.111-vs2.3.9.5/fs/proc/self.c
f19bd705 6160--- linux-4.4.111/fs/proc/self.c 2015-10-29 09:21:39.000000000 +0000
8de2f54c 6161+++ linux-4.4.111-vs2.3.9.5/fs/proc/self.c 2018-01-09 16:36:32.000000000 +0000
927ca606
AM
6162@@ -1,6 +1,7 @@
6163 #include <linux/sched.h>
09be7631
JR
6164 #include <linux/slab.h>
6165 #include <linux/pid_namespace.h>
b00e13aa 6166+#include <linux/vserver/inode.h>
09be7631 6167 #include "internal.h"
b00e13aa
AM
6168
6169 /*
927ca606 6170@@ -52,6 +53,8 @@ int proc_setup_self(struct super_block *
09be7631
JR
6171 self = d_alloc_name(s->s_root, "self");
6172 if (self) {
6173 struct inode *inode = new_inode_pseudo(s);
6174+
6175+ // self->vx_flags = IATTR_PROC_SYMLINK;
6176 if (inode) {
6177 inode->i_ino = self_inum;
6178 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
8de2f54c 6179diff -NurpP --minimal linux-4.4.111/fs/proc/stat.c linux-4.4.111-vs2.3.9.5/fs/proc/stat.c
f19bd705 6180--- linux-4.4.111/fs/proc/stat.c 2015-04-12 22:12:50.000000000 +0000
8de2f54c 6181+++ linux-4.4.111-vs2.3.9.5/fs/proc/stat.c 2018-01-09 16:36:32.000000000 +0000
537831f9 6182@@ -9,8 +9,10 @@
1e8b8f9b
AM
6183 #include <linux/slab.h>
6184 #include <linux/time.h>
6185 #include <linux/irqnr.h>
6186+#include <linux/vserver/cvirt.h>
265de2f7 6187 #include <linux/cputime.h>
1e8b8f9b 6188 #include <linux/tick.h>
537831f9
AM
6189+#include <linux/cpuset.h>
6190
6191 #ifndef arch_irq_stat_cpu
6192 #define arch_irq_stat_cpu(cpu) 0
6193@@ -87,14 +89,26 @@ static int show_stat(struct seq_file *p,
6194 u64 sum_softirq = 0;
6195 unsigned int per_softirq_sums[NR_SOFTIRQS] = {0};
6196 struct timespec boottime;
6197+ cpumask_var_t cpus_allowed;
6198+ bool virt_cpu = vx_flags(VXF_VIRT_CPU, 0);
6199
6200 user = nice = system = idle = iowait =
1e8b8f9b
AM
6201 irq = softirq = steal = 0;
6202 guest = guest_nice = 0;
6203 getboottime(&boottime);
6204+
6205+ if (vx_flags(VXF_VIRT_UPTIME, 0))
6206+ vx_vsi_boottime(&boottime);
537831f9
AM
6207+
6208+ if (virt_cpu)
6209+ cpuset_cpus_allowed(current, cpus_allowed);
1e8b8f9b
AM
6210+
6211 jif = boottime.tv_sec;
6212
6213 for_each_possible_cpu(i) {
537831f9
AM
6214+ if (virt_cpu && !cpumask_test_cpu(i, cpus_allowed))
6215+ continue;
6216+
6217 user += kcpustat_cpu(i).cpustat[CPUTIME_USER];
6218 nice += kcpustat_cpu(i).cpustat[CPUTIME_NICE];
6219 system += kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
6220@@ -131,6 +145,9 @@ static int show_stat(struct seq_file *p,
6221 seq_putc(p, '\n');
6222
6223 for_each_online_cpu(i) {
6224+ if (virt_cpu && !cpumask_test_cpu(i, cpus_allowed))
6225+ continue;
6226+
6227 /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
6228 user = kcpustat_cpu(i).cpustat[CPUTIME_USER];
6229 nice = kcpustat_cpu(i).cpustat[CPUTIME_NICE];
8de2f54c 6230diff -NurpP --minimal linux-4.4.111/fs/proc/uptime.c linux-4.4.111-vs2.3.9.5/fs/proc/uptime.c
f19bd705 6231--- linux-4.4.111/fs/proc/uptime.c 2015-04-12 22:12:50.000000000 +0000
8de2f54c 6232+++ linux-4.4.111-vs2.3.9.5/fs/proc/uptime.c 2018-01-09 16:36:32.000000000 +0000
f6c5ef8b 6233@@ -5,6 +5,7 @@
ec22aa5c
AM
6234 #include <linux/seq_file.h>
6235 #include <linux/time.h>
f6c5ef8b 6236 #include <linux/kernel_stat.h>
ec22aa5c 6237+#include <linux/vserver/cvirt.h>
265de2f7 6238 #include <linux/cputime.h>
ec22aa5c
AM
6239
6240 static int uptime_proc_show(struct seq_file *m, void *v)
c2e5f7c8 6241@@ -24,6 +25,10 @@ static int uptime_proc_show(struct seq_f
f6c5ef8b
AM
6242 nsec = cputime64_to_jiffies64(idletime) * TICK_NSEC;
6243 idle.tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
6244 idle.tv_nsec = rem;
ec22aa5c
AM
6245+
6246+ if (vx_flags(VXF_VIRT_UPTIME, 0))
6247+ vx_vsi_uptime(&uptime, &idle);
6248+
6249 seq_printf(m, "%lu.%02lu %lu.%02lu\n",
6250 (unsigned long) uptime.tv_sec,
6251 (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
8de2f54c 6252diff -NurpP --minimal linux-4.4.111/fs/proc_namespace.c linux-4.4.111-vs2.3.9.5/fs/proc_namespace.c
f19bd705 6253--- linux-4.4.111/fs/proc_namespace.c 2018-01-11 07:57:46.000000000 +0000
8de2f54c 6254+++ linux-4.4.111-vs2.3.9.5/fs/proc_namespace.c 2018-01-09 16:36:32.000000000 +0000
927ca606 6255@@ -46,6 +46,8 @@ static int show_sb_opts(struct seq_file
db55b927
AM
6256 { MS_DIRSYNC, ",dirsync" },
6257 { MS_MANDLOCK, ",mand" },
927ca606 6258 { MS_LAZYTIME, ",lazytime" },
db55b927
AM
6259+ { MS_TAGGED, ",tag" },
6260+ { MS_NOTAGCHECK, ",notagcheck" },
6261 { 0, NULL }
6262 };
6263 const struct proc_fs_info *fs_infop;
927ca606 6264@@ -82,6 +84,38 @@ static inline void mangle(struct seq_fil
db55b927
AM
6265 seq_escape(m, s, " \t\n\\");
6266 }
6267
61b0c03f
JR
6268+#ifdef CONFIG_VSERVER_EXTRA_MNT_CHECK
6269+
db55b927
AM
6270+static int mnt_is_reachable(struct vfsmount *vfsmnt)
6271+{
6272+ struct path root;
6273+ struct dentry *point;
6274+ struct mount *mnt = real_mount(vfsmnt);
6275+ struct mount *root_mnt;
6276+ int ret;
6277+
6278+ if (mnt == mnt->mnt_ns->root)
6279+ return 1;
6280+
98d9a5b1 6281+ rcu_read_lock();
db55b927
AM
6282+ root = current->fs->root;
6283+ root_mnt = real_mount(root.mnt);
6284+ point = root.dentry;
6285+
6286+ while ((mnt != mnt->mnt_parent) && (mnt != root_mnt)) {
6287+ point = mnt->mnt_mountpoint;
6288+ mnt = mnt->mnt_parent;
6289+ }
98d9a5b1 6290+ rcu_read_unlock();
db55b927
AM
6291+
6292+ ret = (mnt == root_mnt) && is_subdir(point, root.dentry);
db55b927
AM
6293+ return ret;
6294+}
61b0c03f
JR
6295+
6296+#else
6297+#define mnt_is_reachable(v) (1)
6298+#endif
db55b927
AM
6299+
6300 static void show_type(struct seq_file *m, struct super_block *sb)
6301 {
6302 mangle(m, sb->s_type->name);
927ca606 6303@@ -99,6 +133,17 @@ static int show_vfsmnt(struct seq_file *
db55b927
AM
6304 struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
6305 struct super_block *sb = mnt_path.dentry->d_sb;
6306
6307+ if (vx_flags(VXF_HIDE_MOUNT, 0))
6308+ return SEQ_SKIP;
6309+ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6310+ return SEQ_SKIP;
6311+
6312+ if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
6313+ mnt == current->fs->root.mnt) {
6314+ seq_puts(m, "/dev/root / ");
6315+ goto type;
6316+ }
6317+
6318 if (sb->s_op->show_devname) {
6319 err = sb->s_op->show_devname(m, mnt_path.dentry);
6320 if (err)
927ca606
AM
6321@@ -112,6 +157,7 @@ static int show_vfsmnt(struct seq_file *
6322 if (err)
6323 goto out;
db55b927
AM
6324 seq_putc(m, ' ');
6325+type:
6326 show_type(m, sb);
6327 seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw");
6328 err = show_sb_opts(m, sb);
927ca606
AM
6329@@ -133,6 +179,11 @@ static int show_mountinfo(struct seq_fil
6330 struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
db55b927
AM
6331 int err = 0;
6332
6333+ if (vx_flags(VXF_HIDE_MOUNT, 0))
6334+ return SEQ_SKIP;
6335+ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6336+ return SEQ_SKIP;
6337+
6338 seq_printf(m, "%i %i %u:%u ", r->mnt_id, r->mnt_parent->mnt_id,
6339 MAJOR(sb->s_dev), MINOR(sb->s_dev));
6340 if (sb->s_op->show_path)
927ca606 6341@@ -193,6 +244,17 @@ static int show_vfsstat(struct seq_file
db55b927
AM
6342 struct super_block *sb = mnt_path.dentry->d_sb;
6343 int err = 0;
6344
6345+ if (vx_flags(VXF_HIDE_MOUNT, 0))
6346+ return SEQ_SKIP;
6347+ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6348+ return SEQ_SKIP;
6349+
6350+ if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
6351+ mnt == current->fs->root.mnt) {
6352+ seq_puts(m, "device /dev/root mounted on / ");
6353+ goto type;
6354+ }
6355+
6356 /* device */
6357 if (sb->s_op->show_devname) {
6358 seq_puts(m, "device ");
927ca606
AM
6359@@ -214,7 +276,7 @@ static int show_vfsstat(struct seq_file
6360 if (err)
6361 goto out;
db55b927
AM
6362 seq_putc(m, ' ');
6363-
6364+type:
6365 /* file system type */
6366 seq_puts(m, "with fstype ");
6367 show_type(m, sb);
8de2f54c 6368diff -NurpP --minimal linux-4.4.111/fs/quota/dquot.c linux-4.4.111-vs2.3.9.5/fs/quota/dquot.c
f19bd705 6369--- linux-4.4.111/fs/quota/dquot.c 2018-01-11 07:57:46.000000000 +0000
8de2f54c 6370+++ linux-4.4.111-vs2.3.9.5/fs/quota/dquot.c 2018-01-09 16:36:32.000000000 +0000
927ca606 6371@@ -1643,6 +1643,9 @@ int __dquot_alloc_space(struct inode *in
76514441 6372 int reserve = flags & DQUOT_SPACE_RESERVE;
927ca606 6373 struct dquot **dquots;
76514441
AM
6374
6375+ if ((ret = dl_alloc_space(inode, number)))
6376+ return ret;
6377+
bb20add7
AM
6378 if (!dquot_active(inode)) {
6379 inode_incr_space(inode, number, reserve);
6380 goto out;
927ca606 6381@@ -1695,6 +1698,9 @@ int dquot_alloc_inode(struct inode *inod
1e8b8f9b 6382 struct dquot_warn warn[MAXQUOTAS];
927ca606 6383 struct dquot * const *dquots;
76514441
AM
6384
6385+ if ((ret = dl_alloc_inode(inode)))
6386+ return ret;
6387+
93de0823 6388 if (!dquot_active(inode))
bb20add7
AM
6389 return 0;
6390 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
927ca606
AM
6391@@ -1797,6 +1803,8 @@ void __dquot_free_space(struct inode *in
6392 struct dquot **dquots;
bb20add7 6393 int reserve = flags & DQUOT_SPACE_RESERVE, index;
76514441
AM
6394
6395+ dl_free_space(inode, number);
6396+
93de0823 6397 if (!dquot_active(inode)) {
bb20add7
AM
6398 inode_decr_space(inode, number, reserve);
6399 return;
927ca606
AM
6400@@ -1841,6 +1849,8 @@ void dquot_free_inode(struct inode *inod
6401 struct dquot * const *dquots;
bb20add7 6402 int index;
76514441
AM
6403
6404+ dl_free_inode(inode);
6405+
93de0823 6406 if (!dquot_active(inode))
bb20add7
AM
6407 return;
6408
8de2f54c 6409diff -NurpP --minimal linux-4.4.111/fs/quota/quota.c linux-4.4.111-vs2.3.9.5/fs/quota/quota.c
f19bd705 6410--- linux-4.4.111/fs/quota/quota.c 2016-07-05 04:12:34.000000000 +0000
8de2f54c 6411+++ linux-4.4.111-vs2.3.9.5/fs/quota/quota.c 2018-01-09 16:36:32.000000000 +0000
78865d5b
AM
6412@@ -8,6 +8,7 @@
6413 #include <linux/fs.h>
6414 #include <linux/namei.h>
6415 #include <linux/slab.h>
d337f35e 6416+#include <linux/vs_context.h>
78865d5b 6417 #include <asm/current.h>
92598135 6418 #include <linux/uaccess.h>
78865d5b 6419 #include <linux/kernel.h>
c2e5f7c8 6420@@ -38,7 +39,7 @@ static int check_quotactl_permission(str
78865d5b
AM
6421 break;
6422 /*FALLTHROUGH*/
6423 default:
d337f35e
JR
6424- if (!capable(CAP_SYS_ADMIN))
6425+ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
6426 return -EPERM;
6427 }
6428
927ca606 6429@@ -702,6 +703,46 @@ static int do_quotactl(struct super_bloc
b00e13aa
AM
6430
6431 #ifdef CONFIG_BLOCK
d337f35e 6432
d337f35e
JR
6433+#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
6434+
6435+#include <linux/vroot.h>
2380c486
JR
6436+#include <linux/major.h>
6437+#include <linux/module.h>
d337f35e 6438+#include <linux/kallsyms.h>
2380c486 6439+#include <linux/vserver/debug.h>
d337f35e
JR
6440+
6441+static vroot_grb_func *vroot_get_real_bdev = NULL;
6442+
763640ca 6443+static DEFINE_SPINLOCK(vroot_grb_lock);
d337f35e
JR
6444+
6445+int register_vroot_grb(vroot_grb_func *func) {
6446+ int ret = -EBUSY;
6447+
6448+ spin_lock(&vroot_grb_lock);
6449+ if (!vroot_get_real_bdev) {
6450+ vroot_get_real_bdev = func;
6451+ ret = 0;
6452+ }
6453+ spin_unlock(&vroot_grb_lock);
6454+ return ret;
6455+}
6456+EXPORT_SYMBOL(register_vroot_grb);
6457+
6458+int unregister_vroot_grb(vroot_grb_func *func) {
6459+ int ret = -EINVAL;
6460+
6461+ spin_lock(&vroot_grb_lock);
6462+ if (vroot_get_real_bdev) {
6463+ vroot_get_real_bdev = NULL;
6464+ ret = 0;
6465+ }
6466+ spin_unlock(&vroot_grb_lock);
6467+ return ret;
6468+}
6469+EXPORT_SYMBOL(unregister_vroot_grb);
6470+
6471+#endif
6472+
db55b927
AM
6473 /* Return 1 if 'cmd' will block on frozen filesystem */
6474 static int quotactl_cmd_write(int cmd)
6475 {
927ca606 6476@@ -737,6 +778,22 @@ static struct super_block *quotactl_bloc
2380c486
JR
6477 putname(tmp);
6478 if (IS_ERR(bdev))
6479 return ERR_CAST(bdev);
6480+#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
6481+ if (bdev && bdev->bd_inode &&
537831f9 6482+ imajor(bdev->bd_inode) == VROOT_MAJOR) {
2380c486
JR
6483+ struct block_device *bdnew = (void *)-EINVAL;
6484+
6485+ if (vroot_get_real_bdev)
6486+ bdnew = vroot_get_real_bdev(bdev);
6487+ else
6488+ vxdprintk(VXD_CBIT(misc, 0),
6489+ "vroot_get_real_bdev not set");
6490+ bdput(bdev);
6491+ if (IS_ERR(bdnew))
6492+ return ERR_PTR(PTR_ERR(bdnew));
6493+ bdev = bdnew;
6494+ }
6495+#endif
db55b927
AM
6496 if (quotactl_cmd_write(cmd))
6497 sb = get_super_thawed(bdev);
6498 else
8de2f54c 6499diff -NurpP --minimal linux-4.4.111/fs/stat.c linux-4.4.111-vs2.3.9.5/fs/stat.c
f19bd705 6500--- linux-4.4.111/fs/stat.c 2018-01-11 07:57:46.000000000 +0000
8de2f54c 6501+++ linux-4.4.111-vs2.3.9.5/fs/stat.c 2018-01-09 16:36:32.000000000 +0000
2380c486 6502@@ -26,6 +26,7 @@ void generic_fillattr(struct inode *inod
d337f35e
JR
6503 stat->nlink = inode->i_nlink;
6504 stat->uid = inode->i_uid;
6505 stat->gid = inode->i_gid;
6506+ stat->tag = inode->i_tag;
6507 stat->rdev = inode->i_rdev;
a168f21d 6508 stat->size = i_size_read(inode);
d337f35e 6509 stat->atime = inode->i_atime;
8de2f54c 6510diff -NurpP --minimal linux-4.4.111/fs/statfs.c linux-4.4.111-vs2.3.9.5/fs/statfs.c
f19bd705 6511--- linux-4.4.111/fs/statfs.c 2015-04-12 22:12:50.000000000 +0000
8de2f54c 6512+++ linux-4.4.111-vs2.3.9.5/fs/statfs.c 2018-01-09 16:36:32.000000000 +0000
93de0823 6513@@ -7,6 +7,8 @@
76514441
AM
6514 #include <linux/statfs.h>
6515 #include <linux/security.h>
6516 #include <linux/uaccess.h>
6517+#include <linux/vs_base.h>
6518+#include <linux/vs_dlimit.h>
db55b927 6519 #include "internal.h"
76514441 6520
93de0823 6521 static int flags_by_mnt(int mnt_flags)
db55b927 6522@@ -60,6 +62,8 @@ static int statfs_by_dentry(struct dentr
93de0823
AM
6523 retval = dentry->d_sb->s_op->statfs(dentry, buf);
6524 if (retval == 0 && buf->f_frsize == 0)
6525 buf->f_frsize = buf->f_bsize;
6526+ if (!vx_check(0, VS_ADMIN|VS_WATCH))
6527+ vx_vsi_statfs(dentry->d_sb, buf);
76514441
AM
6528 return retval;
6529 }
93de0823 6530
8de2f54c 6531diff -NurpP --minimal linux-4.4.111/fs/super.c linux-4.4.111-vs2.3.9.5/fs/super.c
f19bd705 6532--- linux-4.4.111/fs/super.c 2018-01-11 07:57:46.000000000 +0000
8de2f54c 6533+++ linux-4.4.111-vs2.3.9.5/fs/super.c 2018-01-09 16:36:32.000000000 +0000
bb20add7 6534@@ -33,6 +33,8 @@
be261992 6535 #include <linux/cleancache.h>
1e8b8f9b 6536 #include <linux/fsnotify.h>
92598135 6537 #include <linux/lockdep.h>
1e8b8f9b 6538+#include <linux/magic.h>
be261992
AM
6539+#include <linux/vs_context.h>
6540 #include "internal.h"
6541
6542
927ca606
AM
6543@@ -1131,6 +1133,13 @@ mount_fs(struct file_system_type *type,
6544 WARN_ON(!sb->s_bdi);
be261992
AM
6545 sb->s_flags |= MS_BORN;
6546
6547+ error = -EPERM;
6548+ if (!vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT) &&
6549+ !sb->s_bdev &&
6550+ (sb->s_magic != PROC_SUPER_MAGIC) &&
6551+ (sb->s_magic != DEVPTS_SUPER_MAGIC))
6552+ goto out_sb;
6553+
6554 error = security_sb_kern_mount(sb, flags, secdata);
6555 if (error)
6556 goto out_sb;
8de2f54c 6557diff -NurpP --minimal linux-4.4.111/fs/utimes.c linux-4.4.111-vs2.3.9.5/fs/utimes.c
f19bd705 6558--- linux-4.4.111/fs/utimes.c 2018-01-11 07:57:46.000000000 +0000
8de2f54c 6559+++ linux-4.4.111-vs2.3.9.5/fs/utimes.c 2018-01-09 16:36:32.000000000 +0000
2380c486
JR
6560@@ -8,6 +8,8 @@
6561 #include <linux/stat.h>
d337f35e 6562 #include <linux/utime.h>
2380c486 6563 #include <linux/syscalls.h>
d337f35e
JR
6564+#include <linux/mount.h>
6565+#include <linux/vs_cowbl.h>
6566 #include <asm/uaccess.h>
6567 #include <asm/unistd.h>
6568
c2e5f7c8 6569@@ -52,13 +54,19 @@ static int utimes_common(struct path *pa
76514441
AM
6570 {
6571 int error;
6572 struct iattr newattrs;
6573- struct inode *inode = path->dentry->d_inode;
c2e5f7c8 6574 struct inode *delegated_inode = NULL;
76514441 6575+ struct inode *inode;
b00e13aa
AM
6576+
6577+ error = cow_check_and_break(path);
6578+ if (error)
6579+ goto out;
76514441
AM
6580
6581 error = mnt_want_write(path->mnt);
6582 if (error)
6583 goto out;
6584
76514441
AM
6585+ inode = path->dentry->d_inode;
6586+
6587 if (times && times[0].tv_nsec == UTIME_NOW &&
6588 times[1].tv_nsec == UTIME_NOW)
6589 times = NULL;
8de2f54c 6590diff -NurpP --minimal linux-4.4.111/fs/xattr.c linux-4.4.111-vs2.3.9.5/fs/xattr.c
f19bd705 6591--- linux-4.4.111/fs/xattr.c 2018-01-11 07:57:46.000000000 +0000
8de2f54c 6592+++ linux-4.4.111-vs2.3.9.5/fs/xattr.c 2018-01-09 16:36:32.000000000 +0000
537831f9 6593@@ -21,6 +21,7 @@
d337f35e 6594 #include <linux/audit.h>
1e8b8f9b 6595 #include <linux/vmalloc.h>
537831f9 6596 #include <linux/posix_acl_xattr.h>
d337f35e 6597+#include <linux/mount.h>
d337f35e 6598
1e8b8f9b 6599 #include <asm/uaccess.h>
d337f35e 6600
537831f9 6601@@ -52,7 +53,7 @@ xattr_permission(struct inode *inode, co
763640ca 6602 * The trusted.* namespace can only be accessed by privileged users.
e03b8c3c 6603 */
763640ca
JR
6604 if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
6605- if (!capable(CAP_SYS_ADMIN))
a168f21d
AM
6606+ if (!vx_capable(CAP_SYS_ADMIN, VXC_FS_TRUSTED))
6607 return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
6608 return 0;
6609 }
8de2f54c 6610diff -NurpP --minimal linux-4.4.111/include/linux/capability.h linux-4.4.111-vs2.3.9.5/include/linux/capability.h
f19bd705 6611--- linux-4.4.111/include/linux/capability.h 2018-01-11 07:57:47.000000000 +0000
8de2f54c 6612+++ linux-4.4.111-vs2.3.9.5/include/linux/capability.h 2018-01-09 16:36:32.000000000 +0000
927ca606 6613@@ -77,7 +77,8 @@ extern const kernel_cap_t __cap_init_eff
bb20add7
AM
6614 #else /* HAND-CODED capability initializers */
6615
6616 #define CAP_LAST_U32 ((_KERNEL_CAPABILITY_U32S) - 1)
6617-#define CAP_LAST_U32_VALID_MASK (CAP_TO_MASK(CAP_LAST_CAP + 1) -1)
6618+#define CAP_LAST_U32_VALID_MASK ((CAP_TO_MASK(CAP_LAST_CAP + 1) -1) \
6619+ | CAP_TO_MASK(CAP_CONTEXT))
6620
6621 # define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }})
6622 # define CAP_FULL_SET ((kernel_cap_t){{ ~0, CAP_LAST_U32_VALID_MASK }})
8de2f54c 6623diff -NurpP --minimal linux-4.4.111/include/linux/cred.h linux-4.4.111-vs2.3.9.5/include/linux/cred.h
f19bd705 6624--- linux-4.4.111/include/linux/cred.h 2018-01-11 07:57:47.000000000 +0000
8de2f54c 6625+++ linux-4.4.111-vs2.3.9.5/include/linux/cred.h 2018-01-11 08:03:00.000000000 +0000
f19bd705 6626@@ -161,6 +161,7 @@ extern void exit_creds(struct task_struc
1163e6ab
AM
6627 extern int copy_creds(struct task_struct *, unsigned long);
6628 extern const struct cred *get_task_cred(struct task_struct *);
6629 extern struct cred *cred_alloc_blank(void);
6630+extern struct cred *__prepare_creds(const struct cred *);
6631 extern struct cred *prepare_creds(void);
6632 extern struct cred *prepare_exec_creds(void);
6633 extern int commit_creds(struct cred *);
f19bd705 6634@@ -221,6 +222,31 @@ static inline bool cap_ambient_invariant
927ca606 6635 cred->cap_inheritable));
3bac966d 6636 }
3bac966d
AM
6637
6638+static inline void set_cred_subscribers(struct cred *cred, int n)
6639+{
6640+#ifdef CONFIG_DEBUG_CREDENTIALS
6641+ atomic_set(&cred->subscribers, n);
6642+#endif
6643+}
6644+
6645+static inline int read_cred_subscribers(const struct cred *cred)
6646+{
6647+#ifdef CONFIG_DEBUG_CREDENTIALS
6648+ return atomic_read(&cred->subscribers);
6649+#else
6650+ return 0;
6651+#endif
6652+}
6653+
6654+static inline void alter_cred_subscribers(const struct cred *_cred, int n)
6655+{
6656+#ifdef CONFIG_DEBUG_CREDENTIALS
6657+ struct cred *cred = (struct cred *) _cred;
6658+
6659+ atomic_add(n, &cred->subscribers);
6660+#endif
6661+}
6662+
6663 /**
6664 * get_new_cred - Get a reference on a new set of credentials
6665 * @cred: The new credentials to reference
8de2f54c 6666diff -NurpP --minimal linux-4.4.111/include/linux/dcache.h linux-4.4.111-vs2.3.9.5/include/linux/dcache.h
f19bd705 6667--- linux-4.4.111/include/linux/dcache.h 2018-01-11 07:57:47.000000000 +0000
8de2f54c 6668+++ linux-4.4.111-vs2.3.9.5/include/linux/dcache.h 2018-01-09 16:36:32.000000000 +0000
927ca606
AM
6669@@ -10,6 +10,7 @@
6670 #include <linux/cache.h>
6671 #include <linux/rcupdate.h>
6672 #include <linux/lockref.h>
6673+// #include <linux/vs_limit.h>
6674
6675 struct path;
6676 struct vfsmount;
6677@@ -351,8 +352,10 @@ extern char *dentry_path(struct dentry *
6678 */
6679 static inline struct dentry *dget_dlock(struct dentry *dentry)
6680 {
6681- if (dentry)
6682+ if (dentry) {
6683 dentry->d_lockref.count++;
6684+ // vx_dentry_inc(dentry);
6685+ }
6686 return dentry;
6687 }
6688
8de2f54c 6689diff -NurpP --minimal linux-4.4.111/include/linux/devpts_fs.h linux-4.4.111-vs2.3.9.5/include/linux/devpts_fs.h
f19bd705 6690--- linux-4.4.111/include/linux/devpts_fs.h 2018-01-11 07:57:47.000000000 +0000
8de2f54c 6691+++ linux-4.4.111-vs2.3.9.5/include/linux/devpts_fs.h 2018-01-09 16:36:32.000000000 +0000
927ca606 6692@@ -35,5 +35,4 @@ void devpts_pty_kill(struct inode *inode
2380c486
JR
6693
6694 #endif
d337f35e 6695
2380c486 6696-
d337f35e 6697 #endif /* _LINUX_DEVPTS_FS_H */
8de2f54c 6698diff -NurpP --minimal linux-4.4.111/include/linux/fs.h linux-4.4.111-vs2.3.9.5/include/linux/fs.h
f19bd705 6699--- linux-4.4.111/include/linux/fs.h 2018-01-11 07:57:47.000000000 +0000
8de2f54c 6700+++ linux-4.4.111-vs2.3.9.5/include/linux/fs.h 2018-01-09 16:43:56.000000000 +0000
927ca606 6701@@ -227,6 +227,7 @@ typedef void (dax_iodone_t)(struct buffe
2380c486
JR
6702 #define ATTR_OPEN (1 << 15) /* Truncating from open(O_TRUNC) */
6703 #define ATTR_TIMES_SET (1 << 16)
927ca606
AM
6704 #define ATTR_TOUCH (1 << 17)
6705+#define ATTR_TAG (1 << 18)
d337f35e
JR
6706
6707 /*
bb20add7 6708 * Whiteout is represented by a char device. The following constants define the
927ca606 6709@@ -249,6 +250,7 @@ struct iattr {
d337f35e 6710 umode_t ia_mode;
42bc425c
AM
6711 kuid_t ia_uid;
6712 kgid_t ia_gid;
537831f9 6713+ ktag_t ia_tag;
d337f35e
JR
6714 loff_t ia_size;
6715 struct timespec ia_atime;
6716 struct timespec ia_mtime;
927ca606 6717@@ -587,7 +589,9 @@ struct inode {
a168f21d 6718 unsigned short i_opflags;
42bc425c
AM
6719 kuid_t i_uid;
6720 kgid_t i_gid;
2380c486 6721- unsigned int i_flags;
537831f9 6722+ ktag_t i_tag;
2380c486
JR
6723+ unsigned short i_flags;
6724+ unsigned short i_vflags;
a168f21d
AM
6725
6726 #ifdef CONFIG_FS_POSIX_ACL
6727 struct posix_acl *i_acl;
927ca606 6728@@ -616,6 +620,7 @@ struct inode {
f6c5ef8b
AM
6729 unsigned int __i_nlink;
6730 };
d33d7b00
AM
6731 dev_t i_rdev;
6732+ dev_t i_mdev;
42bc425c 6733 loff_t i_size;
a168f21d
AM
6734 struct timespec i_atime;
6735 struct timespec i_mtime;
927ca606 6736@@ -814,6 +819,11 @@ static inline gid_t i_gid_read(const str
537831f9
AM
6737 return from_kgid(&init_user_ns, inode->i_gid);
6738 }
6739
61333608 6740+static inline vtag_t i_tag_read(const struct inode *inode)
537831f9
AM
6741+{
6742+ return from_ktag(&init_user_ns, inode->i_tag);
6743+}
6744+
6745 static inline void i_uid_write(struct inode *inode, uid_t uid)
6746 {
6747 inode->i_uid = make_kuid(&init_user_ns, uid);
927ca606 6748@@ -824,14 +834,19 @@ static inline void i_gid_write(struct in
537831f9
AM
6749 inode->i_gid = make_kgid(&init_user_ns, gid);
6750 }
2380c486 6751
61333608 6752+static inline void i_tag_write(struct inode *inode, vtag_t tag)
537831f9
AM
6753+{
6754+ inode->i_tag = make_ktag(&init_user_ns, tag);
6755+}
6756+
2380c486
JR
6757 static inline unsigned iminor(const struct inode *inode)
6758 {
6759- return MINOR(inode->i_rdev);
6760+ return MINOR(inode->i_mdev);
6761 }
6762
6763 static inline unsigned imajor(const struct inode *inode)
6764 {
6765- return MAJOR(inode->i_rdev);
6766+ return MAJOR(inode->i_mdev);
6767 }
6768
6769 extern struct block_device *I_BDEV(struct inode *inode);
927ca606 6770@@ -888,6 +903,7 @@ struct file {
d337f35e
JR
6771 loff_t f_pos;
6772 struct fown_struct f_owner;
ec22aa5c 6773 const struct cred *f_cred;
61333608 6774+ vxid_t f_xid;
d337f35e
JR
6775 struct file_ra_state f_ra;
6776
2380c486 6777 u64 f_version;
927ca606 6778@@ -1022,6 +1038,7 @@ struct file_lock {
2380c486 6779 struct file *fl_file;
d337f35e
JR
6780 loff_t fl_start;
6781 loff_t fl_end;
61333608 6782+ vxid_t fl_xid;
d337f35e
JR
6783
6784 struct fasync_struct * fl_fasync; /* for lease break notifications */
f6c5ef8b 6785 /* for lease breaks: */
927ca606 6786@@ -1698,6 +1715,7 @@ struct inode_operations {
d4263eb0
JR
6787 ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
6788 ssize_t (*listxattr) (struct dentry *, char *, size_t);
6789 int (*removexattr) (struct dentry *, const char *);
6790+ int (*sync_flags) (struct inode *, int, int);
d33d7b00
AM
6791 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
6792 u64 len);
42bc425c 6793 int (*update_time)(struct inode *, struct timespec *, int);
927ca606 6794@@ -1712,6 +1730,7 @@ ssize_t rw_copy_check_uvector(int type,
537831f9
AM
6795 unsigned long nr_segs, unsigned long fast_segs,
6796 struct iovec *fast_pointer,
6797 struct iovec **ret_pointer);
d337f35e
JR
6798+ssize_t vfs_sendfile(struct file *, struct file *, loff_t *, size_t, loff_t);
6799
927ca606
AM
6800 extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
6801 extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *);
6802@@ -1777,6 +1796,14 @@ struct super_operations {
6803 #else
6804 #define S_DAX 0 /* Make all the DAX code disappear */
6805 #endif
6806+#define S_IXUNLINK 16384 /* Immutable Invert on unlink */
537831f9
AM
6807+
6808+/* Linux-VServer related Inode flags */
6809+
6810+#define V_VALID 1
6811+#define V_XATTR 2
6812+#define V_BARRIER 4 /* Barrier for chroot() */
6813+#define V_COW 8 /* Copy on Write */
6814
6815 /*
6816 * Note that nosuid etc flags are inode-specific: setting some file-system
927ca606 6817@@ -1801,10 +1828,13 @@ struct super_operations {
537831f9
AM
6818 #define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK)
6819 #define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME)
6820 #define IS_I_VERSION(inode) __IS_FLG(inode, MS_I_VERSION)
6821+#define IS_TAGGED(inode) __IS_FLG(inode, MS_TAGGED)
6822
6823 #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
6824 #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
6825 #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
6826+#define IS_IXUNLINK(inode) ((inode)->i_flags & S_IXUNLINK)
6827+#define IS_IXORUNLINK(inode) ((IS_IXUNLINK(inode) ? S_IMMUTABLE : 0) ^ IS_IMMUTABLE(inode))
6828 #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL)
6829
6830 #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
927ca606 6831@@ -1819,6 +1849,16 @@ struct super_operations {
bb20add7
AM
6832 #define IS_WHITEOUT(inode) (S_ISCHR(inode->i_mode) && \
6833 (inode)->i_rdev == WHITEOUT_DEV)
537831f9
AM
6834
6835+#define IS_BARRIER(inode) (S_ISDIR((inode)->i_mode) && ((inode)->i_vflags & V_BARRIER))
6836+
6837+#ifdef CONFIG_VSERVER_COWBL
6838+# define IS_COW(inode) (IS_IXUNLINK(inode) && IS_IMMUTABLE(inode))
6839+# define IS_COW_LINK(inode) (S_ISREG((inode)->i_mode) && ((inode)->i_nlink > 1))
6840+#else
6841+# define IS_COW(inode) (0)
6842+# define IS_COW_LINK(inode) (0)
6843+#endif
6844+
6845 /*
6846 * Inode state bits. Protected by inode->i_lock
6847 *
927ca606 6848@@ -2075,6 +2115,9 @@ extern struct kobject *fs_kobj;
bb20add7 6849 extern int locks_mandatory_locked(struct file *);
537831f9
AM
6850 extern int locks_mandatory_area(int, struct inode *, struct file *, loff_t, size_t);
6851
6852+#define ATTR_FLAG_BARRIER 512 /* Barrier for chroot() */
6853+#define ATTR_FLAG_IXUNLINK 1024 /* Immutable invert on unlink */
6854+
6855 /*
6856 * Candidates for mandatory locking have the setgid bit set
6857 * but no group execute bit - an otherwise meaningless combination.
927ca606 6858@@ -2830,6 +2873,7 @@ extern int dcache_dir_open(struct inode
d337f35e
JR
6859 extern int dcache_dir_close(struct inode *, struct file *);
6860 extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
c2e5f7c8
JR
6861 extern int dcache_readdir(struct file *, struct dir_context *);
6862+extern int dcache_readdir_filter(struct file *, struct dir_context *, int (*)(struct dentry *));
76514441 6863 extern int simple_setattr(struct dentry *, struct iattr *);
d337f35e
JR
6864 extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
6865 extern int simple_statfs(struct dentry *, struct kstatfs *);
8de2f54c 6866diff -NurpP --minimal linux-4.4.111/include/linux/init_task.h linux-4.4.111-vs2.3.9.5/include/linux/init_task.h
f19bd705 6867--- linux-4.4.111/include/linux/init_task.h 2016-07-05 04:15:10.000000000 +0000
8de2f54c 6868+++ linux-4.4.111-vs2.3.9.5/include/linux/init_task.h 2018-01-09 16:36:32.000000000 +0000
927ca606 6869@@ -260,6 +260,10 @@ extern struct task_group root_task_group
b00e13aa 6870 INIT_VTIME(tsk) \
927ca606
AM
6871 INIT_NUMA_BALANCING(tsk) \
6872 INIT_KASAN(tsk) \
d337f35e
JR
6873+ .xid = 0, \
6874+ .vx_info = NULL, \
6875+ .nid = 0, \
6876+ .nx_info = NULL, \
6877 }
6878
6879
8de2f54c 6880diff -NurpP --minimal linux-4.4.111/include/linux/ipc.h linux-4.4.111-vs2.3.9.5/include/linux/ipc.h
f19bd705 6881--- linux-4.4.111/include/linux/ipc.h 2015-04-12 22:12:50.000000000 +0000
8de2f54c 6882+++ linux-4.4.111-vs2.3.9.5/include/linux/ipc.h 2018-01-09 16:36:32.000000000 +0000
537831f9 6883@@ -16,6 +16,7 @@ struct kern_ipc_perm
d337f35e 6884 key_t key;
537831f9
AM
6885 kuid_t uid;
6886 kgid_t gid;
61333608 6887+ vxid_t xid;
537831f9
AM
6888 kuid_t cuid;
6889 kgid_t cgid;
db55b927 6890 umode_t mode;
8de2f54c 6891diff -NurpP --minimal linux-4.4.111/include/linux/memcontrol.h linux-4.4.111-vs2.3.9.5/include/linux/memcontrol.h
f19bd705 6892--- linux-4.4.111/include/linux/memcontrol.h 2018-01-11 07:57:48.000000000 +0000
8de2f54c 6893+++ linux-4.4.111-vs2.3.9.5/include/linux/memcontrol.h 2018-01-09 16:36:32.000000000 +0000
927ca606
AM
6894@@ -113,6 +113,7 @@ struct cg_proto {
6895 struct mem_cgroup *memcg;
6896 };
6897
6898+
6899 #ifdef CONFIG_MEMCG
6900 struct mem_cgroup_stat_cpu {
6901 long count[MEM_CGROUP_STAT_NSTATS];
6902@@ -338,6 +339,11 @@ static inline bool mem_cgroup_is_descend
6903 return cgroup_is_descendant(memcg->css.cgroup, root->css.cgroup);
6904 }
6905
6906+extern u64 mem_cgroup_mem_usage_pages(struct mem_cgroup *memcg);
6907+extern u64 mem_cgroup_mem_limit_pages(struct mem_cgroup *memcg);
6908+extern u64 mem_cgroup_memsw_usage_pages(struct mem_cgroup *memcg);
6909+extern u64 mem_cgroup_memsw_limit_pages(struct mem_cgroup *memcg);
6910+
6911 static inline bool mm_match_cgroup(struct mm_struct *mm,
6912 struct mem_cgroup *memcg)
e3afe727 6913 {
8de2f54c 6914diff -NurpP --minimal linux-4.4.111/include/linux/mount.h linux-4.4.111-vs2.3.9.5/include/linux/mount.h
f19bd705 6915--- linux-4.4.111/include/linux/mount.h 2018-01-11 07:57:48.000000000 +0000
8de2f54c 6916+++ linux-4.4.111-vs2.3.9.5/include/linux/mount.h 2018-01-09 16:36:32.000000000 +0000
927ca606 6917@@ -63,6 +63,9 @@ struct mnt_namespace;
bb20add7 6918 #define MNT_MARKED 0x4000000
927ca606 6919 #define MNT_UMOUNT 0x8000000
d337f35e 6920
2380c486
JR
6921+#define MNT_TAGID 0x10000
6922+#define MNT_NOTAG 0x20000
6923+
d337f35e 6924 struct vfsmount {
db55b927
AM
6925 struct dentry *mnt_root; /* root of the mounted tree */
6926 struct super_block *mnt_sb; /* pointer to superblock */
8de2f54c 6927diff -NurpP --minimal linux-4.4.111/include/linux/net.h linux-4.4.111-vs2.3.9.5/include/linux/net.h
f19bd705 6928--- linux-4.4.111/include/linux/net.h 2018-01-11 07:57:48.000000000 +0000
8de2f54c 6929+++ linux-4.4.111-vs2.3.9.5/include/linux/net.h 2018-01-09 16:42:30.000000000 +0000
927ca606
AM
6930@@ -43,6 +43,7 @@ struct net;
6931 #define SOCK_NOSPACE 2
d337f35e
JR
6932 #define SOCK_PASSCRED 3
6933 #define SOCK_PASSSEC 4
927ca606 6934+#define SOCK_USER_SOCKET 5
d337f35e
JR
6935
6936 #ifndef ARCH_HAS_SOCKET_TYPES
6937 /**
8de2f54c 6938diff -NurpP --minimal linux-4.4.111/include/linux/netdevice.h linux-4.4.111-vs2.3.9.5/include/linux/netdevice.h
f19bd705 6939--- linux-4.4.111/include/linux/netdevice.h 2018-01-11 07:57:48.000000000 +0000
8de2f54c 6940+++ linux-4.4.111-vs2.3.9.5/include/linux/netdevice.h 2018-01-09 16:36:32.000000000 +0000
927ca606 6941@@ -2296,6 +2296,7 @@ static inline int dev_recursion_level(vo
c2e5f7c8
JR
6942
6943 struct net_device *dev_get_by_index(struct net *net, int ifindex);
6944 struct net_device *__dev_get_by_index(struct net *net, int ifindex);
6945+struct net_device *dev_get_by_index_real_rcu(struct net *net, int ifindex);
6946 struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex);
6947 int netdev_get_name(struct net *net, char *name, int ifindex);
6948 int dev_restart(struct net_device *dev);
8de2f54c 6949diff -NurpP --minimal linux-4.4.111/include/linux/nsproxy.h linux-4.4.111-vs2.3.9.5/include/linux/nsproxy.h
f19bd705 6950--- linux-4.4.111/include/linux/nsproxy.h 2015-04-12 22:12:50.000000000 +0000
8de2f54c 6951+++ linux-4.4.111-vs2.3.9.5/include/linux/nsproxy.h 2018-01-09 16:36:32.000000000 +0000
2380c486 6952@@ -3,6 +3,7 @@
d337f35e 6953
2380c486
JR
6954 #include <linux/spinlock.h>
6955 #include <linux/sched.h>
6956+#include <linux/vserver/debug.h>
6957
6958 struct mnt_namespace;
6959 struct uts_namespace;
bb20add7
AM
6960@@ -63,6 +64,7 @@ extern struct nsproxy init_nsproxy;
6961 */
2380c486
JR
6962
6963 int copy_namespaces(unsigned long flags, struct task_struct *tsk);
6964+struct nsproxy *copy_nsproxy(struct nsproxy *orig);
6965 void exit_task_namespaces(struct task_struct *tsk);
6966 void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new);
6967 void free_nsproxy(struct nsproxy *ns);
bb20add7 6968@@ -70,16 +72,26 @@ int unshare_nsproxy_namespaces(unsigned
b00e13aa 6969 struct cred *, struct fs_struct *);
a168f21d 6970 int __init nsproxy_cache_init(void);
2380c486
JR
6971
6972-static inline void put_nsproxy(struct nsproxy *ns)
6973+#define get_nsproxy(n) __get_nsproxy(n, __FILE__, __LINE__)
d337f35e 6974+
2380c486
JR
6975+static inline void __get_nsproxy(struct nsproxy *ns,
6976+ const char *_file, int _line)
6977 {
6978- if (atomic_dec_and_test(&ns->count)) {
6979- free_nsproxy(ns);
6980- }
6981+ vxlprintk(VXD_CBIT(space, 0), "get_nsproxy(%p[%u])",
6982+ ns, atomic_read(&ns->count), _file, _line);
d337f35e 6983+ atomic_inc(&ns->count);
2380c486
JR
6984 }
6985
6986-static inline void get_nsproxy(struct nsproxy *ns)
6987+#define put_nsproxy(n) __put_nsproxy(n, __FILE__, __LINE__)
d337f35e 6988+
2380c486
JR
6989+static inline void __put_nsproxy(struct nsproxy *ns,
6990+ const char *_file, int _line)
6991 {
6992- atomic_inc(&ns->count);
6993+ vxlprintk(VXD_CBIT(space, 0), "put_nsproxy(%p[%u])",
6994+ ns, atomic_read(&ns->count), _file, _line);
6995+ if (atomic_dec_and_test(&ns->count)) {
6996+ free_nsproxy(ns);
6997+ }
6998 }
d337f35e 6999
763640ca 7000 #endif
8de2f54c 7001diff -NurpP --minimal linux-4.4.111/include/linux/pid.h linux-4.4.111-vs2.3.9.5/include/linux/pid.h
f19bd705 7002--- linux-4.4.111/include/linux/pid.h 2018-01-11 07:57:48.000000000 +0000
8de2f54c 7003+++ linux-4.4.111-vs2.3.9.5/include/linux/pid.h 2018-01-09 16:45:21.000000000 +0000
927ca606 7004@@ -10,7 +10,8 @@ enum pid_type
d337f35e 7005 PIDTYPE_SID,
927ca606
AM
7006 PIDTYPE_MAX,
7007 /* only valid to __task_pid_nr_ns() */
7008- __PIDTYPE_TGID
7009+ __PIDTYPE_TGID,
7010+ __PIDTYPE_REALPID
d337f35e
JR
7011 };
7012
7013 /*
927ca606 7014@@ -172,6 +173,7 @@ static inline pid_t pid_nr(struct pid *p
2380c486
JR
7015 }
7016
7017 pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns);
7018+pid_t pid_unmapped_nr_ns(struct pid *pid, struct pid_namespace *ns);
7019 pid_t pid_vnr(struct pid *pid);
7020
7021 #define do_each_pid_task(pid, type, task) \
8de2f54c 7022diff -NurpP --minimal linux-4.4.111/include/linux/quotaops.h linux-4.4.111-vs2.3.9.5/include/linux/quotaops.h
f19bd705 7023--- linux-4.4.111/include/linux/quotaops.h 2016-07-05 04:12:37.000000000 +0000
8de2f54c 7024+++ linux-4.4.111-vs2.3.9.5/include/linux/quotaops.h 2018-01-09 16:36:32.000000000 +0000
e22b5178
AM
7025@@ -8,6 +8,7 @@
7026 #define _LINUX_QUOTAOPS_
7027
7028 #include <linux/fs.h>
7029+#include <linux/vs_dlimit.h>
7030
76514441
AM
7031 #define DQUOT_SPACE_WARN 0x1
7032 #define DQUOT_SPACE_RESERVE 0x2
927ca606 7033@@ -211,11 +212,12 @@ static inline void dquot_drop(struct ino
76514441 7034
927ca606 7035 static inline int dquot_alloc_inode(struct inode *inode)
76514441
AM
7036 {
7037- return 0;
7038+ return dl_alloc_inode(inode);
7039 }
7040
927ca606 7041 static inline void dquot_free_inode(struct inode *inode)
e22b5178 7042 {
76514441
AM
7043+ dl_free_inode(inode);
7044 }
7045
7046 static inline int dquot_transfer(struct inode *inode, struct iattr *iattr)
927ca606 7047@@ -226,6 +228,10 @@ static inline int dquot_transfer(struct
76514441
AM
7048 static inline int __dquot_alloc_space(struct inode *inode, qsize_t number,
7049 int flags)
7050 {
7051+ int ret = 0;
7052+
7053+ if ((ret = dl_alloc_space(inode, number)))
7054+ return ret;
7055 if (!(flags & DQUOT_SPACE_RESERVE))
7056 inode_add_bytes(inode, number);
7057 return 0;
927ca606 7058@@ -236,6 +242,7 @@ static inline void __dquot_free_space(st
76514441
AM
7059 {
7060 if (!(flags & DQUOT_SPACE_RESERVE))
7061 inode_sub_bytes(inode, number);
7062+ dl_free_space(inode, number);
7063 }
7064
7065 static inline int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
8de2f54c 7066diff -NurpP --minimal linux-4.4.111/include/linux/sched.h linux-4.4.111-vs2.3.9.5/include/linux/sched.h
f19bd705 7067--- linux-4.4.111/include/linux/sched.h 2018-01-11 07:57:48.000000000 +0000
8de2f54c 7068+++ linux-4.4.111-vs2.3.9.5/include/linux/sched.h 2018-01-09 16:36:32.000000000 +0000
927ca606 7069@@ -1600,6 +1600,14 @@ struct task_struct {
2380c486 7070 #endif
42bc425c 7071 struct seccomp seccomp;
2380c486
JR
7072
7073+/* vserver context data */
7074+ struct vx_info *vx_info;
7075+ struct nx_info *nx_info;
d337f35e 7076+
61333608
AM
7077+ vxid_t xid;
7078+ vnid_t nid;
7079+ vtag_t tag;
2380c486
JR
7080+
7081 /* Thread group tracking */
7082 u32 parent_exec_id;
7083 u32 self_exec_id;
927ca606 7084@@ -1927,6 +1935,11 @@ struct pid_namespace;
ec22aa5c
AM
7085 pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
7086 struct pid_namespace *ns);
d337f35e 7087
2380c486
JR
7088+#include <linux/vserver/base.h>
7089+#include <linux/vserver/context.h>
7090+#include <linux/vserver/debug.h>
7091+#include <linux/vserver/pid.h>
7092+
7093 static inline pid_t task_pid_nr(struct task_struct *tsk)
7094 {
7095 return tsk->pid;
927ca606 7096@@ -1940,7 +1953,8 @@ static inline pid_t task_pid_nr_ns(struc
d337f35e 7097
2380c486
JR
7098 static inline pid_t task_pid_vnr(struct task_struct *tsk)
7099 {
ec22aa5c
AM
7100- return __task_pid_nr_ns(tsk, PIDTYPE_PID, NULL);
7101+ // return __task_pid_nr_ns(tsk, PIDTYPE_PID, NULL);
7102+ return vx_map_pid(__task_pid_nr_ns(tsk, PIDTYPE_PID, NULL));
2380c486 7103 }
d337f35e 7104
d337f35e 7105
8de2f54c 7106diff -NurpP --minimal linux-4.4.111/include/linux/shmem_fs.h linux-4.4.111-vs2.3.9.5/include/linux/shmem_fs.h
f19bd705 7107--- linux-4.4.111/include/linux/shmem_fs.h 2018-01-11 07:57:48.000000000 +0000
8de2f54c 7108+++ linux-4.4.111-vs2.3.9.5/include/linux/shmem_fs.h 2018-01-09 16:36:32.000000000 +0000
bb20add7 7109@@ -10,6 +10,9 @@
2380c486 7110
a168f21d 7111 /* inode in-kernel data */
2380c486
JR
7112
7113+#define TMPFS_SUPER_MAGIC 0x01021994
7114+
7115+
7116 struct shmem_inode_info {
7117 spinlock_t lock;
bb20add7 7118 unsigned int seals; /* shmem seals */
8de2f54c 7119diff -NurpP --minimal linux-4.4.111/include/linux/stat.h linux-4.4.111-vs2.3.9.5/include/linux/stat.h
f19bd705 7120--- linux-4.4.111/include/linux/stat.h 2015-04-12 22:12:50.000000000 +0000
8de2f54c 7121+++ linux-4.4.111-vs2.3.9.5/include/linux/stat.h 2018-01-09 16:36:32.000000000 +0000
537831f9 7122@@ -25,6 +25,7 @@ struct kstat {
2380c486 7123 unsigned int nlink;
42bc425c
AM
7124 kuid_t uid;
7125 kgid_t gid;
8ce283e1 7126+ ktag_t tag;
2380c486
JR
7127 dev_t rdev;
7128 loff_t size;
7129 struct timespec atime;
8de2f54c 7130diff -NurpP --minimal linux-4.4.111/include/linux/sunrpc/auth.h linux-4.4.111-vs2.3.9.5/include/linux/sunrpc/auth.h
f19bd705 7131--- linux-4.4.111/include/linux/sunrpc/auth.h 2016-07-05 04:12:37.000000000 +0000
8de2f54c 7132+++ linux-4.4.111-vs2.3.9.5/include/linux/sunrpc/auth.h 2018-01-09 16:36:32.000000000 +0000
927ca606 7133@@ -40,6 +40,7 @@ enum {
2380c486 7134 struct auth_cred {
b00e13aa
AM
7135 kuid_t uid;
7136 kgid_t gid;
7137+ ktag_t tag;
2380c486 7138 struct group_info *group_info;
db55b927 7139 const char *principal;
c2e5f7c8 7140 unsigned long ac_flags;
8de2f54c 7141diff -NurpP --minimal linux-4.4.111/include/linux/sunrpc/clnt.h linux-4.4.111-vs2.3.9.5/include/linux/sunrpc/clnt.h
f19bd705 7142--- linux-4.4.111/include/linux/sunrpc/clnt.h 2018-01-11 07:57:48.000000000 +0000
8de2f54c 7143+++ linux-4.4.111-vs2.3.9.5/include/linux/sunrpc/clnt.h 2018-01-09 16:36:32.000000000 +0000
c2e5f7c8 7144@@ -51,7 +51,8 @@ struct rpc_clnt {
2380c486 7145 cl_discrtry : 1,/* disconnect before retry */
c2e5f7c8 7146 cl_noretranstimeo: 1,/* No retransmit timeouts */
2380c486
JR
7147 cl_autobind : 1,/* use getport() */
7148- cl_chatty : 1;/* be verbose */
7149+ cl_chatty : 1,/* be verbose */
7150+ cl_tag : 1;/* context tagging */
d337f35e 7151
2380c486
JR
7152 struct rpc_rtt * cl_rtt; /* RTO estimator data */
7153 const struct rpc_timeout *cl_timeout; /* Timeout strategy */
8de2f54c 7154diff -NurpP --minimal linux-4.4.111/include/linux/types.h linux-4.4.111-vs2.3.9.5/include/linux/types.h
f19bd705 7155--- linux-4.4.111/include/linux/types.h 2016-07-05 04:15:11.000000000 +0000
8de2f54c 7156+++ linux-4.4.111-vs2.3.9.5/include/linux/types.h 2018-01-09 16:36:32.000000000 +0000
537831f9 7157@@ -32,6 +32,9 @@ typedef __kernel_uid32_t uid_t;
2380c486
JR
7158 typedef __kernel_gid32_t gid_t;
7159 typedef __kernel_uid16_t uid16_t;
7160 typedef __kernel_gid16_t gid16_t;
61333608
AM
7161+typedef unsigned int vxid_t;
7162+typedef unsigned int vnid_t;
7163+typedef unsigned int vtag_t;
2380c486
JR
7164
7165 typedef unsigned long uintptr_t;
7166
8de2f54c 7167diff -NurpP --minimal linux-4.4.111/include/linux/uidgid.h linux-4.4.111-vs2.3.9.5/include/linux/uidgid.h
f19bd705 7168--- linux-4.4.111/include/linux/uidgid.h 2015-07-06 20:41:43.000000000 +0000
8de2f54c 7169+++ linux-4.4.111-vs2.3.9.5/include/linux/uidgid.h 2018-01-09 16:36:32.000000000 +0000
bb20add7 7170@@ -21,13 +21,17 @@ typedef struct {
537831f9
AM
7171 uid_t val;
7172 } kuid_t;
7173
7174-
7175 typedef struct {
7176 gid_t val;
7177 } kgid_t;
7178
7179+typedef struct {
61333608 7180+ vtag_t val;
537831f9
AM
7181+} ktag_t;
7182+
7183 #define KUIDT_INIT(value) (kuid_t){ value }
7184 #define KGIDT_INIT(value) (kgid_t){ value }
7185+#define KTAGT_INIT(value) (ktag_t){ value }
7186
927ca606 7187 #ifdef CONFIG_MULTIUSER
537831f9 7188 static inline uid_t __kuid_val(kuid_t uid)
927ca606 7189@@ -51,11 +55,18 @@ static inline gid_t __kgid_val(kgid_t gi
537831f9 7190 }
927ca606 7191 #endif
537831f9 7192
61333608 7193+static inline vtag_t __ktag_val(ktag_t tag)
537831f9
AM
7194+{
7195+ return tag.val;
7196+}
7197+
537831f9
AM
7198 #define GLOBAL_ROOT_UID KUIDT_INIT(0)
7199 #define GLOBAL_ROOT_GID KGIDT_INIT(0)
7200+#define GLOBAL_ROOT_TAG KTAGT_INIT(0)
7201
7202 #define INVALID_UID KUIDT_INIT(-1)
7203 #define INVALID_GID KGIDT_INIT(-1)
7204+#define INVALID_TAG KTAGT_INIT(-1)
7205
7206 static inline bool uid_eq(kuid_t left, kuid_t right)
7207 {
927ca606 7208@@ -67,6 +78,11 @@ static inline bool gid_eq(kgid_t left, k
537831f9
AM
7209 return __kgid_val(left) == __kgid_val(right);
7210 }
7211
7212+static inline bool tag_eq(ktag_t left, ktag_t right)
7213+{
7214+ return __ktag_val(left) == __ktag_val(right);
7215+}
7216+
7217 static inline bool uid_gt(kuid_t left, kuid_t right)
7218 {
7219 return __kuid_val(left) > __kuid_val(right);
927ca606
AM
7220@@ -117,13 +133,21 @@ static inline bool gid_valid(kgid_t gid)
7221 return __kgid_val(gid) != (gid_t) -1;
537831f9
AM
7222 }
7223
7224+static inline bool tag_valid(ktag_t tag)
7225+{
7226+ return !tag_eq(tag, INVALID_TAG);
7227+}
7228+
7229 #ifdef CONFIG_USER_NS
7230
7231 extern kuid_t make_kuid(struct user_namespace *from, uid_t uid);
7232 extern kgid_t make_kgid(struct user_namespace *from, gid_t gid);
c90fe048 7233+extern ktag_t make_ktag(struct user_namespace *from, gid_t gid);
537831f9
AM
7234
7235 extern uid_t from_kuid(struct user_namespace *to, kuid_t uid);
7236 extern gid_t from_kgid(struct user_namespace *to, kgid_t gid);
61333608 7237+extern vtag_t from_ktag(struct user_namespace *to, ktag_t tag);
537831f9
AM
7238+
7239 extern uid_t from_kuid_munged(struct user_namespace *to, kuid_t uid);
7240 extern gid_t from_kgid_munged(struct user_namespace *to, kgid_t gid);
7241
927ca606 7242@@ -149,6 +173,11 @@ static inline kgid_t make_kgid(struct us
537831f9
AM
7243 return KGIDT_INIT(gid);
7244 }
7245
61333608 7246+static inline ktag_t make_ktag(struct user_namespace *from, vtag_t tag)
537831f9
AM
7247+{
7248+ return KTAGT_INIT(tag);
7249+}
7250+
7251 static inline uid_t from_kuid(struct user_namespace *to, kuid_t kuid)
7252 {
7253 return __kuid_val(kuid);
927ca606 7254@@ -159,6 +188,11 @@ static inline gid_t from_kgid(struct use
537831f9
AM
7255 return __kgid_val(kgid);
7256 }
7257
61333608 7258+static inline vtag_t from_ktag(struct user_namespace *to, ktag_t ktag)
537831f9
AM
7259+{
7260+ return __ktag_val(ktag);
7261+}
7262+
7263 static inline uid_t from_kuid_munged(struct user_namespace *to, kuid_t kuid)
7264 {
7265 uid_t uid = from_kuid(to, kuid);
8de2f54c 7266diff -NurpP --minimal linux-4.4.111/include/linux/vroot.h linux-4.4.111-vs2.3.9.5/include/linux/vroot.h
f19bd705 7267--- linux-4.4.111/include/linux/vroot.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 7268+++ linux-4.4.111-vs2.3.9.5/include/linux/vroot.h 2018-01-09 16:36:32.000000000 +0000
2380c486
JR
7269@@ -0,0 +1,51 @@
7270+
7271+/*
7272+ * include/linux/vroot.h
7273+ *
927ca606
AM
7274+ * written by Herbert P?tzl, 9/11/2002
7275+ * ported to 2.6 by Herbert P?tzl, 30/12/2004
2380c486 7276+ *
927ca606 7277+ * Copyright (C) 2002-2007 by Herbert P?tzl.
2380c486
JR
7278+ * Redistribution of this file is permitted under the
7279+ * GNU General Public License.
7280+ */
7281+
7282+#ifndef _LINUX_VROOT_H
7283+#define _LINUX_VROOT_H
7284+
7285+
7286+#ifdef __KERNEL__
7287+
7288+/* Possible states of device */
7289+enum {
7290+ Vr_unbound,
7291+ Vr_bound,
7292+};
7293+
7294+struct vroot_device {
7295+ int vr_number;
7296+ int vr_refcnt;
7297+
7298+ struct semaphore vr_ctl_mutex;
7299+ struct block_device *vr_device;
7300+ int vr_state;
7301+};
7302+
7303+
7304+typedef struct block_device *(vroot_grb_func)(struct block_device *);
7305+
7306+extern int register_vroot_grb(vroot_grb_func *);
7307+extern int unregister_vroot_grb(vroot_grb_func *);
7308+
7309+#endif /* __KERNEL__ */
7310+
7311+#define MAX_VROOT_DEFAULT 8
7312+
7313+/*
7314+ * IOCTL commands --- we will commandeer 0x56 ('V')
7315+ */
7316+
7317+#define VROOT_SET_DEV 0x5600
7318+#define VROOT_CLR_DEV 0x5601
7319+
7320+#endif /* _LINUX_VROOT_H */
8de2f54c 7321diff -NurpP --minimal linux-4.4.111/include/linux/vs_base.h linux-4.4.111-vs2.3.9.5/include/linux/vs_base.h
f19bd705 7322--- linux-4.4.111/include/linux/vs_base.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 7323+++ linux-4.4.111-vs2.3.9.5/include/linux/vs_base.h 2018-01-09 16:36:32.000000000 +0000
2380c486
JR
7324@@ -0,0 +1,10 @@
7325+#ifndef _VS_BASE_H
7326+#define _VS_BASE_H
7327+
7328+#include "vserver/base.h"
7329+#include "vserver/check.h"
7330+#include "vserver/debug.h"
7331+
7332+#else
7333+#warning duplicate inclusion
7334+#endif
8de2f54c 7335diff -NurpP --minimal linux-4.4.111/include/linux/vs_context.h linux-4.4.111-vs2.3.9.5/include/linux/vs_context.h
f19bd705 7336--- linux-4.4.111/include/linux/vs_context.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 7337+++ linux-4.4.111-vs2.3.9.5/include/linux/vs_context.h 2018-01-09 16:36:32.000000000 +0000
4a036bed 7338@@ -0,0 +1,242 @@
2380c486
JR
7339+#ifndef _VS_CONTEXT_H
7340+#define _VS_CONTEXT_H
7341+
7342+#include "vserver/base.h"
7343+#include "vserver/check.h"
7344+#include "vserver/context.h"
7345+#include "vserver/history.h"
7346+#include "vserver/debug.h"
7347+
7348+#include <linux/sched.h>
7349+
7350+
7351+#define get_vx_info(i) __get_vx_info(i, __FILE__, __LINE__, __HERE__)
7352+
7353+static inline struct vx_info *__get_vx_info(struct vx_info *vxi,
7354+ const char *_file, int _line, void *_here)
7355+{
7356+ if (!vxi)
7357+ return NULL;
7358+
7359+ vxlprintk(VXD_CBIT(xid, 2), "get_vx_info(%p[#%d.%d])",
7360+ vxi, vxi ? vxi->vx_id : 0,
7361+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7362+ _file, _line);
7363+ __vxh_get_vx_info(vxi, _here);
7364+
7365+ atomic_inc(&vxi->vx_usecnt);
7366+ return vxi;
7367+}
7368+
7369+
7370+extern void free_vx_info(struct vx_info *);
7371+
7372+#define put_vx_info(i) __put_vx_info(i, __FILE__, __LINE__, __HERE__)
7373+
7374+static inline void __put_vx_info(struct vx_info *vxi,
7375+ const char *_file, int _line, void *_here)
7376+{
7377+ if (!vxi)
7378+ return;
7379+
7380+ vxlprintk(VXD_CBIT(xid, 2), "put_vx_info(%p[#%d.%d])",
7381+ vxi, vxi ? vxi->vx_id : 0,
7382+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7383+ _file, _line);
7384+ __vxh_put_vx_info(vxi, _here);
7385+
7386+ if (atomic_dec_and_test(&vxi->vx_usecnt))
7387+ free_vx_info(vxi);
7388+}
7389+
7390+
7391+#define init_vx_info(p, i) \
7392+ __init_vx_info(p, i, __FILE__, __LINE__, __HERE__)
7393+
7394+static inline void __init_vx_info(struct vx_info **vxp, struct vx_info *vxi,
7395+ const char *_file, int _line, void *_here)
7396+{
7397+ if (vxi) {
7398+ vxlprintk(VXD_CBIT(xid, 3),
7399+ "init_vx_info(%p[#%d.%d])",
7400+ vxi, vxi ? vxi->vx_id : 0,
7401+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7402+ _file, _line);
7403+ __vxh_init_vx_info(vxi, vxp, _here);
7404+
7405+ atomic_inc(&vxi->vx_usecnt);
7406+ }
7407+ *vxp = vxi;
7408+}
7409+
7410+
7411+#define set_vx_info(p, i) \
7412+ __set_vx_info(p, i, __FILE__, __LINE__, __HERE__)
7413+
7414+static inline void __set_vx_info(struct vx_info **vxp, struct vx_info *vxi,
7415+ const char *_file, int _line, void *_here)
7416+{
7417+ struct vx_info *vxo;
7418+
7419+ if (!vxi)
7420+ return;
7421+
7422+ vxlprintk(VXD_CBIT(xid, 3), "set_vx_info(%p[#%d.%d])",
7423+ vxi, vxi ? vxi->vx_id : 0,
7424+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7425+ _file, _line);
7426+ __vxh_set_vx_info(vxi, vxp, _here);
7427+
7428+ atomic_inc(&vxi->vx_usecnt);
7429+ vxo = xchg(vxp, vxi);
7430+ BUG_ON(vxo);
7431+}
7432+
7433+
7434+#define clr_vx_info(p) __clr_vx_info(p, __FILE__, __LINE__, __HERE__)
7435+
7436+static inline void __clr_vx_info(struct vx_info **vxp,
7437+ const char *_file, int _line, void *_here)
7438+{
7439+ struct vx_info *vxo;
7440+
7441+ vxo = xchg(vxp, NULL);
7442+ if (!vxo)
7443+ return;
7444+
7445+ vxlprintk(VXD_CBIT(xid, 3), "clr_vx_info(%p[#%d.%d])",
7446+ vxo, vxo ? vxo->vx_id : 0,
7447+ vxo ? atomic_read(&vxo->vx_usecnt) : 0,
7448+ _file, _line);
7449+ __vxh_clr_vx_info(vxo, vxp, _here);
7450+
7451+ if (atomic_dec_and_test(&vxo->vx_usecnt))
7452+ free_vx_info(vxo);
7453+}
7454+
7455+
7456+#define claim_vx_info(v, p) \
7457+ __claim_vx_info(v, p, __FILE__, __LINE__, __HERE__)
7458+
7459+static inline void __claim_vx_info(struct vx_info *vxi,
7460+ struct task_struct *task,
7461+ const char *_file, int _line, void *_here)
7462+{
7463+ vxlprintk(VXD_CBIT(xid, 3), "claim_vx_info(%p[#%d.%d.%d]) %p",
7464+ vxi, vxi ? vxi->vx_id : 0,
7465+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7466+ vxi ? atomic_read(&vxi->vx_tasks) : 0,
7467+ task, _file, _line);
7468+ __vxh_claim_vx_info(vxi, task, _here);
7469+
7470+ atomic_inc(&vxi->vx_tasks);
7471+}
7472+
7473+
7474+extern void unhash_vx_info(struct vx_info *);
7475+
7476+#define release_vx_info(v, p) \
7477+ __release_vx_info(v, p, __FILE__, __LINE__, __HERE__)
7478+
7479+static inline void __release_vx_info(struct vx_info *vxi,
7480+ struct task_struct *task,
7481+ const char *_file, int _line, void *_here)
7482+{
7483+ vxlprintk(VXD_CBIT(xid, 3), "release_vx_info(%p[#%d.%d.%d]) %p",
7484+ vxi, vxi ? vxi->vx_id : 0,
7485+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7486+ vxi ? atomic_read(&vxi->vx_tasks) : 0,
7487+ task, _file, _line);
7488+ __vxh_release_vx_info(vxi, task, _here);
7489+
7490+ might_sleep();
7491+
7492+ if (atomic_dec_and_test(&vxi->vx_tasks))
7493+ unhash_vx_info(vxi);
7494+}
7495+
7496+
7497+#define task_get_vx_info(p) \
7498+ __task_get_vx_info(p, __FILE__, __LINE__, __HERE__)
7499+
7500+static inline struct vx_info *__task_get_vx_info(struct task_struct *p,
7501+ const char *_file, int _line, void *_here)
7502+{
7503+ struct vx_info *vxi;
7504+
7505+ task_lock(p);
7506+ vxlprintk(VXD_CBIT(xid, 5), "task_get_vx_info(%p)",
7507+ p, _file, _line);
7508+ vxi = __get_vx_info(p->vx_info, _file, _line, _here);
7509+ task_unlock(p);
7510+ return vxi;
7511+}
7512+
7513+
7514+static inline void __wakeup_vx_info(struct vx_info *vxi)
7515+{
7516+ if (waitqueue_active(&vxi->vx_wait))
7517+ wake_up_interruptible(&vxi->vx_wait);
7518+}
7519+
7520+
7521+#define enter_vx_info(v, s) __enter_vx_info(v, s, __FILE__, __LINE__)
7522+
7523+static inline void __enter_vx_info(struct vx_info *vxi,
7524+ struct vx_info_save *vxis, const char *_file, int _line)
7525+{
7526+ vxlprintk(VXD_CBIT(xid, 5), "enter_vx_info(%p[#%d],%p) %p[#%d,%p]",
7527+ vxi, vxi ? vxi->vx_id : 0, vxis, current,
7528+ current->xid, current->vx_info, _file, _line);
7529+ vxis->vxi = xchg(&current->vx_info, vxi);
7530+ vxis->xid = current->xid;
7531+ current->xid = vxi ? vxi->vx_id : 0;
7532+}
7533+
7534+#define leave_vx_info(s) __leave_vx_info(s, __FILE__, __LINE__)
7535+
7536+static inline void __leave_vx_info(struct vx_info_save *vxis,
7537+ const char *_file, int _line)
7538+{
7539+ vxlprintk(VXD_CBIT(xid, 5), "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]",
7540+ vxis, vxis->xid, vxis->vxi, current,
7541+ current->xid, current->vx_info, _file, _line);
7542+ (void)xchg(&current->vx_info, vxis->vxi);
7543+ current->xid = vxis->xid;
7544+}
7545+
7546+
7547+static inline void __enter_vx_admin(struct vx_info_save *vxis)
7548+{
7549+ vxis->vxi = xchg(&current->vx_info, NULL);
61333608 7550+ vxis->xid = xchg(&current->xid, (vxid_t)0);
2380c486
JR
7551+}
7552+
7553+static inline void __leave_vx_admin(struct vx_info_save *vxis)
7554+{
7555+ (void)xchg(&current->xid, vxis->xid);
7556+ (void)xchg(&current->vx_info, vxis->vxi);
7557+}
7558+
4a036bed
AM
7559+#define task_is_init(p) \
7560+ __task_is_init(p, __FILE__, __LINE__, __HERE__)
7561+
7562+static inline int __task_is_init(struct task_struct *p,
7563+ const char *_file, int _line, void *_here)
7564+{
7565+ int is_init = is_global_init(p);
7566+
7567+ task_lock(p);
7568+ if (p->vx_info)
7569+ is_init = p->vx_info->vx_initpid == p->pid;
7570+ task_unlock(p);
7571+ return is_init;
7572+}
7573+
2380c486
JR
7574+extern void exit_vx_info(struct task_struct *, int);
7575+extern void exit_vx_info_early(struct task_struct *, int);
7576+
7577+
7578+#else
7579+#warning duplicate inclusion
7580+#endif
8de2f54c 7581diff -NurpP --minimal linux-4.4.111/include/linux/vs_cowbl.h linux-4.4.111-vs2.3.9.5/include/linux/vs_cowbl.h
f19bd705 7582--- linux-4.4.111/include/linux/vs_cowbl.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 7583+++ linux-4.4.111-vs2.3.9.5/include/linux/vs_cowbl.h 2018-01-09 16:36:32.000000000 +0000
78865d5b 7584@@ -0,0 +1,48 @@
2380c486
JR
7585+#ifndef _VS_COWBL_H
7586+#define _VS_COWBL_H
7587+
7588+#include <linux/fs.h>
7589+#include <linux/dcache.h>
7590+#include <linux/namei.h>
78865d5b 7591+#include <linux/slab.h>
2380c486
JR
7592+
7593+extern struct dentry *cow_break_link(const char *pathname);
7594+
7595+static inline int cow_check_and_break(struct path *path)
7596+{
7597+ struct inode *inode = path->dentry->d_inode;
7598+ int error = 0;
7599+
7600+ /* do we need this check? */
7601+ if (IS_RDONLY(inode))
7602+ return -EROFS;
7603+
7604+ if (IS_COW(inode)) {
7605+ if (IS_COW_LINK(inode)) {
7606+ struct dentry *new_dentry, *old_dentry = path->dentry;
7607+ char *pp, *buf;
7608+
7609+ buf = kmalloc(PATH_MAX, GFP_KERNEL);
7610+ if (!buf) {
7611+ return -ENOMEM;
7612+ }
7613+ pp = d_path(path, buf, PATH_MAX);
7614+ new_dentry = cow_break_link(pp);
7615+ kfree(buf);
7616+ if (!IS_ERR(new_dentry)) {
7617+ path->dentry = new_dentry;
7618+ dput(old_dentry);
7619+ } else
7620+ error = PTR_ERR(new_dentry);
7621+ } else {
7622+ inode->i_flags &= ~(S_IXUNLINK | S_IMMUTABLE);
7623+ inode->i_ctime = CURRENT_TIME;
7624+ mark_inode_dirty(inode);
7625+ }
7626+ }
7627+ return error;
7628+}
7629+
7630+#else
7631+#warning duplicate inclusion
7632+#endif
8de2f54c 7633diff -NurpP --minimal linux-4.4.111/include/linux/vs_cvirt.h linux-4.4.111-vs2.3.9.5/include/linux/vs_cvirt.h
f19bd705 7634--- linux-4.4.111/include/linux/vs_cvirt.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 7635+++ linux-4.4.111-vs2.3.9.5/include/linux/vs_cvirt.h 2018-01-09 16:36:32.000000000 +0000
2380c486
JR
7636@@ -0,0 +1,50 @@
7637+#ifndef _VS_CVIRT_H
7638+#define _VS_CVIRT_H
7639+
7640+#include "vserver/cvirt.h"
7641+#include "vserver/context.h"
7642+#include "vserver/base.h"
7643+#include "vserver/check.h"
7644+#include "vserver/debug.h"
7645+
7646+
7647+static inline void vx_activate_task(struct task_struct *p)
7648+{
7649+ struct vx_info *vxi;
7650+
7651+ if ((vxi = p->vx_info)) {
7652+ vx_update_load(vxi);
7653+ atomic_inc(&vxi->cvirt.nr_running);
7654+ }
7655+}
7656+
7657+static inline void vx_deactivate_task(struct task_struct *p)
7658+{
7659+ struct vx_info *vxi;
7660+
7661+ if ((vxi = p->vx_info)) {
7662+ vx_update_load(vxi);
7663+ atomic_dec(&vxi->cvirt.nr_running);
7664+ }
7665+}
7666+
7667+static inline void vx_uninterruptible_inc(struct task_struct *p)
7668+{
7669+ struct vx_info *vxi;
7670+
7671+ if ((vxi = p->vx_info))
7672+ atomic_inc(&vxi->cvirt.nr_uninterruptible);
7673+}
7674+
7675+static inline void vx_uninterruptible_dec(struct task_struct *p)
7676+{
7677+ struct vx_info *vxi;
7678+
7679+ if ((vxi = p->vx_info))
7680+ atomic_dec(&vxi->cvirt.nr_uninterruptible);
7681+}
7682+
7683+
7684+#else
7685+#warning duplicate inclusion
7686+#endif
8de2f54c 7687diff -NurpP --minimal linux-4.4.111/include/linux/vs_device.h linux-4.4.111-vs2.3.9.5/include/linux/vs_device.h
f19bd705 7688--- linux-4.4.111/include/linux/vs_device.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 7689+++ linux-4.4.111-vs2.3.9.5/include/linux/vs_device.h 2018-01-09 16:36:32.000000000 +0000
2380c486
JR
7690@@ -0,0 +1,45 @@
7691+#ifndef _VS_DEVICE_H
7692+#define _VS_DEVICE_H
7693+
7694+#include "vserver/base.h"
7695+#include "vserver/device.h"
7696+#include "vserver/debug.h"
7697+
7698+
7699+#ifdef CONFIG_VSERVER_DEVICE
7700+
7701+int vs_map_device(struct vx_info *, dev_t, dev_t *, umode_t);
7702+
7703+#define vs_device_perm(v, d, m, p) \
7704+ ((vs_map_device(current_vx_info(), d, NULL, m) & (p)) == (p))
7705+
7706+#else
7707+
7708+static inline
7709+int vs_map_device(struct vx_info *vxi,
7710+ dev_t device, dev_t *target, umode_t mode)
7711+{
7712+ if (target)
7713+ *target = device;
7714+ return ~0;
7715+}
7716+
7717+#define vs_device_perm(v, d, m, p) ((p) == (p))
7718+
7719+#endif
7720+
7721+
7722+#define vs_map_chrdev(d, t, p) \
7723+ ((vs_map_device(current_vx_info(), d, t, S_IFCHR) & (p)) == (p))
7724+#define vs_map_blkdev(d, t, p) \
7725+ ((vs_map_device(current_vx_info(), d, t, S_IFBLK) & (p)) == (p))
7726+
7727+#define vs_chrdev_perm(d, p) \
7728+ vs_device_perm(current_vx_info(), d, S_IFCHR, p)
7729+#define vs_blkdev_perm(d, p) \
7730+ vs_device_perm(current_vx_info(), d, S_IFBLK, p)
7731+
7732+
7733+#else
7734+#warning duplicate inclusion
7735+#endif
8de2f54c 7736diff -NurpP --minimal linux-4.4.111/include/linux/vs_dlimit.h linux-4.4.111-vs2.3.9.5/include/linux/vs_dlimit.h
f19bd705 7737--- linux-4.4.111/include/linux/vs_dlimit.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 7738+++ linux-4.4.111-vs2.3.9.5/include/linux/vs_dlimit.h 2018-01-09 16:36:32.000000000 +0000
2c8c5bc5 7739@@ -0,0 +1,215 @@
2380c486
JR
7740+#ifndef _VS_DLIMIT_H
7741+#define _VS_DLIMIT_H
7742+
7743+#include <linux/fs.h>
7744+
7745+#include "vserver/dlimit.h"
7746+#include "vserver/base.h"
7747+#include "vserver/debug.h"
7748+
7749+
7750+#define get_dl_info(i) __get_dl_info(i, __FILE__, __LINE__)
7751+
7752+static inline struct dl_info *__get_dl_info(struct dl_info *dli,
7753+ const char *_file, int _line)
7754+{
7755+ if (!dli)
7756+ return NULL;
7757+ vxlprintk(VXD_CBIT(dlim, 4), "get_dl_info(%p[#%d.%d])",
7758+ dli, dli ? dli->dl_tag : 0,
7759+ dli ? atomic_read(&dli->dl_usecnt) : 0,
7760+ _file, _line);
7761+ atomic_inc(&dli->dl_usecnt);
7762+ return dli;
7763+}
7764+
7765+
7766+#define free_dl_info(i) \
7767+ call_rcu(&(i)->dl_rcu, rcu_free_dl_info)
7768+
7769+#define put_dl_info(i) __put_dl_info(i, __FILE__, __LINE__)
7770+
7771+static inline void __put_dl_info(struct dl_info *dli,
7772+ const char *_file, int _line)
7773+{
7774+ if (!dli)
7775+ return;
7776+ vxlprintk(VXD_CBIT(dlim, 4), "put_dl_info(%p[#%d.%d])",
7777+ dli, dli ? dli->dl_tag : 0,
7778+ dli ? atomic_read(&dli->dl_usecnt) : 0,
7779+ _file, _line);
7780+ if (atomic_dec_and_test(&dli->dl_usecnt))
7781+ free_dl_info(dli);
7782+}
7783+
7784+
7785+#define __dlimit_char(d) ((d) ? '*' : ' ')
7786+
7787+static inline int __dl_alloc_space(struct super_block *sb,
61333608 7788+ vtag_t tag, dlsize_t nr, const char *file, int line)
2380c486
JR
7789+{
7790+ struct dl_info *dli = NULL;
7791+ int ret = 0;
7792+
7793+ if (nr == 0)
7794+ goto out;
7795+ dli = locate_dl_info(sb, tag);
7796+ if (!dli)
7797+ goto out;
7798+
7799+ spin_lock(&dli->dl_lock);
7800+ ret = (dli->dl_space_used + nr > dli->dl_space_total);
7801+ if (!ret)
7802+ dli->dl_space_used += nr;
7803+ spin_unlock(&dli->dl_lock);
7804+ put_dl_info(dli);
7805+out:
7806+ vxlprintk(VXD_CBIT(dlim, 1),
7807+ "ALLOC (%p,#%d)%c %lld bytes (%d)",
7808+ sb, tag, __dlimit_char(dli), (long long)nr,
7809+ ret, file, line);
76514441 7810+ return ret ? -ENOSPC : 0;
2380c486
JR
7811+}
7812+
7813+static inline void __dl_free_space(struct super_block *sb,
61333608 7814+ vtag_t tag, dlsize_t nr, const char *_file, int _line)
2380c486
JR
7815+{
7816+ struct dl_info *dli = NULL;
7817+
7818+ if (nr == 0)
7819+ goto out;
7820+ dli = locate_dl_info(sb, tag);
7821+ if (!dli)
7822+ goto out;
7823+
7824+ spin_lock(&dli->dl_lock);
7825+ if (dli->dl_space_used > nr)
7826+ dli->dl_space_used -= nr;
7827+ else
7828+ dli->dl_space_used = 0;
7829+ spin_unlock(&dli->dl_lock);
7830+ put_dl_info(dli);
7831+out:
7832+ vxlprintk(VXD_CBIT(dlim, 1),
7833+ "FREE (%p,#%d)%c %lld bytes",
7834+ sb, tag, __dlimit_char(dli), (long long)nr,
7835+ _file, _line);
7836+}
7837+
7838+static inline int __dl_alloc_inode(struct super_block *sb,
61333608 7839+ vtag_t tag, const char *_file, int _line)
2380c486
JR
7840+{
7841+ struct dl_info *dli;
7842+ int ret = 0;
d337f35e 7843+
2380c486
JR
7844+ dli = locate_dl_info(sb, tag);
7845+ if (!dli)
7846+ goto out;
d337f35e 7847+
2380c486 7848+ spin_lock(&dli->dl_lock);
2c8c5bc5
AM
7849+ dli->dl_inodes_used++;
7850+ ret = (dli->dl_inodes_used > dli->dl_inodes_total);
2380c486
JR
7851+ spin_unlock(&dli->dl_lock);
7852+ put_dl_info(dli);
7853+out:
7854+ vxlprintk(VXD_CBIT(dlim, 0),
7855+ "ALLOC (%p,#%d)%c inode (%d)",
7856+ sb, tag, __dlimit_char(dli), ret, _file, _line);
76514441 7857+ return ret ? -ENOSPC : 0;
2380c486 7858+}
d337f35e 7859+
2380c486 7860+static inline void __dl_free_inode(struct super_block *sb,
61333608 7861+ vtag_t tag, const char *_file, int _line)
d337f35e 7862+{
2380c486
JR
7863+ struct dl_info *dli;
7864+
7865+ dli = locate_dl_info(sb, tag);
7866+ if (!dli)
7867+ goto out;
7868+
7869+ spin_lock(&dli->dl_lock);
7870+ if (dli->dl_inodes_used > 1)
7871+ dli->dl_inodes_used--;
7872+ else
7873+ dli->dl_inodes_used = 0;
7874+ spin_unlock(&dli->dl_lock);
7875+ put_dl_info(dli);
7876+out:
7877+ vxlprintk(VXD_CBIT(dlim, 0),
7878+ "FREE (%p,#%d)%c inode",
7879+ sb, tag, __dlimit_char(dli), _file, _line);
d337f35e
JR
7880+}
7881+
61333608 7882+static inline void __dl_adjust_block(struct super_block *sb, vtag_t tag,
2380c486
JR
7883+ unsigned long long *free_blocks, unsigned long long *root_blocks,
7884+ const char *_file, int _line)
d337f35e 7885+{
2380c486
JR
7886+ struct dl_info *dli;
7887+ uint64_t broot, bfree;
7888+
7889+ dli = locate_dl_info(sb, tag);
7890+ if (!dli)
7891+ return;
7892+
7893+ spin_lock(&dli->dl_lock);
7894+ broot = (dli->dl_space_total -
7895+ (dli->dl_space_total >> 10) * dli->dl_nrlmult)
7896+ >> sb->s_blocksize_bits;
7897+ bfree = (dli->dl_space_total - dli->dl_space_used)
7898+ >> sb->s_blocksize_bits;
7899+ spin_unlock(&dli->dl_lock);
7900+
7901+ vxlprintk(VXD_CBIT(dlim, 2),
7902+ "ADJUST: %lld,%lld on %lld,%lld [mult=%d]",
7903+ (long long)bfree, (long long)broot,
7904+ *free_blocks, *root_blocks, dli->dl_nrlmult,
7905+ _file, _line);
7906+ if (free_blocks) {
7907+ if (*free_blocks > bfree)
7908+ *free_blocks = bfree;
7909+ }
7910+ if (root_blocks) {
7911+ if (*root_blocks > broot)
7912+ *root_blocks = broot;
7913+ }
7914+ put_dl_info(dli);
d337f35e
JR
7915+}
7916+
e22b5178 7917+#define dl_prealloc_space(in, bytes) \
537831f9 7918+ __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 7919+ __FILE__, __LINE__ )
d337f35e 7920+
e22b5178 7921+#define dl_alloc_space(in, bytes) \
537831f9 7922+ __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 7923+ __FILE__, __LINE__ )
d337f35e 7924+
e22b5178 7925+#define dl_reserve_space(in, bytes) \
537831f9 7926+ __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 7927+ __FILE__, __LINE__ )
d337f35e 7928+
e22b5178
AM
7929+#define dl_claim_space(in, bytes) (0)
7930+
7931+#define dl_release_space(in, bytes) \
537831f9 7932+ __dl_free_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 7933+ __FILE__, __LINE__ )
d337f35e 7934+
e22b5178 7935+#define dl_free_space(in, bytes) \
537831f9 7936+ __dl_free_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
e22b5178
AM
7937+ __FILE__, __LINE__ )
7938+
7939+
d337f35e 7940+
e22b5178 7941+#define dl_alloc_inode(in) \
537831f9 7942+ __dl_alloc_inode((in)->i_sb, i_tag_read(in), __FILE__, __LINE__ )
d337f35e 7943+
e22b5178 7944+#define dl_free_inode(in) \
537831f9 7945+ __dl_free_inode((in)->i_sb, i_tag_read(in), __FILE__, __LINE__ )
d337f35e 7946+
d337f35e 7947+
e22b5178 7948+#define dl_adjust_block(sb, tag, fb, rb) \
2380c486 7949+ __dl_adjust_block(sb, tag, fb, rb, __FILE__, __LINE__ )
d337f35e 7950+
d337f35e 7951+
2380c486
JR
7952+#else
7953+#warning duplicate inclusion
7954+#endif
8de2f54c 7955diff -NurpP --minimal linux-4.4.111/include/linux/vs_inet.h linux-4.4.111-vs2.3.9.5/include/linux/vs_inet.h
f19bd705 7956--- linux-4.4.111/include/linux/vs_inet.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 7957+++ linux-4.4.111-vs2.3.9.5/include/linux/vs_inet.h 2018-01-09 16:36:32.000000000 +0000
5cb1760b 7958@@ -0,0 +1,364 @@
d33d7b00
AM
7959+#ifndef _VS_INET_H
7960+#define _VS_INET_H
d337f35e 7961+
d33d7b00
AM
7962+#include "vserver/base.h"
7963+#include "vserver/network.h"
7964+#include "vserver/debug.h"
d337f35e 7965+
d33d7b00 7966+#define IPI_LOOPBACK htonl(INADDR_LOOPBACK)
d337f35e 7967+
d33d7b00
AM
7968+#define NXAV4(a) NIPQUAD((a)->ip[0]), NIPQUAD((a)->ip[1]), \
7969+ NIPQUAD((a)->mask), (a)->type
7970+#define NXAV4_FMT "[" NIPQUAD_FMT "-" NIPQUAD_FMT "/" NIPQUAD_FMT ":%04x]"
d337f35e 7971+
d33d7b00
AM
7972+#define NIPQUAD(addr) \
7973+ ((unsigned char *)&addr)[0], \
7974+ ((unsigned char *)&addr)[1], \
7975+ ((unsigned char *)&addr)[2], \
7976+ ((unsigned char *)&addr)[3]
d337f35e 7977+
d33d7b00 7978+#define NIPQUAD_FMT "%u.%u.%u.%u"
d337f35e 7979+
d337f35e 7980+
d33d7b00
AM
7981+static inline
7982+int v4_addr_match(struct nx_addr_v4 *nxa, __be32 addr, uint16_t tmask)
7983+{
7984+ __be32 ip = nxa->ip[0].s_addr;
7985+ __be32 mask = nxa->mask.s_addr;
7986+ __be32 bcast = ip | ~mask;
7987+ int ret = 0;
d337f35e 7988+
d33d7b00
AM
7989+ switch (nxa->type & tmask) {
7990+ case NXA_TYPE_MASK:
7991+ ret = (ip == (addr & mask));
7992+ break;
7993+ case NXA_TYPE_ADDR:
7994+ ret = 3;
7995+ if (addr == ip)
7996+ break;
7997+ /* fall through to broadcast */
7998+ case NXA_MOD_BCAST:
7999+ ret = ((tmask & NXA_MOD_BCAST) && (addr == bcast));
8000+ break;
8001+ case NXA_TYPE_RANGE:
8002+ ret = ((nxa->ip[0].s_addr <= addr) &&
8003+ (nxa->ip[1].s_addr > addr));
8004+ break;
8005+ case NXA_TYPE_ANY:
8006+ ret = 2;
8007+ break;
8008+ }
d337f35e 8009+
d33d7b00
AM
8010+ vxdprintk(VXD_CBIT(net, 0),
8011+ "v4_addr_match(%p" NXAV4_FMT "," NIPQUAD_FMT ",%04x) = %d",
8012+ nxa, NXAV4(nxa), NIPQUAD(addr), tmask, ret);
8013+ return ret;
8014+}
d337f35e 8015+
d33d7b00
AM
8016+static inline
8017+int v4_addr_in_nx_info(struct nx_info *nxi, __be32 addr, uint16_t tmask)
8018+{
8019+ struct nx_addr_v4 *nxa;
7a9e40b8 8020+ unsigned long irqflags;
d33d7b00 8021+ int ret = 1;
d337f35e 8022+
d33d7b00
AM
8023+ if (!nxi)
8024+ goto out;
d337f35e 8025+
d33d7b00
AM
8026+ ret = 2;
8027+ /* allow 127.0.0.1 when remapping lback */
8028+ if ((tmask & NXA_LOOPBACK) &&
8029+ (addr == IPI_LOOPBACK) &&
8030+ nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
8031+ goto out;
8032+ ret = 3;
8033+ /* check for lback address */
8034+ if ((tmask & NXA_MOD_LBACK) &&
8035+ (nxi->v4_lback.s_addr == addr))
8036+ goto out;
8037+ ret = 4;
8038+ /* check for broadcast address */
8039+ if ((tmask & NXA_MOD_BCAST) &&
8040+ (nxi->v4_bcast.s_addr == addr))
8041+ goto out;
8042+ ret = 5;
4bf69007 8043+
d33d7b00 8044+ /* check for v4 addresses */
7a9e40b8 8045+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
d33d7b00
AM
8046+ for (nxa = &nxi->v4; nxa; nxa = nxa->next)
8047+ if (v4_addr_match(nxa, addr, tmask))
4bf69007 8048+ goto out_unlock;
d33d7b00 8049+ ret = 0;
4bf69007 8050+out_unlock:
7a9e40b8 8051+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
d33d7b00
AM
8052+out:
8053+ vxdprintk(VXD_CBIT(net, 0),
8054+ "v4_addr_in_nx_info(%p[#%u]," NIPQUAD_FMT ",%04x) = %d",
8055+ nxi, nxi ? nxi->nx_id : 0, NIPQUAD(addr), tmask, ret);
8056+ return ret;
8057+}
d337f35e 8058+
d33d7b00
AM
8059+static inline
8060+int v4_nx_addr_match(struct nx_addr_v4 *nxa, struct nx_addr_v4 *addr, uint16_t mask)
8061+{
8062+ /* FIXME: needs full range checks */
8063+ return v4_addr_match(nxa, addr->ip[0].s_addr, mask);
8064+}
d337f35e 8065+
d33d7b00
AM
8066+static inline
8067+int v4_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v4 *nxa, uint16_t mask)
8068+{
8069+ struct nx_addr_v4 *ptr;
7a9e40b8 8070+ unsigned long irqflags;
4bf69007 8071+ int ret = 1;
d337f35e 8072+
7a9e40b8 8073+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
d33d7b00
AM
8074+ for (ptr = &nxi->v4; ptr; ptr = ptr->next)
8075+ if (v4_nx_addr_match(ptr, nxa, mask))
4bf69007
AM
8076+ goto out_unlock;
8077+ ret = 0;
8078+out_unlock:
7a9e40b8 8079+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007 8080+ return ret;
d33d7b00 8081+}
d337f35e 8082+
d33d7b00 8083+#include <net/inet_sock.h>
d337f35e 8084+
d33d7b00
AM
8085+/*
8086+ * Check if a given address matches for a socket
8087+ *
8088+ * nxi: the socket's nx_info if any
8089+ * addr: to be verified address
8090+ */
8091+static inline
8092+int v4_sock_addr_match (
8093+ struct nx_info *nxi,
8094+ struct inet_sock *inet,
8095+ __be32 addr)
8096+{
8097+ __be32 saddr = inet->inet_rcv_saddr;
8098+ __be32 bcast = nxi ? nxi->v4_bcast.s_addr : INADDR_BROADCAST;
d337f35e 8099+
d33d7b00
AM
8100+ if (addr && (saddr == addr || bcast == addr))
8101+ return 1;
8102+ if (!saddr)
8103+ return v4_addr_in_nx_info(nxi, addr, NXA_MASK_BIND);
8104+ return 0;
8105+}
d337f35e 8106+
d337f35e 8107+
d33d7b00 8108+/* inet related checks and helpers */
d337f35e
JR
8109+
8110+
d33d7b00
AM
8111+struct in_ifaddr;
8112+struct net_device;
8113+struct sock;
d337f35e 8114+
d33d7b00 8115+#ifdef CONFIG_INET
d337f35e 8116+
d33d7b00
AM
8117+#include <linux/netdevice.h>
8118+#include <linux/inetdevice.h>
8119+#include <net/inet_sock.h>
8120+#include <net/inet_timewait_sock.h>
d337f35e 8121+
d337f35e 8122+
d33d7b00
AM
8123+int dev_in_nx_info(struct net_device *, struct nx_info *);
8124+int v4_dev_in_nx_info(struct net_device *, struct nx_info *);
8125+int nx_v4_addr_conflict(struct nx_info *, struct nx_info *);
d337f35e 8126+
d337f35e 8127+
d33d7b00
AM
8128+/*
8129+ * check if address is covered by socket
8130+ *
8131+ * sk: the socket to check against
8132+ * addr: the address in question (must be != 0)
8133+ */
d337f35e 8134+
d33d7b00
AM
8135+static inline
8136+int __v4_addr_match_socket(const struct sock *sk, struct nx_addr_v4 *nxa)
8137+{
8138+ struct nx_info *nxi = sk->sk_nx_info;
c2e5f7c8 8139+ __be32 saddr = sk->sk_rcv_saddr;
d337f35e 8140+
d33d7b00
AM
8141+ vxdprintk(VXD_CBIT(net, 5),
8142+ "__v4_addr_in_socket(%p," NXAV4_FMT ") %p:" NIPQUAD_FMT " %p;%lx",
8143+ sk, NXAV4(nxa), nxi, NIPQUAD(saddr), sk->sk_socket,
8144+ (sk->sk_socket?sk->sk_socket->flags:0));
d337f35e 8145+
d33d7b00
AM
8146+ if (saddr) { /* direct address match */
8147+ return v4_addr_match(nxa, saddr, -1);
8148+ } else if (nxi) { /* match against nx_info */
8149+ return v4_nx_addr_in_nx_info(nxi, nxa, -1);
8150+ } else { /* unrestricted any socket */
8151+ return 1;
8152+ }
8153+}
d337f35e
JR
8154+
8155+
d337f35e 8156+
d33d7b00
AM
8157+static inline
8158+int nx_dev_visible(struct nx_info *nxi, struct net_device *dev)
8159+{
8160+ vxdprintk(VXD_CBIT(net, 1),
8161+ "nx_dev_visible(%p[#%u],%p " VS_Q("%s") ") %d",
8162+ nxi, nxi ? nxi->nx_id : 0, dev, dev->name,
8163+ nxi ? dev_in_nx_info(dev, nxi) : 0);
d337f35e 8164+
d33d7b00
AM
8165+ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
8166+ return 1;
8167+ if (dev_in_nx_info(dev, nxi))
8168+ return 1;
8169+ return 0;
8170+}
d337f35e
JR
8171+
8172+
d33d7b00
AM
8173+static inline
8174+int v4_ifa_in_nx_info(struct in_ifaddr *ifa, struct nx_info *nxi)
8175+{
8176+ if (!nxi)
8177+ return 1;
8178+ if (!ifa)
8179+ return 0;
8180+ return v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW);
8181+}
d337f35e 8182+
d33d7b00
AM
8183+static inline
8184+int nx_v4_ifa_visible(struct nx_info *nxi, struct in_ifaddr *ifa)
8185+{
8186+ vxdprintk(VXD_CBIT(net, 1), "nx_v4_ifa_visible(%p[#%u],%p) %d",
8187+ nxi, nxi ? nxi->nx_id : 0, ifa,
8188+ nxi ? v4_ifa_in_nx_info(ifa, nxi) : 0);
d337f35e 8189+
d33d7b00
AM
8190+ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
8191+ return 1;
8192+ if (v4_ifa_in_nx_info(ifa, nxi))
8193+ return 1;
8194+ return 0;
8195+}
d337f35e 8196+
d337f35e 8197+
d33d7b00
AM
8198+struct nx_v4_sock_addr {
8199+ __be32 saddr; /* Address used for validation */
8200+ __be32 baddr; /* Address used for socket bind */
8201+};
d337f35e 8202+
d33d7b00
AM
8203+static inline
8204+int v4_map_sock_addr(struct inet_sock *inet, struct sockaddr_in *addr,
8205+ struct nx_v4_sock_addr *nsa)
8206+{
8207+ struct sock *sk = &inet->sk;
8208+ struct nx_info *nxi = sk->sk_nx_info;
8209+ __be32 saddr = addr->sin_addr.s_addr;
8210+ __be32 baddr = saddr;
d337f35e 8211+
d33d7b00
AM
8212+ vxdprintk(VXD_CBIT(net, 3),
8213+ "inet_bind(%p)* %p,%p;%lx " NIPQUAD_FMT,
8214+ sk, sk->sk_nx_info, sk->sk_socket,
8215+ (sk->sk_socket ? sk->sk_socket->flags : 0),
8216+ NIPQUAD(saddr));
d337f35e 8217+
d33d7b00
AM
8218+ if (nxi) {
8219+ if (saddr == INADDR_ANY) {
8220+ if (nx_info_flags(nxi, NXF_SINGLE_IP, 0))
8221+ baddr = nxi->v4.ip[0].s_addr;
8222+ } else if (saddr == IPI_LOOPBACK) {
8223+ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
8224+ baddr = nxi->v4_lback.s_addr;
9795bf04
AM
8225+ } else if (!ipv4_is_multicast(saddr) ||
8226+ !nx_info_ncaps(nxi, NXC_MULTICAST)) {
8227+ /* normal address bind */
d33d7b00
AM
8228+ if (!v4_addr_in_nx_info(nxi, saddr, NXA_MASK_BIND))
8229+ return -EADDRNOTAVAIL;
8230+ }
8231+ }
d337f35e 8232+
d33d7b00
AM
8233+ vxdprintk(VXD_CBIT(net, 3),
8234+ "inet_bind(%p) " NIPQUAD_FMT ", " NIPQUAD_FMT,
8235+ sk, NIPQUAD(saddr), NIPQUAD(baddr));
d337f35e 8236+
d33d7b00
AM
8237+ nsa->saddr = saddr;
8238+ nsa->baddr = baddr;
8239+ return 0;
8240+}
d337f35e 8241+
d33d7b00
AM
8242+static inline
8243+void v4_set_sock_addr(struct inet_sock *inet, struct nx_v4_sock_addr *nsa)
8244+{
8245+ inet->inet_saddr = nsa->baddr;
8246+ inet->inet_rcv_saddr = nsa->baddr;
8247+}
d337f35e 8248+
d337f35e 8249+
d33d7b00
AM
8250+/*
8251+ * helper to simplify inet_lookup_listener
8252+ *
8253+ * nxi: the socket's nx_info if any
8254+ * addr: to be verified address
8255+ * saddr: socket address
8256+ */
8257+static inline int v4_inet_addr_match (
8258+ struct nx_info *nxi,
8259+ __be32 addr,
8260+ __be32 saddr)
8261+{
8262+ if (addr && (saddr == addr))
8263+ return 1;
8264+ if (!saddr)
8265+ return nxi ? v4_addr_in_nx_info(nxi, addr, NXA_MASK_BIND) : 1;
8266+ return 0;
8267+}
d337f35e 8268+
d33d7b00
AM
8269+static inline __be32 nx_map_sock_lback(struct nx_info *nxi, __be32 addr)
8270+{
8271+ if (nx_info_flags(nxi, NXF_HIDE_LBACK, 0) &&
8272+ (addr == nxi->v4_lback.s_addr))
8273+ return IPI_LOOPBACK;
8274+ return addr;
8275+}
d337f35e 8276+
d33d7b00
AM
8277+static inline
8278+int nx_info_has_v4(struct nx_info *nxi)
8279+{
8280+ if (!nxi)
8281+ return 1;
8282+ if (NX_IPV4(nxi))
8283+ return 1;
8284+ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
8285+ return 1;
8286+ return 0;
8287+}
d337f35e 8288+
d33d7b00 8289+#else /* CONFIG_INET */
d337f35e 8290+
d33d7b00
AM
8291+static inline
8292+int nx_dev_visible(struct nx_info *n, struct net_device *d)
8293+{
8294+ return 1;
8295+}
d337f35e 8296+
d33d7b00
AM
8297+static inline
8298+int nx_v4_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s)
8299+{
8300+ return 1;
8301+}
d337f35e 8302+
d33d7b00
AM
8303+static inline
8304+int v4_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
8305+{
8306+ return 1;
8307+}
d337f35e 8308+
d33d7b00
AM
8309+static inline
8310+int nx_info_has_v4(struct nx_info *nxi)
8311+{
8312+ return 0;
8313+}
d337f35e 8314+
d33d7b00 8315+#endif /* CONFIG_INET */
d337f35e 8316+
d33d7b00
AM
8317+#define current_nx_info_has_v4() \
8318+ nx_info_has_v4(current_nx_info())
d337f35e 8319+
d33d7b00
AM
8320+#else
8321+// #warning duplicate inclusion
3bac966d 8322+#endif
8de2f54c 8323diff -NurpP --minimal linux-4.4.111/include/linux/vs_inet6.h linux-4.4.111-vs2.3.9.5/include/linux/vs_inet6.h
f19bd705 8324--- linux-4.4.111/include/linux/vs_inet6.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 8325+++ linux-4.4.111-vs2.3.9.5/include/linux/vs_inet6.h 2018-01-09 16:36:32.000000000 +0000
5cb1760b 8326@@ -0,0 +1,257 @@
d33d7b00
AM
8327+#ifndef _VS_INET6_H
8328+#define _VS_INET6_H
4a036bed 8329+
d33d7b00
AM
8330+#include "vserver/base.h"
8331+#include "vserver/network.h"
8332+#include "vserver/debug.h"
d337f35e 8333+
d33d7b00 8334+#include <net/ipv6.h>
d337f35e 8335+
d33d7b00
AM
8336+#define NXAV6(a) &(a)->ip, &(a)->mask, (a)->prefix, (a)->type
8337+#define NXAV6_FMT "[%pI6/%pI6/%d:%04x]"
7e46296a 8338+
7e46296a 8339+
d33d7b00 8340+#ifdef CONFIG_IPV6
7e46296a 8341+
d33d7b00
AM
8342+static inline
8343+int v6_addr_match(struct nx_addr_v6 *nxa,
8344+ const struct in6_addr *addr, uint16_t mask)
8345+{
8346+ int ret = 0;
7e46296a 8347+
d33d7b00
AM
8348+ switch (nxa->type & mask) {
8349+ case NXA_TYPE_MASK:
8350+ ret = ipv6_masked_addr_cmp(&nxa->ip, &nxa->mask, addr);
8351+ break;
8352+ case NXA_TYPE_ADDR:
8353+ ret = ipv6_addr_equal(&nxa->ip, addr);
8354+ break;
8355+ case NXA_TYPE_ANY:
8356+ ret = 1;
8357+ break;
8358+ }
8359+ vxdprintk(VXD_CBIT(net, 0),
8360+ "v6_addr_match(%p" NXAV6_FMT ",%pI6,%04x) = %d",
8361+ nxa, NXAV6(nxa), addr, mask, ret);
8362+ return ret;
8363+}
7e46296a 8364+
d33d7b00
AM
8365+static inline
8366+int v6_addr_in_nx_info(struct nx_info *nxi,
8367+ const struct in6_addr *addr, uint16_t mask)
8368+{
8369+ struct nx_addr_v6 *nxa;
7a9e40b8 8370+ unsigned long irqflags;
d33d7b00 8371+ int ret = 1;
d337f35e 8372+
d33d7b00
AM
8373+ if (!nxi)
8374+ goto out;
4bf69007 8375+
7a9e40b8 8376+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
d33d7b00
AM
8377+ for (nxa = &nxi->v6; nxa; nxa = nxa->next)
8378+ if (v6_addr_match(nxa, addr, mask))
4bf69007 8379+ goto out_unlock;
d33d7b00 8380+ ret = 0;
4bf69007 8381+out_unlock:
7a9e40b8 8382+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
d33d7b00
AM
8383+out:
8384+ vxdprintk(VXD_CBIT(net, 0),
8385+ "v6_addr_in_nx_info(%p[#%u],%pI6,%04x) = %d",
8386+ nxi, nxi ? nxi->nx_id : 0, addr, mask, ret);
8387+ return ret;
8388+}
d337f35e 8389+
d33d7b00
AM
8390+static inline
8391+int v6_nx_addr_match(struct nx_addr_v6 *nxa, struct nx_addr_v6 *addr, uint16_t mask)
8392+{
8393+ /* FIXME: needs full range checks */
8394+ return v6_addr_match(nxa, &addr->ip, mask);
8395+}
d337f35e 8396+
d33d7b00
AM
8397+static inline
8398+int v6_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v6 *nxa, uint16_t mask)
8399+{
8400+ struct nx_addr_v6 *ptr;
7a9e40b8 8401+ unsigned long irqflags;
4bf69007 8402+ int ret = 1;
d337f35e 8403+
7a9e40b8 8404+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
d33d7b00
AM
8405+ for (ptr = &nxi->v6; ptr; ptr = ptr->next)
8406+ if (v6_nx_addr_match(ptr, nxa, mask))
4bf69007
AM
8407+ goto out_unlock;
8408+ ret = 0;
8409+out_unlock:
7a9e40b8 8410+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007 8411+ return ret;
d33d7b00 8412+}
d337f35e 8413+
d337f35e 8414+
d33d7b00
AM
8415+/*
8416+ * Check if a given address matches for a socket
8417+ *
8418+ * nxi: the socket's nx_info if any
8419+ * addr: to be verified address
8420+ */
8421+static inline
8422+int v6_sock_addr_match (
8423+ struct nx_info *nxi,
8424+ struct inet_sock *inet,
8425+ struct in6_addr *addr)
8426+{
8427+ struct sock *sk = &inet->sk;
c2e5f7c8 8428+ const struct in6_addr *saddr = inet6_rcv_saddr(sk);
d337f35e 8429+
d33d7b00
AM
8430+ if (!ipv6_addr_any(addr) &&
8431+ ipv6_addr_equal(saddr, addr))
8432+ return 1;
8433+ if (ipv6_addr_any(saddr))
8434+ return v6_addr_in_nx_info(nxi, addr, -1);
8435+ return 0;
8436+}
d337f35e 8437+
d33d7b00
AM
8438+/*
8439+ * check if address is covered by socket
8440+ *
8441+ * sk: the socket to check against
8442+ * addr: the address in question (must be != 0)
8443+ */
d337f35e 8444+
d33d7b00
AM
8445+static inline
8446+int __v6_addr_match_socket(const struct sock *sk, struct nx_addr_v6 *nxa)
8447+{
8448+ struct nx_info *nxi = sk->sk_nx_info;
c2e5f7c8 8449+ const struct in6_addr *saddr = inet6_rcv_saddr(sk);
d337f35e 8450+
d33d7b00
AM
8451+ vxdprintk(VXD_CBIT(net, 5),
8452+ "__v6_addr_in_socket(%p," NXAV6_FMT ") %p:%pI6 %p;%lx",
8453+ sk, NXAV6(nxa), nxi, saddr, sk->sk_socket,
8454+ (sk->sk_socket?sk->sk_socket->flags:0));
d337f35e 8455+
d33d7b00
AM
8456+ if (!ipv6_addr_any(saddr)) { /* direct address match */
8457+ return v6_addr_match(nxa, saddr, -1);
8458+ } else if (nxi) { /* match against nx_info */
8459+ return v6_nx_addr_in_nx_info(nxi, nxa, -1);
8460+ } else { /* unrestricted any socket */
8461+ return 1;
8462+ }
8463+}
d337f35e 8464+
d337f35e 8465+
d33d7b00 8466+/* inet related checks and helpers */
d337f35e 8467+
d337f35e 8468+
d33d7b00
AM
8469+struct in_ifaddr;
8470+struct net_device;
8471+struct sock;
d337f35e
JR
8472+
8473+
d33d7b00
AM
8474+#include <linux/netdevice.h>
8475+#include <linux/inetdevice.h>
8476+#include <net/inet_timewait_sock.h>
d337f35e 8477+
d337f35e 8478+
d33d7b00
AM
8479+int dev_in_nx_info(struct net_device *, struct nx_info *);
8480+int v6_dev_in_nx_info(struct net_device *, struct nx_info *);
8481+int nx_v6_addr_conflict(struct nx_info *, struct nx_info *);
d337f35e
JR
8482+
8483+
3bac966d 8484+
d33d7b00
AM
8485+static inline
8486+int v6_ifa_in_nx_info(struct inet6_ifaddr *ifa, struct nx_info *nxi)
adc1caaa 8487+{
d33d7b00
AM
8488+ if (!nxi)
8489+ return 1;
8490+ if (!ifa)
8491+ return 0;
8492+ return v6_addr_in_nx_info(nxi, &ifa->addr, -1);
8493+}
d337f35e 8494+
d33d7b00
AM
8495+static inline
8496+int nx_v6_ifa_visible(struct nx_info *nxi, struct inet6_ifaddr *ifa)
8497+{
8498+ vxdprintk(VXD_CBIT(net, 1), "nx_v6_ifa_visible(%p[#%u],%p) %d",
8499+ nxi, nxi ? nxi->nx_id : 0, ifa,
8500+ nxi ? v6_ifa_in_nx_info(ifa, nxi) : 0);
d337f35e 8501+
d33d7b00
AM
8502+ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
8503+ return 1;
8504+ if (v6_ifa_in_nx_info(ifa, nxi))
8505+ return 1;
8506+ return 0;
adc1caaa 8507+}
d337f35e 8508+
d337f35e 8509+
d33d7b00
AM
8510+struct nx_v6_sock_addr {
8511+ struct in6_addr saddr; /* Address used for validation */
8512+ struct in6_addr baddr; /* Address used for socket bind */
8513+};
8514+
8515+static inline
8516+int v6_map_sock_addr(struct inet_sock *inet, struct sockaddr_in6 *addr,
8517+ struct nx_v6_sock_addr *nsa)
8518+{
8519+ // struct sock *sk = &inet->sk;
8520+ // struct nx_info *nxi = sk->sk_nx_info;
8521+ struct in6_addr saddr = addr->sin6_addr;
8522+ struct in6_addr baddr = saddr;
3bac966d 8523+
d33d7b00
AM
8524+ nsa->saddr = saddr;
8525+ nsa->baddr = baddr;
8526+ return 0;
8527+}
3bac966d 8528+
d33d7b00
AM
8529+static inline
8530+void v6_set_sock_addr(struct inet_sock *inet, struct nx_v6_sock_addr *nsa)
8531+{
8532+ // struct sock *sk = &inet->sk;
8533+ // struct in6_addr *saddr = inet6_rcv_saddr(sk);
3bac966d 8534+
d33d7b00
AM
8535+ // *saddr = nsa->baddr;
8536+ // inet->inet_saddr = nsa->baddr;
8537+}
3bac966d 8538+
d33d7b00
AM
8539+static inline
8540+int nx_info_has_v6(struct nx_info *nxi)
8541+{
8542+ if (!nxi)
8543+ return 1;
8544+ if (NX_IPV6(nxi))
8545+ return 1;
8546+ return 0;
8547+}
3bac966d 8548+
d33d7b00 8549+#else /* CONFIG_IPV6 */
d337f35e 8550+
2380c486 8551+static inline
d33d7b00 8552+int nx_v6_dev_visible(struct nx_info *n, struct net_device *d)
2380c486 8553+{
d33d7b00 8554+ return 1;
d337f35e
JR
8555+}
8556+
3bac966d 8557+
adc1caaa 8558+static inline
d33d7b00 8559+int nx_v6_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s)
adc1caaa 8560+{
d33d7b00 8561+ return 1;
adc1caaa 8562+}
2380c486 8563+
d33d7b00
AM
8564+static inline
8565+int v6_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
8566+{
8567+ return 1;
8568+}
8569+
8570+static inline
8571+int nx_info_has_v6(struct nx_info *nxi)
8572+{
8573+ return 0;
8574+}
2380c486 8575+
d33d7b00 8576+#endif /* CONFIG_IPV6 */
d337f35e 8577+
d33d7b00
AM
8578+#define current_nx_info_has_v6() \
8579+ nx_info_has_v6(current_nx_info())
3bac966d 8580+
d337f35e 8581+#else
d33d7b00 8582+#warning duplicate inclusion
d337f35e 8583+#endif
8de2f54c 8584diff -NurpP --minimal linux-4.4.111/include/linux/vs_limit.h linux-4.4.111-vs2.3.9.5/include/linux/vs_limit.h
f19bd705 8585--- linux-4.4.111/include/linux/vs_limit.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 8586+++ linux-4.4.111-vs2.3.9.5/include/linux/vs_limit.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00
AM
8587@@ -0,0 +1,140 @@
8588+#ifndef _VS_LIMIT_H
8589+#define _VS_LIMIT_H
d337f35e 8590+
d33d7b00
AM
8591+#include "vserver/limit.h"
8592+#include "vserver/base.h"
8593+#include "vserver/context.h"
8594+#include "vserver/debug.h"
8595+#include "vserver/context.h"
8596+#include "vserver/limit_int.h"
d337f35e
JR
8597+
8598+
d33d7b00
AM
8599+#define vx_acc_cres(v, d, p, r) \
8600+ __vx_acc_cres(v, r, d, p, __FILE__, __LINE__)
d337f35e 8601+
d33d7b00
AM
8602+#define vx_acc_cres_cond(x, d, p, r) \
8603+ __vx_acc_cres(((x) == vx_current_xid()) ? current_vx_info() : 0, \
8604+ r, d, p, __FILE__, __LINE__)
d337f35e
JR
8605+
8606+
d33d7b00
AM
8607+#define vx_add_cres(v, a, p, r) \
8608+ __vx_add_cres(v, r, a, p, __FILE__, __LINE__)
8609+#define vx_sub_cres(v, a, p, r) vx_add_cres(v, -(a), p, r)
d337f35e 8610+
d33d7b00
AM
8611+#define vx_add_cres_cond(x, a, p, r) \
8612+ __vx_add_cres(((x) == vx_current_xid()) ? current_vx_info() : 0, \
8613+ r, a, p, __FILE__, __LINE__)
8614+#define vx_sub_cres_cond(x, a, p, r) vx_add_cres_cond(x, -(a), p, r)
d337f35e 8615+
d337f35e 8616+
d33d7b00 8617+/* process and file limits */
d337f35e 8618+
d33d7b00
AM
8619+#define vx_nproc_inc(p) \
8620+ vx_acc_cres((p)->vx_info, 1, p, RLIMIT_NPROC)
d337f35e 8621+
d33d7b00
AM
8622+#define vx_nproc_dec(p) \
8623+ vx_acc_cres((p)->vx_info,-1, p, RLIMIT_NPROC)
d337f35e 8624+
d33d7b00
AM
8625+#define vx_files_inc(f) \
8626+ vx_acc_cres_cond((f)->f_xid, 1, f, RLIMIT_NOFILE)
d337f35e 8627+
d33d7b00
AM
8628+#define vx_files_dec(f) \
8629+ vx_acc_cres_cond((f)->f_xid,-1, f, RLIMIT_NOFILE)
d337f35e 8630+
d33d7b00
AM
8631+#define vx_locks_inc(l) \
8632+ vx_acc_cres_cond((l)->fl_xid, 1, l, RLIMIT_LOCKS)
d337f35e 8633+
d33d7b00
AM
8634+#define vx_locks_dec(l) \
8635+ vx_acc_cres_cond((l)->fl_xid,-1, l, RLIMIT_LOCKS)
d337f35e 8636+
d33d7b00
AM
8637+#define vx_openfd_inc(f) \
8638+ vx_acc_cres(current_vx_info(), 1, (void *)(long)(f), VLIMIT_OPENFD)
d337f35e 8639+
d33d7b00
AM
8640+#define vx_openfd_dec(f) \
8641+ vx_acc_cres(current_vx_info(),-1, (void *)(long)(f), VLIMIT_OPENFD)
d337f35e 8642+
d337f35e 8643+
d33d7b00
AM
8644+#define vx_cres_avail(v, n, r) \
8645+ __vx_cres_avail(v, r, n, __FILE__, __LINE__)
d337f35e 8646+
d337f35e 8647+
d33d7b00
AM
8648+#define vx_nproc_avail(n) \
8649+ vx_cres_avail(current_vx_info(), n, RLIMIT_NPROC)
d337f35e 8650+
d33d7b00
AM
8651+#define vx_files_avail(n) \
8652+ vx_cres_avail(current_vx_info(), n, RLIMIT_NOFILE)
d337f35e 8653+
d33d7b00
AM
8654+#define vx_locks_avail(n) \
8655+ vx_cres_avail(current_vx_info(), n, RLIMIT_LOCKS)
d337f35e 8656+
d33d7b00
AM
8657+#define vx_openfd_avail(n) \
8658+ vx_cres_avail(current_vx_info(), n, VLIMIT_OPENFD)
d337f35e 8659+
d337f35e 8660+
d33d7b00 8661+/* dentry limits */
d337f35e 8662+
d33d7b00 8663+#define vx_dentry_inc(d) do { \
c2e5f7c8 8664+ if (d_count(d) == 1) \
d33d7b00
AM
8665+ vx_acc_cres(current_vx_info(), 1, d, VLIMIT_DENTRY); \
8666+ } while (0)
d337f35e 8667+
d33d7b00 8668+#define vx_dentry_dec(d) do { \
c2e5f7c8 8669+ if (d_count(d) == 0) \
d33d7b00
AM
8670+ vx_acc_cres(current_vx_info(),-1, d, VLIMIT_DENTRY); \
8671+ } while (0)
d337f35e 8672+
d33d7b00
AM
8673+#define vx_dentry_avail(n) \
8674+ vx_cres_avail(current_vx_info(), n, VLIMIT_DENTRY)
d337f35e 8675+
d337f35e 8676+
d33d7b00 8677+/* socket limits */
d337f35e 8678+
d33d7b00
AM
8679+#define vx_sock_inc(s) \
8680+ vx_acc_cres((s)->sk_vx_info, 1, s, VLIMIT_NSOCK)
d337f35e 8681+
d33d7b00
AM
8682+#define vx_sock_dec(s) \
8683+ vx_acc_cres((s)->sk_vx_info,-1, s, VLIMIT_NSOCK)
d337f35e 8684+
d33d7b00
AM
8685+#define vx_sock_avail(n) \
8686+ vx_cres_avail(current_vx_info(), n, VLIMIT_NSOCK)
d337f35e 8687+
d337f35e 8688+
d33d7b00 8689+/* ipc resource limits */
d337f35e 8690+
d33d7b00
AM
8691+#define vx_ipcmsg_add(v, u, a) \
8692+ vx_add_cres(v, a, u, RLIMIT_MSGQUEUE)
d337f35e 8693+
d33d7b00
AM
8694+#define vx_ipcmsg_sub(v, u, a) \
8695+ vx_sub_cres(v, a, u, RLIMIT_MSGQUEUE)
d337f35e 8696+
d33d7b00
AM
8697+#define vx_ipcmsg_avail(v, a) \
8698+ vx_cres_avail(v, a, RLIMIT_MSGQUEUE)
d337f35e 8699+
d337f35e 8700+
d33d7b00
AM
8701+#define vx_ipcshm_add(v, k, a) \
8702+ vx_add_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
d337f35e 8703+
d33d7b00
AM
8704+#define vx_ipcshm_sub(v, k, a) \
8705+ vx_sub_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
d337f35e 8706+
d33d7b00
AM
8707+#define vx_ipcshm_avail(v, a) \
8708+ vx_cres_avail(v, a, VLIMIT_SHMEM)
d337f35e
JR
8709+
8710+
d33d7b00
AM
8711+#define vx_semary_inc(a) \
8712+ vx_acc_cres(current_vx_info(), 1, a, VLIMIT_SEMARY)
d337f35e 8713+
d33d7b00
AM
8714+#define vx_semary_dec(a) \
8715+ vx_acc_cres(current_vx_info(), -1, a, VLIMIT_SEMARY)
d337f35e 8716+
d337f35e 8717+
d33d7b00
AM
8718+#define vx_nsems_add(a,n) \
8719+ vx_add_cres(current_vx_info(), n, a, VLIMIT_NSEMS)
d337f35e 8720+
d33d7b00
AM
8721+#define vx_nsems_sub(a,n) \
8722+ vx_sub_cres(current_vx_info(), n, a, VLIMIT_NSEMS)
d337f35e
JR
8723+
8724+
d33d7b00
AM
8725+#else
8726+#warning duplicate inclusion
8727+#endif
8de2f54c 8728diff -NurpP --minimal linux-4.4.111/include/linux/vs_network.h linux-4.4.111-vs2.3.9.5/include/linux/vs_network.h
f19bd705 8729--- linux-4.4.111/include/linux/vs_network.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 8730+++ linux-4.4.111-vs2.3.9.5/include/linux/vs_network.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00
AM
8731@@ -0,0 +1,169 @@
8732+#ifndef _NX_VS_NETWORK_H
8733+#define _NX_VS_NETWORK_H
7e46296a 8734+
d33d7b00
AM
8735+#include "vserver/context.h"
8736+#include "vserver/network.h"
8737+#include "vserver/base.h"
8738+#include "vserver/check.h"
8739+#include "vserver/debug.h"
2380c486 8740+
d33d7b00 8741+#include <linux/sched.h>
2380c486 8742+
2380c486 8743+
d33d7b00 8744+#define get_nx_info(i) __get_nx_info(i, __FILE__, __LINE__)
2380c486 8745+
d33d7b00
AM
8746+static inline struct nx_info *__get_nx_info(struct nx_info *nxi,
8747+ const char *_file, int _line)
8748+{
8749+ if (!nxi)
8750+ return NULL;
d337f35e 8751+
d33d7b00
AM
8752+ vxlprintk(VXD_CBIT(nid, 2), "get_nx_info(%p[#%d.%d])",
8753+ nxi, nxi ? nxi->nx_id : 0,
8754+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
8755+ _file, _line);
d337f35e 8756+
d33d7b00
AM
8757+ atomic_inc(&nxi->nx_usecnt);
8758+ return nxi;
8759+}
d337f35e
JR
8760+
8761+
d33d7b00 8762+extern void free_nx_info(struct nx_info *);
d337f35e 8763+
d33d7b00 8764+#define put_nx_info(i) __put_nx_info(i, __FILE__, __LINE__)
d337f35e 8765+
d33d7b00
AM
8766+static inline void __put_nx_info(struct nx_info *nxi, const char *_file, int _line)
8767+{
8768+ if (!nxi)
8769+ return;
d337f35e 8770+
d33d7b00
AM
8771+ vxlprintk(VXD_CBIT(nid, 2), "put_nx_info(%p[#%d.%d])",
8772+ nxi, nxi ? nxi->nx_id : 0,
8773+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
8774+ _file, _line);
d337f35e 8775+
d33d7b00
AM
8776+ if (atomic_dec_and_test(&nxi->nx_usecnt))
8777+ free_nx_info(nxi);
8778+}
d337f35e 8779+
d337f35e 8780+
d33d7b00 8781+#define init_nx_info(p, i) __init_nx_info(p, i, __FILE__, __LINE__)
d337f35e 8782+
d33d7b00
AM
8783+static inline void __init_nx_info(struct nx_info **nxp, struct nx_info *nxi,
8784+ const char *_file, int _line)
8785+{
8786+ if (nxi) {
8787+ vxlprintk(VXD_CBIT(nid, 3),
8788+ "init_nx_info(%p[#%d.%d])",
8789+ nxi, nxi ? nxi->nx_id : 0,
8790+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
8791+ _file, _line);
d337f35e 8792+
d33d7b00
AM
8793+ atomic_inc(&nxi->nx_usecnt);
8794+ }
8795+ *nxp = nxi;
8796+}
d337f35e 8797+
d337f35e 8798+
d33d7b00 8799+#define set_nx_info(p, i) __set_nx_info(p, i, __FILE__, __LINE__)
d337f35e 8800+
d33d7b00
AM
8801+static inline void __set_nx_info(struct nx_info **nxp, struct nx_info *nxi,
8802+ const char *_file, int _line)
8803+{
8804+ struct nx_info *nxo;
d337f35e 8805+
d33d7b00
AM
8806+ if (!nxi)
8807+ return;
d337f35e 8808+
d33d7b00
AM
8809+ vxlprintk(VXD_CBIT(nid, 3), "set_nx_info(%p[#%d.%d])",
8810+ nxi, nxi ? nxi->nx_id : 0,
8811+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
8812+ _file, _line);
d337f35e 8813+
d33d7b00
AM
8814+ atomic_inc(&nxi->nx_usecnt);
8815+ nxo = xchg(nxp, nxi);
8816+ BUG_ON(nxo);
8817+}
d337f35e 8818+
d33d7b00 8819+#define clr_nx_info(p) __clr_nx_info(p, __FILE__, __LINE__)
d337f35e 8820+
d33d7b00
AM
8821+static inline void __clr_nx_info(struct nx_info **nxp,
8822+ const char *_file, int _line)
8823+{
8824+ struct nx_info *nxo;
d337f35e 8825+
d33d7b00
AM
8826+ nxo = xchg(nxp, NULL);
8827+ if (!nxo)
8828+ return;
d337f35e 8829+
d33d7b00
AM
8830+ vxlprintk(VXD_CBIT(nid, 3), "clr_nx_info(%p[#%d.%d])",
8831+ nxo, nxo ? nxo->nx_id : 0,
8832+ nxo ? atomic_read(&nxo->nx_usecnt) : 0,
8833+ _file, _line);
d337f35e 8834+
d33d7b00
AM
8835+ if (atomic_dec_and_test(&nxo->nx_usecnt))
8836+ free_nx_info(nxo);
8837+}
d337f35e
JR
8838+
8839+
d33d7b00 8840+#define claim_nx_info(v, p) __claim_nx_info(v, p, __FILE__, __LINE__)
d337f35e 8841+
d33d7b00
AM
8842+static inline void __claim_nx_info(struct nx_info *nxi,
8843+ struct task_struct *task, const char *_file, int _line)
8844+{
8845+ vxlprintk(VXD_CBIT(nid, 3), "claim_nx_info(%p[#%d.%d.%d]) %p",
8846+ nxi, nxi ? nxi->nx_id : 0,
8847+ nxi?atomic_read(&nxi->nx_usecnt):0,
8848+ nxi?atomic_read(&nxi->nx_tasks):0,
8849+ task, _file, _line);
d337f35e 8850+
d33d7b00
AM
8851+ atomic_inc(&nxi->nx_tasks);
8852+}
d337f35e 8853+
d337f35e 8854+
d33d7b00 8855+extern void unhash_nx_info(struct nx_info *);
d337f35e 8856+
d33d7b00 8857+#define release_nx_info(v, p) __release_nx_info(v, p, __FILE__, __LINE__)
d337f35e 8858+
d33d7b00
AM
8859+static inline void __release_nx_info(struct nx_info *nxi,
8860+ struct task_struct *task, const char *_file, int _line)
8861+{
8862+ vxlprintk(VXD_CBIT(nid, 3), "release_nx_info(%p[#%d.%d.%d]) %p",
8863+ nxi, nxi ? nxi->nx_id : 0,
8864+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
8865+ nxi ? atomic_read(&nxi->nx_tasks) : 0,
8866+ task, _file, _line);
ab30d09f 8867+
d33d7b00 8868+ might_sleep();
d337f35e 8869+
d33d7b00
AM
8870+ if (atomic_dec_and_test(&nxi->nx_tasks))
8871+ unhash_nx_info(nxi);
8872+}
d337f35e
JR
8873+
8874+
d33d7b00 8875+#define task_get_nx_info(i) __task_get_nx_info(i, __FILE__, __LINE__)
d337f35e 8876+
d33d7b00
AM
8877+static __inline__ struct nx_info *__task_get_nx_info(struct task_struct *p,
8878+ const char *_file, int _line)
8879+{
8880+ struct nx_info *nxi;
d337f35e 8881+
d33d7b00
AM
8882+ task_lock(p);
8883+ vxlprintk(VXD_CBIT(nid, 5), "task_get_nx_info(%p)",
8884+ p, _file, _line);
8885+ nxi = __get_nx_info(p->nx_info, _file, _line);
8886+ task_unlock(p);
8887+ return nxi;
8888+}
d337f35e 8889+
d337f35e 8890+
d33d7b00
AM
8891+static inline void exit_nx_info(struct task_struct *p)
8892+{
8893+ if (p->nx_info)
8894+ release_nx_info(p->nx_info, p);
8895+}
adc1caaa 8896+
d337f35e 8897+
2380c486 8898+#else
d33d7b00 8899+#warning duplicate inclusion
2380c486 8900+#endif
8de2f54c 8901diff -NurpP --minimal linux-4.4.111/include/linux/vs_pid.h linux-4.4.111-vs2.3.9.5/include/linux/vs_pid.h
f19bd705 8902--- linux-4.4.111/include/linux/vs_pid.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 8903+++ linux-4.4.111-vs2.3.9.5/include/linux/vs_pid.h 2018-01-09 16:36:32.000000000 +0000
b3b0d4fd 8904@@ -0,0 +1,50 @@
d33d7b00
AM
8905+#ifndef _VS_PID_H
8906+#define _VS_PID_H
d337f35e 8907+
d33d7b00
AM
8908+#include "vserver/base.h"
8909+#include "vserver/check.h"
8910+#include "vserver/context.h"
8911+#include "vserver/debug.h"
8912+#include "vserver/pid.h"
8913+#include <linux/pid_namespace.h>
d337f35e 8914+
d337f35e 8915+
d33d7b00 8916+#define VXF_FAKE_INIT (VXF_INFO_INIT | VXF_STATE_INIT)
d337f35e 8917+
d33d7b00
AM
8918+static inline
8919+int vx_proc_task_visible(struct task_struct *task)
8920+{
8921+ if ((task->pid == 1) &&
8922+ !vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT))
8923+ /* show a blend through init */
8924+ goto visible;
8925+ if (vx_check(vx_task_xid(task), VS_WATCH | VS_IDENT))
8926+ goto visible;
8927+ return 0;
8928+visible:
8929+ return 1;
8930+}
d337f35e 8931+
d33d7b00 8932+#define find_task_by_real_pid(pid) find_task_by_pid_ns(pid, &init_pid_ns)
d337f35e 8933+
d337f35e 8934+
d33d7b00
AM
8935+static inline
8936+struct task_struct *vx_get_proc_task(struct inode *inode, struct pid *pid)
8937+{
8938+ struct task_struct *task = get_pid_task(pid, PIDTYPE_PID);
d337f35e 8939+
d33d7b00
AM
8940+ if (task && !vx_proc_task_visible(task)) {
8941+ vxdprintk(VXD_CBIT(misc, 6),
8942+ "dropping task (get) %p[#%u,%u] for %p[#%u,%u]",
8943+ task, task->xid, task->pid,
8944+ current, current->xid, current->pid);
8945+ put_task_struct(task);
8946+ task = NULL;
8947+ }
8948+ return task;
8949+}
d337f35e 8950+
d337f35e 8951+
d33d7b00
AM
8952+#else
8953+#warning duplicate inclusion
8954+#endif
8de2f54c 8955diff -NurpP --minimal linux-4.4.111/include/linux/vs_sched.h linux-4.4.111-vs2.3.9.5/include/linux/vs_sched.h
f19bd705 8956--- linux-4.4.111/include/linux/vs_sched.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 8957+++ linux-4.4.111-vs2.3.9.5/include/linux/vs_sched.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00
AM
8958@@ -0,0 +1,40 @@
8959+#ifndef _VS_SCHED_H
8960+#define _VS_SCHED_H
d337f35e 8961+
d33d7b00
AM
8962+#include "vserver/base.h"
8963+#include "vserver/context.h"
8964+#include "vserver/sched.h"
d337f35e
JR
8965+
8966+
d33d7b00
AM
8967+#define MAX_PRIO_BIAS 20
8968+#define MIN_PRIO_BIAS -20
d337f35e 8969+
d33d7b00
AM
8970+static inline
8971+int vx_adjust_prio(struct task_struct *p, int prio, int max_user)
8972+{
8973+ struct vx_info *vxi = p->vx_info;
d337f35e 8974+
d33d7b00
AM
8975+ if (vxi)
8976+ prio += vx_cpu(vxi, sched_pc).prio_bias;
8977+ return prio;
8978+}
d337f35e 8979+
d33d7b00
AM
8980+static inline void vx_account_user(struct vx_info *vxi,
8981+ cputime_t cputime, int nice)
8982+{
8983+ if (!vxi)
8984+ return;
8985+ vx_cpu(vxi, sched_pc).user_ticks += cputime;
8986+}
d337f35e 8987+
d33d7b00
AM
8988+static inline void vx_account_system(struct vx_info *vxi,
8989+ cputime_t cputime, int idle)
8990+{
8991+ if (!vxi)
8992+ return;
8993+ vx_cpu(vxi, sched_pc).sys_ticks += cputime;
8994+}
d337f35e 8995+
d33d7b00
AM
8996+#else
8997+#warning duplicate inclusion
8998+#endif
8de2f54c 8999diff -NurpP --minimal linux-4.4.111/include/linux/vs_socket.h linux-4.4.111-vs2.3.9.5/include/linux/vs_socket.h
f19bd705 9000--- linux-4.4.111/include/linux/vs_socket.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9001+++ linux-4.4.111-vs2.3.9.5/include/linux/vs_socket.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00
AM
9002@@ -0,0 +1,67 @@
9003+#ifndef _VS_SOCKET_H
9004+#define _VS_SOCKET_H
d337f35e 9005+
d33d7b00
AM
9006+#include "vserver/debug.h"
9007+#include "vserver/base.h"
9008+#include "vserver/cacct.h"
9009+#include "vserver/context.h"
9010+#include "vserver/tag.h"
d337f35e 9011+
d337f35e 9012+
d33d7b00 9013+/* socket accounting */
d337f35e 9014+
d33d7b00 9015+#include <linux/socket.h>
d337f35e 9016+
d33d7b00
AM
9017+static inline int vx_sock_type(int family)
9018+{
9019+ switch (family) {
9020+ case PF_UNSPEC:
9021+ return VXA_SOCK_UNSPEC;
9022+ case PF_UNIX:
9023+ return VXA_SOCK_UNIX;
9024+ case PF_INET:
9025+ return VXA_SOCK_INET;
9026+ case PF_INET6:
9027+ return VXA_SOCK_INET6;
9028+ case PF_PACKET:
9029+ return VXA_SOCK_PACKET;
9030+ default:
9031+ return VXA_SOCK_OTHER;
9032+ }
9033+}
d337f35e 9034+
d33d7b00
AM
9035+#define vx_acc_sock(v, f, p, s) \
9036+ __vx_acc_sock(v, f, p, s, __FILE__, __LINE__)
d337f35e 9037+
d33d7b00
AM
9038+static inline void __vx_acc_sock(struct vx_info *vxi,
9039+ int family, int pos, int size, char *file, int line)
9040+{
9041+ if (vxi) {
9042+ int type = vx_sock_type(family);
d337f35e 9043+
d33d7b00
AM
9044+ atomic_long_inc(&vxi->cacct.sock[type][pos].count);
9045+ atomic_long_add(size, &vxi->cacct.sock[type][pos].total);
9046+ }
9047+}
d337f35e 9048+
d33d7b00
AM
9049+#define vx_sock_recv(sk, s) \
9050+ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, s)
9051+#define vx_sock_send(sk, s) \
9052+ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, s)
9053+#define vx_sock_fail(sk, s) \
9054+ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, s)
d337f35e 9055+
d337f35e 9056+
d33d7b00
AM
9057+#define sock_vx_init(s) do { \
9058+ (s)->sk_xid = 0; \
9059+ (s)->sk_vx_info = NULL; \
9060+ } while (0)
d337f35e 9061+
d33d7b00
AM
9062+#define sock_nx_init(s) do { \
9063+ (s)->sk_nid = 0; \
9064+ (s)->sk_nx_info = NULL; \
9065+ } while (0)
d337f35e 9066+
d33d7b00
AM
9067+#else
9068+#warning duplicate inclusion
9069+#endif
8de2f54c 9070diff -NurpP --minimal linux-4.4.111/include/linux/vs_tag.h linux-4.4.111-vs2.3.9.5/include/linux/vs_tag.h
f19bd705 9071--- linux-4.4.111/include/linux/vs_tag.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9072+++ linux-4.4.111-vs2.3.9.5/include/linux/vs_tag.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00
AM
9073@@ -0,0 +1,47 @@
9074+#ifndef _VS_TAG_H
9075+#define _VS_TAG_H
d337f35e 9076+
d33d7b00 9077+#include <linux/vserver/tag.h>
d337f35e 9078+
d33d7b00 9079+/* check conditions */
d337f35e 9080+
d33d7b00
AM
9081+#define DX_ADMIN 0x0001
9082+#define DX_WATCH 0x0002
9083+#define DX_HOSTID 0x0008
d337f35e 9084+
d33d7b00 9085+#define DX_IDENT 0x0010
d337f35e 9086+
d33d7b00 9087+#define DX_ARG_MASK 0x0010
d337f35e 9088+
d337f35e 9089+
d33d7b00 9090+#define dx_task_tag(t) ((t)->tag)
d337f35e 9091+
d33d7b00 9092+#define dx_current_tag() dx_task_tag(current)
d337f35e 9093+
d33d7b00 9094+#define dx_check(c, m) __dx_check(dx_current_tag(), c, m)
d337f35e 9095+
d33d7b00 9096+#define dx_weak_check(c, m) ((m) ? dx_check(c, m) : 1)
d337f35e
JR
9097+
9098+
d33d7b00
AM
9099+/*
9100+ * check current context for ADMIN/WATCH and
9101+ * optionally against supplied argument
9102+ */
61333608 9103+static inline int __dx_check(vtag_t cid, vtag_t id, unsigned int mode)
d33d7b00
AM
9104+{
9105+ if (mode & DX_ARG_MASK) {
9106+ if ((mode & DX_IDENT) && (id == cid))
9107+ return 1;
9108+ }
9109+ return (((mode & DX_ADMIN) && (cid == 0)) ||
9110+ ((mode & DX_WATCH) && (cid == 1)) ||
9111+ ((mode & DX_HOSTID) && (id == 0)));
9112+}
d337f35e 9113+
d33d7b00
AM
9114+struct inode;
9115+int dx_permission(const struct inode *inode, int mask);
d337f35e 9116+
d337f35e 9117+
d33d7b00
AM
9118+#else
9119+#warning duplicate inclusion
9120+#endif
8de2f54c 9121diff -NurpP --minimal linux-4.4.111/include/linux/vs_time.h linux-4.4.111-vs2.3.9.5/include/linux/vs_time.h
f19bd705 9122--- linux-4.4.111/include/linux/vs_time.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9123+++ linux-4.4.111-vs2.3.9.5/include/linux/vs_time.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00
AM
9124@@ -0,0 +1,19 @@
9125+#ifndef _VS_TIME_H
9126+#define _VS_TIME_H
d337f35e 9127+
d337f35e 9128+
d33d7b00 9129+/* time faking stuff */
d337f35e 9130+
d33d7b00 9131+#ifdef CONFIG_VSERVER_VTIME
d337f35e 9132+
d33d7b00 9133+extern void vx_adjust_timespec(struct timespec *ts);
763640ca 9134+extern int vx_settimeofday(const struct timespec *ts);
d337f35e 9135+
d33d7b00
AM
9136+#else
9137+#define vx_adjust_timespec(t) do { } while (0)
9138+#define vx_settimeofday(t) do_settimeofday(t)
9139+#endif
d337f35e 9140+
d33d7b00
AM
9141+#else
9142+#warning duplicate inclusion
9143+#endif
8de2f54c 9144diff -NurpP --minimal linux-4.4.111/include/linux/vserver/base.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/base.h
f19bd705 9145--- linux-4.4.111/include/linux/vserver/base.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9146+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/base.h 2018-01-09 16:36:32.000000000 +0000
c2e5f7c8 9147@@ -0,0 +1,184 @@
4bf69007
AM
9148+#ifndef _VSERVER_BASE_H
9149+#define _VSERVER_BASE_H
d337f35e 9150+
d337f35e 9151+
d33d7b00 9152+/* context state changes */
d337f35e 9153+
d33d7b00
AM
9154+enum {
9155+ VSC_STARTUP = 1,
9156+ VSC_SHUTDOWN,
d337f35e 9157+
d33d7b00
AM
9158+ VSC_NETUP,
9159+ VSC_NETDOWN,
3bac966d 9160+};
d337f35e 9161+
d337f35e
JR
9162+
9163+
d33d7b00 9164+#define vx_task_xid(t) ((t)->xid)
d337f35e 9165+
d33d7b00 9166+#define vx_current_xid() vx_task_xid(current)
d337f35e 9167+
d33d7b00 9168+#define current_vx_info() (current->vx_info)
d337f35e 9169+
ba86f833 9170+
d33d7b00 9171+#define nx_task_nid(t) ((t)->nid)
ba86f833 9172+
d33d7b00 9173+#define nx_current_nid() nx_task_nid(current)
d337f35e 9174+
d33d7b00 9175+#define current_nx_info() (current->nx_info)
d337f35e 9176+
d337f35e 9177+
d33d7b00 9178+/* generic flag merging */
d337f35e 9179+
d33d7b00 9180+#define vs_check_flags(v, m, f) (((v) & (m)) ^ (f))
d337f35e 9181+
d33d7b00 9182+#define vs_mask_flags(v, f, m) (((v) & ~(m)) | ((f) & (m)))
d337f35e 9183+
d33d7b00 9184+#define vs_mask_mask(v, f, m) (((v) & ~(m)) | ((v) & (f) & (m)))
d337f35e 9185+
d33d7b00 9186+#define vs_check_bit(v, n) ((v) & (1LL << (n)))
d337f35e 9187+
d337f35e 9188+
d33d7b00 9189+/* context flags */
d337f35e 9190+
d33d7b00 9191+#define __vx_flags(v) ((v) ? (v)->vx_flags : 0)
d337f35e 9192+
d33d7b00 9193+#define vx_current_flags() __vx_flags(current_vx_info())
d337f35e 9194+
d33d7b00
AM
9195+#define vx_info_flags(v, m, f) \
9196+ vs_check_flags(__vx_flags(v), m, f)
d337f35e 9197+
d33d7b00
AM
9198+#define task_vx_flags(t, m, f) \
9199+ ((t) && vx_info_flags((t)->vx_info, m, f))
d337f35e 9200+
d33d7b00 9201+#define vx_flags(m, f) vx_info_flags(current_vx_info(), m, f)
d337f35e
JR
9202+
9203+
d33d7b00 9204+/* context caps */
d337f35e 9205+
d33d7b00 9206+#define __vx_ccaps(v) ((v) ? (v)->vx_ccaps : 0)
d337f35e 9207+
d33d7b00 9208+#define vx_current_ccaps() __vx_ccaps(current_vx_info())
d337f35e 9209+
d33d7b00 9210+#define vx_info_ccaps(v, c) (__vx_ccaps(v) & (c))
d337f35e 9211+
d33d7b00 9212+#define vx_ccaps(c) vx_info_ccaps(current_vx_info(), (c))
d337f35e 9213+
d337f35e
JR
9214+
9215+
d33d7b00 9216+/* network flags */
2380c486 9217+
d33d7b00 9218+#define __nx_flags(n) ((n) ? (n)->nx_flags : 0)
d337f35e 9219+
d33d7b00 9220+#define nx_current_flags() __nx_flags(current_nx_info())
d337f35e 9221+
d33d7b00
AM
9222+#define nx_info_flags(n, m, f) \
9223+ vs_check_flags(__nx_flags(n), m, f)
d337f35e 9224+
d33d7b00
AM
9225+#define task_nx_flags(t, m, f) \
9226+ ((t) && nx_info_flags((t)->nx_info, m, f))
d337f35e 9227+
d33d7b00 9228+#define nx_flags(m, f) nx_info_flags(current_nx_info(), m, f)
d337f35e 9229+
d337f35e 9230+
d33d7b00 9231+/* network caps */
d337f35e 9232+
d33d7b00 9233+#define __nx_ncaps(n) ((n) ? (n)->nx_ncaps : 0)
d337f35e 9234+
d33d7b00 9235+#define nx_current_ncaps() __nx_ncaps(current_nx_info())
d337f35e 9236+
d33d7b00 9237+#define nx_info_ncaps(n, c) (__nx_ncaps(n) & (c))
d337f35e 9238+
d33d7b00 9239+#define nx_ncaps(c) nx_info_ncaps(current_nx_info(), c)
d337f35e 9240+
d337f35e 9241+
d33d7b00 9242+/* context mask capabilities */
d337f35e 9243+
d33d7b00 9244+#define __vx_mcaps(v) ((v) ? (v)->vx_ccaps >> 32UL : ~0 )
d337f35e 9245+
d33d7b00 9246+#define vx_info_mcaps(v, c) (__vx_mcaps(v) & (c))
d337f35e 9247+
d33d7b00 9248+#define vx_mcaps(c) vx_info_mcaps(current_vx_info(), c)
d337f35e
JR
9249+
9250+
d33d7b00 9251+/* context bcap mask */
d337f35e 9252+
d33d7b00 9253+#define __vx_bcaps(v) ((v)->vx_bcaps)
d337f35e 9254+
d33d7b00 9255+#define vx_current_bcaps() __vx_bcaps(current_vx_info())
d337f35e 9256+
d337f35e 9257+
d33d7b00 9258+/* mask given bcaps */
adc1caaa 9259+
d33d7b00 9260+#define vx_info_mbcaps(v, c) ((v) ? cap_intersect(__vx_bcaps(v), c) : c)
2380c486 9261+
d33d7b00 9262+#define vx_mbcaps(c) vx_info_mbcaps(current_vx_info(), c)
d337f35e
JR
9263+
9264+
d33d7b00 9265+/* masked cap_bset */
2380c486 9266+
d33d7b00 9267+#define vx_info_cap_bset(v) vx_info_mbcaps(v, current->cap_bset)
2380c486 9268+
d33d7b00 9269+#define vx_current_cap_bset() vx_info_cap_bset(current_vx_info())
d337f35e 9270+
d33d7b00
AM
9271+#if 0
9272+#define vx_info_mbcap(v, b) \
9273+ (!vx_info_flags(v, VXF_STATE_SETUP, 0) ? \
9274+ vx_info_bcaps(v, b) : (b))
d337f35e 9275+
d33d7b00
AM
9276+#define task_vx_mbcap(t, b) \
9277+ vx_info_mbcap((t)->vx_info, (t)->b)
9278+
9279+#define vx_mbcap(b) task_vx_mbcap(current, b)
3bac966d 9280+#endif
d337f35e 9281+
d33d7b00 9282+#define vx_cap_raised(v, c, f) cap_raised(vx_info_mbcaps(v, c), f)
d337f35e 9283+
d33d7b00
AM
9284+#define vx_capable(b, c) (capable(b) || \
9285+ (cap_raised(current_cap(), b) && vx_ccaps(c)))
d337f35e 9286+
763640ca
JR
9287+#define vx_ns_capable(n, b, c) (ns_capable(n, b) || \
9288+ (cap_raised(current_cap(), b) && vx_ccaps(c)))
9289+
d33d7b00
AM
9290+#define nx_capable(b, c) (capable(b) || \
9291+ (cap_raised(current_cap(), b) && nx_ncaps(c)))
d337f35e 9292+
c2e5f7c8
JR
9293+#define nx_ns_capable(n, b, c) (ns_capable(n, b) || \
9294+ (cap_raised(current_cap(), b) && nx_ncaps(c)))
9295+
d33d7b00
AM
9296+#define vx_task_initpid(t, n) \
9297+ ((t)->vx_info && \
9298+ ((t)->vx_info->vx_initpid == (n)))
d337f35e 9299+
d33d7b00 9300+#define vx_current_initpid(n) vx_task_initpid(current, n)
d337f35e 9301+
d337f35e 9302+
d33d7b00 9303+/* context unshare mask */
d337f35e 9304+
d33d7b00 9305+#define __vx_umask(v) ((v)->vx_umask)
7e46296a 9306+
d33d7b00 9307+#define vx_current_umask() __vx_umask(current_vx_info())
7e46296a 9308+
d33d7b00
AM
9309+#define vx_can_unshare(b, f) (capable(b) || \
9310+ (cap_raised(current_cap(), b) && \
9311+ !((f) & ~vx_current_umask())))
7e46296a 9312+
b00e13aa
AM
9313+#define vx_ns_can_unshare(n, b, f) (ns_capable(n, b) || \
9314+ (cap_raised(current_cap(), b) && \
9315+ !((f) & ~vx_current_umask())))
7e46296a 9316+
265d6dcc
JR
9317+#define __vx_wmask(v) ((v)->vx_wmask)
9318+
9319+#define vx_current_wmask() __vx_wmask(current_vx_info())
9320+
9321+
d33d7b00 9322+#define __vx_state(v) ((v) ? ((v)->vx_state) : 0)
7e46296a 9323+
d33d7b00 9324+#define vx_info_state(v, m) (__vx_state(v) & (m))
d337f35e 9325+
d337f35e 9326+
d33d7b00 9327+#define __nx_state(n) ((n) ? ((n)->nx_state) : 0)
d337f35e 9328+
d33d7b00 9329+#define nx_info_state(n, m) (__nx_state(n) & (m))
d337f35e 9330+
d33d7b00 9331+#endif
8de2f54c 9332diff -NurpP --minimal linux-4.4.111/include/linux/vserver/cacct.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/cacct.h
f19bd705 9333--- linux-4.4.111/include/linux/vserver/cacct.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9334+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/cacct.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00 9335@@ -0,0 +1,15 @@
4bf69007
AM
9336+#ifndef _VSERVER_CACCT_H
9337+#define _VSERVER_CACCT_H
d337f35e 9338+
d337f35e 9339+
d33d7b00
AM
9340+enum sock_acc_field {
9341+ VXA_SOCK_UNSPEC = 0,
9342+ VXA_SOCK_UNIX,
9343+ VXA_SOCK_INET,
9344+ VXA_SOCK_INET6,
9345+ VXA_SOCK_PACKET,
9346+ VXA_SOCK_OTHER,
9347+ VXA_SOCK_SIZE /* array size */
9348+};
d337f35e 9349+
4bf69007 9350+#endif /* _VSERVER_CACCT_H */
8de2f54c 9351diff -NurpP --minimal linux-4.4.111/include/linux/vserver/cacct_cmd.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/cacct_cmd.h
f19bd705 9352--- linux-4.4.111/include/linux/vserver/cacct_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9353+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/cacct_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9354@@ -0,0 +1,10 @@
9355+#ifndef _VSERVER_CACCT_CMD_H
9356+#define _VSERVER_CACCT_CMD_H
d337f35e 9357+
d337f35e 9358+
3bac966d 9359+#include <linux/compiler.h>
4bf69007 9360+#include <uapi/vserver/cacct_cmd.h>
d337f35e 9361+
d33d7b00 9362+extern int vc_sock_stat(struct vx_info *, void __user *);
d337f35e 9363+
4bf69007 9364+#endif /* _VSERVER_CACCT_CMD_H */
8de2f54c 9365diff -NurpP --minimal linux-4.4.111/include/linux/vserver/cacct_def.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/cacct_def.h
f19bd705 9366--- linux-4.4.111/include/linux/vserver/cacct_def.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9367+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/cacct_def.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00 9368@@ -0,0 +1,43 @@
4bf69007
AM
9369+#ifndef _VSERVER_CACCT_DEF_H
9370+#define _VSERVER_CACCT_DEF_H
d337f35e 9371+
d33d7b00
AM
9372+#include <asm/atomic.h>
9373+#include <linux/vserver/cacct.h>
d337f35e
JR
9374+
9375+
d33d7b00
AM
9376+struct _vx_sock_acc {
9377+ atomic_long_t count;
9378+ atomic_long_t total;
9379+};
d337f35e 9380+
d33d7b00 9381+/* context sub struct */
d337f35e 9382+
d33d7b00
AM
9383+struct _vx_cacct {
9384+ struct _vx_sock_acc sock[VXA_SOCK_SIZE][3];
9385+ atomic_t slab[8];
9386+ atomic_t page[6][8];
9387+};
d337f35e 9388+
d33d7b00 9389+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 9390+
d33d7b00
AM
9391+static inline void __dump_vx_cacct(struct _vx_cacct *cacct)
9392+{
9393+ int i, j;
d337f35e 9394+
d33d7b00
AM
9395+ printk("\t_vx_cacct:");
9396+ for (i = 0; i < 6; i++) {
9397+ struct _vx_sock_acc *ptr = cacct->sock[i];
d337f35e 9398+
d33d7b00
AM
9399+ printk("\t [%d] =", i);
9400+ for (j = 0; j < 3; j++) {
9401+ printk(" [%d] = %8lu, %8lu", j,
9402+ atomic_long_read(&ptr[j].count),
9403+ atomic_long_read(&ptr[j].total));
9404+ }
9405+ printk("\n");
9406+ }
9407+}
2380c486 9408+
d33d7b00 9409+#endif
d337f35e 9410+
4bf69007 9411+#endif /* _VSERVER_CACCT_DEF_H */
8de2f54c 9412diff -NurpP --minimal linux-4.4.111/include/linux/vserver/cacct_int.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/cacct_int.h
f19bd705 9413--- linux-4.4.111/include/linux/vserver/cacct_int.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9414+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/cacct_int.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9415@@ -0,0 +1,17 @@
9416+#ifndef _VSERVER_CACCT_INT_H
9417+#define _VSERVER_CACCT_INT_H
d337f35e 9418+
d33d7b00
AM
9419+static inline
9420+unsigned long vx_sock_count(struct _vx_cacct *cacct, int type, int pos)
9421+{
9422+ return atomic_long_read(&cacct->sock[type][pos].count);
9423+}
d337f35e 9424+
d337f35e 9425+
d33d7b00
AM
9426+static inline
9427+unsigned long vx_sock_total(struct _vx_cacct *cacct, int type, int pos)
9428+{
9429+ return atomic_long_read(&cacct->sock[type][pos].total);
9430+}
d337f35e 9431+
4bf69007 9432+#endif /* _VSERVER_CACCT_INT_H */
8de2f54c 9433diff -NurpP --minimal linux-4.4.111/include/linux/vserver/check.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/check.h
f19bd705 9434--- linux-4.4.111/include/linux/vserver/check.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9435+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/check.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00 9436@@ -0,0 +1,89 @@
4bf69007
AM
9437+#ifndef _VSERVER_CHECK_H
9438+#define _VSERVER_CHECK_H
d337f35e 9439+
d337f35e 9440+
d33d7b00 9441+#define MAX_S_CONTEXT 65535 /* Arbitrary limit */
d337f35e 9442+
d33d7b00
AM
9443+#ifdef CONFIG_VSERVER_DYNAMIC_IDS
9444+#define MIN_D_CONTEXT 49152 /* dynamic contexts start here */
9445+#else
9446+#define MIN_D_CONTEXT 65536
9447+#endif
d337f35e 9448+
d33d7b00 9449+/* check conditions */
d337f35e 9450+
d33d7b00
AM
9451+#define VS_ADMIN 0x0001
9452+#define VS_WATCH 0x0002
9453+#define VS_HIDE 0x0004
9454+#define VS_HOSTID 0x0008
d337f35e 9455+
d33d7b00
AM
9456+#define VS_IDENT 0x0010
9457+#define VS_EQUIV 0x0020
9458+#define VS_PARENT 0x0040
9459+#define VS_CHILD 0x0080
d337f35e 9460+
d33d7b00 9461+#define VS_ARG_MASK 0x00F0
d337f35e 9462+
d33d7b00
AM
9463+#define VS_DYNAMIC 0x0100
9464+#define VS_STATIC 0x0200
d337f35e 9465+
d33d7b00 9466+#define VS_ATR_MASK 0x0F00
d337f35e 9467+
d33d7b00
AM
9468+#ifdef CONFIG_VSERVER_PRIVACY
9469+#define VS_ADMIN_P (0)
9470+#define VS_WATCH_P (0)
9471+#else
9472+#define VS_ADMIN_P VS_ADMIN
9473+#define VS_WATCH_P VS_WATCH
9474+#endif
d337f35e 9475+
d33d7b00
AM
9476+#define VS_HARDIRQ 0x1000
9477+#define VS_SOFTIRQ 0x2000
9478+#define VS_IRQ 0x4000
d337f35e 9479+
d33d7b00 9480+#define VS_IRQ_MASK 0xF000
d337f35e 9481+
d33d7b00 9482+#include <linux/hardirq.h>
d337f35e 9483+
d33d7b00
AM
9484+/*
9485+ * check current context for ADMIN/WATCH and
9486+ * optionally against supplied argument
9487+ */
9488+static inline int __vs_check(int cid, int id, unsigned int mode)
9489+{
9490+ if (mode & VS_ARG_MASK) {
9491+ if ((mode & VS_IDENT) && (id == cid))
9492+ return 1;
9493+ }
9494+ if (mode & VS_ATR_MASK) {
9495+ if ((mode & VS_DYNAMIC) &&
9496+ (id >= MIN_D_CONTEXT) &&
9497+ (id <= MAX_S_CONTEXT))
9498+ return 1;
9499+ if ((mode & VS_STATIC) &&
9500+ (id > 1) && (id < MIN_D_CONTEXT))
9501+ return 1;
9502+ }
9503+ if (mode & VS_IRQ_MASK) {
9504+ if ((mode & VS_IRQ) && unlikely(in_interrupt()))
9505+ return 1;
9506+ if ((mode & VS_HARDIRQ) && unlikely(in_irq()))
9507+ return 1;
9508+ if ((mode & VS_SOFTIRQ) && unlikely(in_softirq()))
9509+ return 1;
9510+ }
9511+ return (((mode & VS_ADMIN) && (cid == 0)) ||
9512+ ((mode & VS_WATCH) && (cid == 1)) ||
9513+ ((mode & VS_HOSTID) && (id == 0)));
9514+}
d337f35e 9515+
d33d7b00 9516+#define vx_check(c, m) __vs_check(vx_current_xid(), c, (m) | VS_IRQ)
d337f35e 9517+
d33d7b00 9518+#define vx_weak_check(c, m) ((m) ? vx_check(c, m) : 1)
2380c486 9519+
d337f35e 9520+
d33d7b00 9521+#define nx_check(c, m) __vs_check(nx_current_nid(), c, m)
d337f35e 9522+
d33d7b00 9523+#define nx_weak_check(c, m) ((m) ? nx_check(c, m) : 1)
d337f35e 9524+
d33d7b00 9525+#endif
8de2f54c 9526diff -NurpP --minimal linux-4.4.111/include/linux/vserver/context.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/context.h
f19bd705 9527--- linux-4.4.111/include/linux/vserver/context.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9528+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/context.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9529@@ -0,0 +1,110 @@
9530+#ifndef _VSERVER_CONTEXT_H
9531+#define _VSERVER_CONTEXT_H
d337f35e
JR
9532+
9533+
d33d7b00
AM
9534+#include <linux/list.h>
9535+#include <linux/spinlock.h>
9536+#include <linux/rcupdate.h>
4bf69007 9537+#include <uapi/vserver/context.h>
d337f35e 9538+
d33d7b00
AM
9539+#include "limit_def.h"
9540+#include "sched_def.h"
9541+#include "cvirt_def.h"
9542+#include "cacct_def.h"
9543+#include "device_def.h"
d337f35e 9544+
d33d7b00 9545+#define VX_SPACES 2
d337f35e 9546+
d33d7b00
AM
9547+struct _vx_info_pc {
9548+ struct _vx_sched_pc sched_pc;
9549+ struct _vx_cvirt_pc cvirt_pc;
9550+};
d337f35e 9551+
d33d7b00
AM
9552+struct _vx_space {
9553+ unsigned long vx_nsmask; /* assignment mask */
9554+ struct nsproxy *vx_nsproxy; /* private namespaces */
9555+ struct fs_struct *vx_fs; /* private namespace fs */
9556+ const struct cred *vx_cred; /* task credentials */
9557+};
d337f35e 9558+
d33d7b00
AM
9559+struct vx_info {
9560+ struct hlist_node vx_hlist; /* linked list of contexts */
61333608 9561+ vxid_t vx_id; /* context id */
d33d7b00
AM
9562+ atomic_t vx_usecnt; /* usage count */
9563+ atomic_t vx_tasks; /* tasks count */
9564+ struct vx_info *vx_parent; /* parent context */
9565+ int vx_state; /* context state */
d337f35e 9566+
d33d7b00 9567+ struct _vx_space space[VX_SPACES]; /* namespace store */
d337f35e 9568+
d33d7b00
AM
9569+ uint64_t vx_flags; /* context flags */
9570+ uint64_t vx_ccaps; /* context caps (vserver) */
763640ca 9571+ uint64_t vx_umask; /* unshare mask (guest) */
265d6dcc 9572+ uint64_t vx_wmask; /* warn mask (guest) */
d33d7b00 9573+ kernel_cap_t vx_bcaps; /* bounding caps (system) */
d337f35e 9574+
d33d7b00
AM
9575+ struct task_struct *vx_reaper; /* guest reaper process */
9576+ pid_t vx_initpid; /* PID of guest init */
9577+ int64_t vx_badness_bias; /* OOM points bias */
d337f35e 9578+
d33d7b00
AM
9579+ struct _vx_limit limit; /* vserver limits */
9580+ struct _vx_sched sched; /* vserver scheduler */
9581+ struct _vx_cvirt cvirt; /* virtual/bias stuff */
9582+ struct _vx_cacct cacct; /* context accounting */
d337f35e 9583+
d33d7b00 9584+ struct _vx_device dmap; /* default device map targets */
d337f35e 9585+
d33d7b00
AM
9586+#ifndef CONFIG_SMP
9587+ struct _vx_info_pc info_pc; /* per cpu data */
9588+#else
9589+ struct _vx_info_pc *ptr_pc; /* per cpu array */
9590+#endif
d337f35e 9591+
d33d7b00
AM
9592+ wait_queue_head_t vx_wait; /* context exit waitqueue */
9593+ int reboot_cmd; /* last sys_reboot() cmd */
9594+ int exit_code; /* last process exit code */
d337f35e 9595+
d33d7b00
AM
9596+ char vx_name[65]; /* vserver name */
9597+};
d337f35e 9598+
d33d7b00
AM
9599+#ifndef CONFIG_SMP
9600+#define vx_ptr_pc(vxi) (&(vxi)->info_pc)
9601+#define vx_per_cpu(vxi, v, id) vx_ptr_pc(vxi)->v
9602+#else
9603+#define vx_ptr_pc(vxi) ((vxi)->ptr_pc)
9604+#define vx_per_cpu(vxi, v, id) per_cpu_ptr(vx_ptr_pc(vxi), id)->v
9605+#endif
d337f35e 9606+
d33d7b00 9607+#define vx_cpu(vxi, v) vx_per_cpu(vxi, v, smp_processor_id())
d337f35e 9608+
d337f35e 9609+
d33d7b00
AM
9610+struct vx_info_save {
9611+ struct vx_info *vxi;
61333608 9612+ vxid_t xid;
d33d7b00 9613+};
d337f35e
JR
9614+
9615+
d33d7b00 9616+/* status flags */
d337f35e 9617+
d33d7b00
AM
9618+#define VXS_HASHED 0x0001
9619+#define VXS_PAUSED 0x0010
9620+#define VXS_SHUTDOWN 0x0100
9621+#define VXS_HELPER 0x1000
9622+#define VXS_RELEASED 0x8000
d337f35e 9623+
d337f35e 9624+
d33d7b00
AM
9625+extern void claim_vx_info(struct vx_info *, struct task_struct *);
9626+extern void release_vx_info(struct vx_info *, struct task_struct *);
adc1caaa 9627+
d33d7b00
AM
9628+extern struct vx_info *lookup_vx_info(int);
9629+extern struct vx_info *lookup_or_create_vx_info(int);
d337f35e 9630+
d33d7b00 9631+extern int get_xid_list(int, unsigned int *, int);
61333608 9632+extern int xid_is_hashed(vxid_t);
d337f35e 9633+
d33d7b00 9634+extern int vx_migrate_task(struct task_struct *, struct vx_info *, int);
d337f35e 9635+
d33d7b00 9636+extern long vs_state_change(struct vx_info *, unsigned int);
d337f35e 9637+
d337f35e 9638+
4bf69007 9639+#endif /* _VSERVER_CONTEXT_H */
8de2f54c 9640diff -NurpP --minimal linux-4.4.111/include/linux/vserver/context_cmd.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/context_cmd.h
f19bd705 9641--- linux-4.4.111/include/linux/vserver/context_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9642+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/context_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9643@@ -0,0 +1,33 @@
9644+#ifndef _VSERVER_CONTEXT_CMD_H
9645+#define _VSERVER_CONTEXT_CMD_H
d337f35e 9646+
4bf69007 9647+#include <uapi/vserver/context_cmd.h>
d337f35e 9648+
d33d7b00 9649+extern int vc_task_xid(uint32_t);
d337f35e 9650+
d33d7b00 9651+extern int vc_vx_info(struct vx_info *, void __user *);
d337f35e 9652+
d33d7b00 9653+extern int vc_ctx_stat(struct vx_info *, void __user *);
d337f35e 9654+
4bf69007
AM
9655+extern int vc_ctx_create(uint32_t, void __user *);
9656+extern int vc_ctx_migrate(struct vx_info *, void __user *);
d337f35e 9657+
4bf69007
AM
9658+extern int vc_get_cflags(struct vx_info *, void __user *);
9659+extern int vc_set_cflags(struct vx_info *, void __user *);
d337f35e 9660+
4bf69007
AM
9661+extern int vc_get_ccaps(struct vx_info *, void __user *);
9662+extern int vc_set_ccaps(struct vx_info *, void __user *);
d337f35e 9663+
4bf69007
AM
9664+extern int vc_get_bcaps(struct vx_info *, void __user *);
9665+extern int vc_set_bcaps(struct vx_info *, void __user *);
d337f35e 9666+
4bf69007
AM
9667+extern int vc_get_umask(struct vx_info *, void __user *);
9668+extern int vc_set_umask(struct vx_info *, void __user *);
d33d7b00 9669+
4bf69007
AM
9670+extern int vc_get_wmask(struct vx_info *, void __user *);
9671+extern int vc_set_wmask(struct vx_info *, void __user *);
d33d7b00 9672+
4bf69007
AM
9673+extern int vc_get_badness(struct vx_info *, void __user *);
9674+extern int vc_set_badness(struct vx_info *, void __user *);
d337f35e 9675+
4bf69007 9676+#endif /* _VSERVER_CONTEXT_CMD_H */
8de2f54c 9677diff -NurpP --minimal linux-4.4.111/include/linux/vserver/cvirt.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/cvirt.h
f19bd705 9678--- linux-4.4.111/include/linux/vserver/cvirt.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9679+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/cvirt.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9680@@ -0,0 +1,18 @@
9681+#ifndef _VSERVER_CVIRT_H
9682+#define _VSERVER_CVIRT_H
d337f35e 9683+
4bf69007 9684+struct timespec;
d337f35e 9685+
4bf69007 9686+void vx_vsi_boottime(struct timespec *);
d337f35e 9687+
4bf69007 9688+void vx_vsi_uptime(struct timespec *, struct timespec *);
d337f35e 9689+
d337f35e 9690+
4bf69007 9691+struct vx_info;
d337f35e 9692+
4bf69007 9693+void vx_update_load(struct vx_info *);
d337f35e 9694+
d337f35e 9695+
4bf69007 9696+int vx_do_syslog(int, char __user *, int);
d337f35e 9697+
4bf69007 9698+#endif /* _VSERVER_CVIRT_H */
8de2f54c 9699diff -NurpP --minimal linux-4.4.111/include/linux/vserver/cvirt_cmd.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/cvirt_cmd.h
f19bd705 9700--- linux-4.4.111/include/linux/vserver/cvirt_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9701+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/cvirt_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9702@@ -0,0 +1,13 @@
9703+#ifndef _VSERVER_CVIRT_CMD_H
9704+#define _VSERVER_CVIRT_CMD_H
d337f35e 9705+
d337f35e 9706+
4bf69007
AM
9707+#include <linux/compiler.h>
9708+#include <uapi/vserver/cvirt_cmd.h>
d337f35e 9709+
4bf69007
AM
9710+extern int vc_set_vhi_name(struct vx_info *, void __user *);
9711+extern int vc_get_vhi_name(struct vx_info *, void __user *);
d337f35e 9712+
4bf69007 9713+extern int vc_virt_stat(struct vx_info *, void __user *);
d337f35e 9714+
4bf69007 9715+#endif /* _VSERVER_CVIRT_CMD_H */
8de2f54c 9716diff -NurpP --minimal linux-4.4.111/include/linux/vserver/cvirt_def.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/cvirt_def.h
f19bd705 9717--- linux-4.4.111/include/linux/vserver/cvirt_def.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9718+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/cvirt_def.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9719@@ -0,0 +1,80 @@
9720+#ifndef _VSERVER_CVIRT_DEF_H
9721+#define _VSERVER_CVIRT_DEF_H
d337f35e 9722+
d33d7b00
AM
9723+#include <linux/jiffies.h>
9724+#include <linux/spinlock.h>
9725+#include <linux/wait.h>
9726+#include <linux/time.h>
9727+#include <asm/atomic.h>
d337f35e 9728+
d337f35e 9729+
d33d7b00
AM
9730+struct _vx_usage_stat {
9731+ uint64_t user;
9732+ uint64_t nice;
9733+ uint64_t system;
9734+ uint64_t softirq;
9735+ uint64_t irq;
9736+ uint64_t idle;
9737+ uint64_t iowait;
9738+};
d337f35e 9739+
d33d7b00
AM
9740+struct _vx_syslog {
9741+ wait_queue_head_t log_wait;
9742+ spinlock_t logbuf_lock; /* lock for the log buffer */
d337f35e 9743+
d33d7b00
AM
9744+ unsigned long log_start; /* next char to be read by syslog() */
9745+ unsigned long con_start; /* next char to be sent to consoles */
9746+ unsigned long log_end; /* most-recently-written-char + 1 */
9747+ unsigned long logged_chars; /* #chars since last read+clear operation */
d337f35e 9748+
d33d7b00
AM
9749+ char log_buf[1024];
9750+};
d337f35e 9751+
d337f35e 9752+
d33d7b00 9753+/* context sub struct */
d337f35e 9754+
d33d7b00
AM
9755+struct _vx_cvirt {
9756+ atomic_t nr_threads; /* number of current threads */
9757+ atomic_t nr_running; /* number of running threads */
9758+ atomic_t nr_uninterruptible; /* number of uninterruptible threads */
d337f35e 9759+
d33d7b00
AM
9760+ atomic_t nr_onhold; /* processes on hold */
9761+ uint32_t onhold_last; /* jiffies when put on hold */
d337f35e 9762+
d33d7b00
AM
9763+ struct timespec bias_ts; /* time offset to the host */
9764+ struct timespec bias_idle;
9765+ struct timespec bias_uptime; /* context creation point */
9766+ uint64_t bias_clock; /* offset in clock_t */
3bac966d 9767+
d33d7b00
AM
9768+ spinlock_t load_lock; /* lock for the load averages */
9769+ atomic_t load_updates; /* nr of load updates done so far */
9770+ uint32_t load_last; /* last time load was calculated */
9771+ uint32_t load[3]; /* load averages 1,5,15 */
d337f35e 9772+
d33d7b00 9773+ atomic_t total_forks; /* number of forks so far */
d337f35e 9774+
d33d7b00
AM
9775+ struct _vx_syslog syslog;
9776+};
d337f35e 9777+
d33d7b00
AM
9778+struct _vx_cvirt_pc {
9779+ struct _vx_usage_stat cpustat;
9780+};
3bac966d 9781+
d337f35e 9782+
d33d7b00 9783+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 9784+
d33d7b00 9785+static inline void __dump_vx_cvirt(struct _vx_cvirt *cvirt)
3bac966d 9786+{
d33d7b00
AM
9787+ printk("\t_vx_cvirt:\n");
9788+ printk("\t threads: %4d, %4d, %4d, %4d\n",
9789+ atomic_read(&cvirt->nr_threads),
9790+ atomic_read(&cvirt->nr_running),
9791+ atomic_read(&cvirt->nr_uninterruptible),
9792+ atomic_read(&cvirt->nr_onhold));
9793+ /* add rest here */
9794+ printk("\t total_forks = %d\n", atomic_read(&cvirt->total_forks));
3bac966d 9795+}
d337f35e 9796+
d33d7b00 9797+#endif
d337f35e 9798+
4bf69007 9799+#endif /* _VSERVER_CVIRT_DEF_H */
8de2f54c 9800diff -NurpP --minimal linux-4.4.111/include/linux/vserver/debug.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/debug.h
f19bd705 9801--- linux-4.4.111/include/linux/vserver/debug.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9802+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/debug.h 2018-01-09 16:36:32.000000000 +0000
a4a22af8 9803@@ -0,0 +1,146 @@
4bf69007
AM
9804+#ifndef _VSERVER_DEBUG_H
9805+#define _VSERVER_DEBUG_H
d337f35e 9806+
d337f35e 9807+
dd5f3080 9808+#define VXD_CBIT(n, m) (vs_debug_ ## n & (1 << (m)))
9809+#define VXD_CMIN(n, m) (vs_debug_ ## n > (m))
9810+#define VXD_MASK(n, m) (vs_debug_ ## n & (m))
d337f35e 9811+
d33d7b00
AM
9812+#define VXD_DEV(d) (d), (d)->bd_inode->i_ino, \
9813+ imajor((d)->bd_inode), iminor((d)->bd_inode)
9814+#define VXF_DEV "%p[%lu,%d:%d]"
d337f35e 9815+
d33d7b00
AM
9816+#if defined(CONFIG_QUOTES_UTF8)
9817+#define VS_Q_LQM "\xc2\xbb"
9818+#define VS_Q_RQM "\xc2\xab"
9819+#elif defined(CONFIG_QUOTES_ASCII)
9820+#define VS_Q_LQM "\x27"
9821+#define VS_Q_RQM "\x27"
9822+#else
9823+#define VS_Q_LQM "\xbb"
9824+#define VS_Q_RQM "\xab"
9825+#endif
d337f35e 9826+
d33d7b00 9827+#define VS_Q(f) VS_Q_LQM f VS_Q_RQM
d337f35e
JR
9828+
9829+
d33d7b00
AM
9830+#define vxd_path(p) \
9831+ ({ static char _buffer[PATH_MAX]; \
9832+ d_path(p, _buffer, sizeof(_buffer)); })
d337f35e 9833+
d33d7b00
AM
9834+#define vxd_cond_path(n) \
9835+ ((n) ? vxd_path(&(n)->path) : "<null>" )
d337f35e 9836+
d337f35e 9837+
d33d7b00 9838+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 9839+
dd5f3080 9840+extern unsigned int vs_debug_switch;
9841+extern unsigned int vs_debug_xid;
9842+extern unsigned int vs_debug_nid;
9843+extern unsigned int vs_debug_tag;
9844+extern unsigned int vs_debug_net;
9845+extern unsigned int vs_debug_limit;
9846+extern unsigned int vs_debug_cres;
9847+extern unsigned int vs_debug_dlim;
9848+extern unsigned int vs_debug_quota;
9849+extern unsigned int vs_debug_cvirt;
9850+extern unsigned int vs_debug_space;
9851+extern unsigned int vs_debug_perm;
9852+extern unsigned int vs_debug_misc;
d337f35e 9853+
d337f35e 9854+
d33d7b00
AM
9855+#define VX_LOGLEVEL "vxD: "
9856+#define VX_PROC_FMT "%p: "
9857+#define VX_PROCESS current
d337f35e 9858+
d33d7b00
AM
9859+#define vxdprintk(c, f, x...) \
9860+ do { \
9861+ if (c) \
9862+ printk(VX_LOGLEVEL VX_PROC_FMT f "\n", \
9863+ VX_PROCESS , ##x); \
9864+ } while (0)
d337f35e 9865+
d33d7b00
AM
9866+#define vxlprintk(c, f, x...) \
9867+ do { \
9868+ if (c) \
9869+ printk(VX_LOGLEVEL f " @%s:%d\n", x); \
9870+ } while (0)
d337f35e 9871+
d33d7b00
AM
9872+#define vxfprintk(c, f, x...) \
9873+ do { \
9874+ if (c) \
9875+ printk(VX_LOGLEVEL f " %s@%s:%d\n", x); \
9876+ } while (0)
d337f35e 9877+
d337f35e 9878+
d33d7b00 9879+struct vx_info;
d337f35e 9880+
d33d7b00
AM
9881+void dump_vx_info(struct vx_info *, int);
9882+void dump_vx_info_inactive(int);
d337f35e 9883+
d33d7b00 9884+#else /* CONFIG_VSERVER_DEBUG */
d337f35e 9885+
dd5f3080 9886+#define vs_debug_switch 0
9887+#define vs_debug_xid 0
9888+#define vs_debug_nid 0
9889+#define vs_debug_tag 0
9890+#define vs_debug_net 0
9891+#define vs_debug_limit 0
9892+#define vs_debug_cres 0
9893+#define vs_debug_dlim 0
9894+#define vs_debug_quota 0
9895+#define vs_debug_cvirt 0
9896+#define vs_debug_space 0
9897+#define vs_debug_perm 0
9898+#define vs_debug_misc 0
d337f35e 9899+
d33d7b00
AM
9900+#define vxdprintk(x...) do { } while (0)
9901+#define vxlprintk(x...) do { } while (0)
9902+#define vxfprintk(x...) do { } while (0)
2380c486 9903+
d33d7b00 9904+#endif /* CONFIG_VSERVER_DEBUG */
2380c486 9905+
d337f35e 9906+
d33d7b00 9907+#ifdef CONFIG_VSERVER_WARN
d337f35e 9908+
d33d7b00
AM
9909+#define VX_WARNLEVEL KERN_WARNING "vxW: "
9910+#define VX_WARN_TASK "[" VS_Q("%s") ",%u:#%u|%u|%u] "
9911+#define VX_WARN_XID "[xid #%u] "
9912+#define VX_WARN_NID "[nid #%u] "
9913+#define VX_WARN_TAG "[tag #%u] "
d337f35e 9914+
d33d7b00
AM
9915+#define vxwprintk(c, f, x...) \
9916+ do { \
9917+ if (c) \
9918+ printk(VX_WARNLEVEL f "\n", ##x); \
9919+ } while (0)
d337f35e 9920+
d33d7b00 9921+#else /* CONFIG_VSERVER_WARN */
d337f35e 9922+
d33d7b00 9923+#define vxwprintk(x...) do { } while (0)
d337f35e 9924+
d33d7b00 9925+#endif /* CONFIG_VSERVER_WARN */
d337f35e 9926+
d33d7b00
AM
9927+#define vxwprintk_task(c, f, x...) \
9928+ vxwprintk(c, VX_WARN_TASK f, \
9929+ current->comm, current->pid, \
a4a22af8
AM
9930+ current->xid, current->nid, \
9931+ current->tag, ##x)
d33d7b00
AM
9932+#define vxwprintk_xid(c, f, x...) \
9933+ vxwprintk(c, VX_WARN_XID f, current->xid, x)
9934+#define vxwprintk_nid(c, f, x...) \
9935+ vxwprintk(c, VX_WARN_NID f, current->nid, x)
9936+#define vxwprintk_tag(c, f, x...) \
9937+ vxwprintk(c, VX_WARN_TAG f, current->tag, x)
d337f35e 9938+
d33d7b00
AM
9939+#ifdef CONFIG_VSERVER_DEBUG
9940+#define vxd_assert_lock(l) assert_spin_locked(l)
9941+#define vxd_assert(c, f, x...) vxlprintk(!(c), \
9942+ "assertion [" f "] failed.", ##x, __FILE__, __LINE__)
9943+#else
9944+#define vxd_assert_lock(l) do { } while (0)
9945+#define vxd_assert(c, f, x...) do { } while (0)
9946+#endif
d337f35e 9947+
d337f35e 9948+
4bf69007 9949+#endif /* _VSERVER_DEBUG_H */
8de2f54c 9950diff -NurpP --minimal linux-4.4.111/include/linux/vserver/debug_cmd.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/debug_cmd.h
f19bd705 9951--- linux-4.4.111/include/linux/vserver/debug_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9952+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/debug_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9953@@ -0,0 +1,37 @@
9954+#ifndef _VSERVER_DEBUG_CMD_H
9955+#define _VSERVER_DEBUG_CMD_H
d337f35e 9956+
4bf69007 9957+#include <uapi/vserver/debug_cmd.h>
d337f35e
JR
9958+
9959+
d33d7b00 9960+#ifdef CONFIG_COMPAT
d337f35e 9961+
d33d7b00 9962+#include <asm/compat.h>
d337f35e 9963+
d33d7b00
AM
9964+struct vcmd_read_history_v0_x32 {
9965+ uint32_t index;
9966+ uint32_t count;
9967+ compat_uptr_t data_ptr;
3bac966d 9968+};
d337f35e 9969+
d33d7b00
AM
9970+struct vcmd_read_monitor_v0_x32 {
9971+ uint32_t index;
9972+ uint32_t count;
9973+ compat_uptr_t data_ptr;
3bac966d 9974+};
d337f35e 9975+
d33d7b00 9976+#endif /* CONFIG_COMPAT */
d337f35e 9977+
d33d7b00 9978+extern int vc_dump_history(uint32_t);
d337f35e 9979+
d33d7b00
AM
9980+extern int vc_read_history(uint32_t, void __user *);
9981+extern int vc_read_monitor(uint32_t, void __user *);
d337f35e 9982+
d33d7b00 9983+#ifdef CONFIG_COMPAT
d337f35e 9984+
d33d7b00
AM
9985+extern int vc_read_history_x32(uint32_t, void __user *);
9986+extern int vc_read_monitor_x32(uint32_t, void __user *);
d337f35e 9987+
d33d7b00 9988+#endif /* CONFIG_COMPAT */
d337f35e 9989+
4bf69007 9990+#endif /* _VSERVER_DEBUG_CMD_H */
8de2f54c 9991diff -NurpP --minimal linux-4.4.111/include/linux/vserver/device.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/device.h
f19bd705 9992--- linux-4.4.111/include/linux/vserver/device.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 9993+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/device.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9994@@ -0,0 +1,9 @@
9995+#ifndef _VSERVER_DEVICE_H
9996+#define _VSERVER_DEVICE_H
d337f35e 9997+
d337f35e 9998+
4bf69007 9999+#include <uapi/vserver/device.h>
d337f35e 10000+
4bf69007 10001+#else /* _VSERVER_DEVICE_H */
d33d7b00 10002+#warning duplicate inclusion
4bf69007 10003+#endif /* _VSERVER_DEVICE_H */
8de2f54c 10004diff -NurpP --minimal linux-4.4.111/include/linux/vserver/device_cmd.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/device_cmd.h
f19bd705 10005--- linux-4.4.111/include/linux/vserver/device_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10006+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/device_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10007@@ -0,0 +1,31 @@
10008+#ifndef _VSERVER_DEVICE_CMD_H
10009+#define _VSERVER_DEVICE_CMD_H
d337f35e 10010+
4bf69007 10011+#include <uapi/vserver/device_cmd.h>
d337f35e 10012+
d337f35e 10013+
d33d7b00 10014+#ifdef CONFIG_COMPAT
d337f35e 10015+
d33d7b00 10016+#include <asm/compat.h>
3bac966d 10017+
d33d7b00
AM
10018+struct vcmd_set_mapping_v0_x32 {
10019+ compat_uptr_t device_ptr;
10020+ compat_uptr_t target_ptr;
10021+ uint32_t flags;
d337f35e
JR
10022+};
10023+
d33d7b00 10024+#endif /* CONFIG_COMPAT */
d337f35e 10025+
d33d7b00 10026+#include <linux/compiler.h>
d337f35e 10027+
d33d7b00
AM
10028+extern int vc_set_mapping(struct vx_info *, void __user *);
10029+extern int vc_unset_mapping(struct vx_info *, void __user *);
d337f35e 10030+
d33d7b00 10031+#ifdef CONFIG_COMPAT
d337f35e 10032+
d33d7b00
AM
10033+extern int vc_set_mapping_x32(struct vx_info *, void __user *);
10034+extern int vc_unset_mapping_x32(struct vx_info *, void __user *);
d337f35e 10035+
d33d7b00 10036+#endif /* CONFIG_COMPAT */
d337f35e 10037+
4bf69007 10038+#endif /* _VSERVER_DEVICE_CMD_H */
8de2f54c 10039diff -NurpP --minimal linux-4.4.111/include/linux/vserver/device_def.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/device_def.h
f19bd705 10040--- linux-4.4.111/include/linux/vserver/device_def.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10041+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/device_def.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00 10042@@ -0,0 +1,17 @@
4bf69007
AM
10043+#ifndef _VSERVER_DEVICE_DEF_H
10044+#define _VSERVER_DEVICE_DEF_H
d337f35e 10045+
d33d7b00 10046+#include <linux/types.h>
d337f35e 10047+
d33d7b00
AM
10048+struct vx_dmap_target {
10049+ dev_t target;
10050+ uint32_t flags;
10051+};
d337f35e 10052+
d33d7b00
AM
10053+struct _vx_device {
10054+#ifdef CONFIG_VSERVER_DEVICE
10055+ struct vx_dmap_target targets[2];
10056+#endif
10057+};
d337f35e 10058+
4bf69007 10059+#endif /* _VSERVER_DEVICE_DEF_H */
8de2f54c 10060diff -NurpP --minimal linux-4.4.111/include/linux/vserver/dlimit.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/dlimit.h
f19bd705 10061--- linux-4.4.111/include/linux/vserver/dlimit.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10062+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/dlimit.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00 10063@@ -0,0 +1,54 @@
4bf69007
AM
10064+#ifndef _VSERVER_DLIMIT_H
10065+#define _VSERVER_DLIMIT_H
d337f35e 10066+
d33d7b00 10067+#include "switch.h"
3bac966d 10068+
d337f35e 10069+
3bac966d 10070+#ifdef __KERNEL__
d337f35e 10071+
d33d7b00 10072+/* keep in sync with CDLIM_INFINITY */
d337f35e 10073+
d33d7b00 10074+#define DLIM_INFINITY (~0ULL)
d337f35e 10075+
d33d7b00
AM
10076+#include <linux/spinlock.h>
10077+#include <linux/rcupdate.h>
d337f35e 10078+
d33d7b00 10079+struct super_block;
d337f35e 10080+
d33d7b00
AM
10081+struct dl_info {
10082+ struct hlist_node dl_hlist; /* linked list of contexts */
10083+ struct rcu_head dl_rcu; /* the rcu head */
61333608 10084+ vtag_t dl_tag; /* context tag */
d33d7b00
AM
10085+ atomic_t dl_usecnt; /* usage count */
10086+ atomic_t dl_refcnt; /* reference count */
d337f35e 10087+
d33d7b00 10088+ struct super_block *dl_sb; /* associated superblock */
d337f35e 10089+
d33d7b00 10090+ spinlock_t dl_lock; /* protect the values */
d337f35e 10091+
d33d7b00
AM
10092+ unsigned long long dl_space_used; /* used space in bytes */
10093+ unsigned long long dl_space_total; /* maximum space in bytes */
10094+ unsigned long dl_inodes_used; /* used inodes */
10095+ unsigned long dl_inodes_total; /* maximum inodes */
d337f35e 10096+
d33d7b00
AM
10097+ unsigned int dl_nrlmult; /* non root limit mult */
10098+};
d337f35e 10099+
d33d7b00 10100+struct rcu_head;
d337f35e 10101+
d33d7b00
AM
10102+extern void rcu_free_dl_info(struct rcu_head *);
10103+extern void unhash_dl_info(struct dl_info *);
d337f35e 10104+
61333608 10105+extern struct dl_info *locate_dl_info(struct super_block *, vtag_t);
d337f35e 10106+
d337f35e 10107+
d33d7b00 10108+struct kstatfs;
d337f35e 10109+
d33d7b00 10110+extern void vx_vsi_statfs(struct super_block *, struct kstatfs *);
d337f35e 10111+
d33d7b00 10112+typedef uint64_t dlsize_t;
d337f35e 10113+
d33d7b00 10114+#endif /* __KERNEL__ */
4bf69007 10115+#else /* _VSERVER_DLIMIT_H */
d33d7b00 10116+#warning duplicate inclusion
4bf69007 10117+#endif /* _VSERVER_DLIMIT_H */
8de2f54c 10118diff -NurpP --minimal linux-4.4.111/include/linux/vserver/dlimit_cmd.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/dlimit_cmd.h
f19bd705 10119--- linux-4.4.111/include/linux/vserver/dlimit_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10120+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/dlimit_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10121@@ -0,0 +1,46 @@
10122+#ifndef _VSERVER_DLIMIT_CMD_H
10123+#define _VSERVER_DLIMIT_CMD_H
d337f35e 10124+
4bf69007 10125+#include <uapi/vserver/dlimit_cmd.h>
d337f35e 10126+
d337f35e 10127+
4bf69007 10128+#ifdef CONFIG_COMPAT
d337f35e 10129+
4bf69007 10130+#include <asm/compat.h>
2380c486 10131+
4bf69007
AM
10132+struct vcmd_ctx_dlimit_base_v0_x32 {
10133+ compat_uptr_t name_ptr;
d33d7b00
AM
10134+ uint32_t flags;
10135+};
adc1caaa 10136+
4bf69007
AM
10137+struct vcmd_ctx_dlimit_v0_x32 {
10138+ compat_uptr_t name_ptr;
d33d7b00
AM
10139+ uint32_t space_used; /* used space in kbytes */
10140+ uint32_t space_total; /* maximum space in kbytes */
10141+ uint32_t inodes_used; /* used inodes */
10142+ uint32_t inodes_total; /* maximum inodes */
10143+ uint32_t reserved; /* reserved for root in % */
10144+ uint32_t flags;
10145+};
d337f35e 10146+
4bf69007 10147+#endif /* CONFIG_COMPAT */
d337f35e 10148+
4bf69007 10149+#include <linux/compiler.h>
d337f35e 10150+
4bf69007
AM
10151+extern int vc_add_dlimit(uint32_t, void __user *);
10152+extern int vc_rem_dlimit(uint32_t, void __user *);
d337f35e 10153+
4bf69007
AM
10154+extern int vc_set_dlimit(uint32_t, void __user *);
10155+extern int vc_get_dlimit(uint32_t, void __user *);
d337f35e 10156+
4bf69007 10157+#ifdef CONFIG_COMPAT
d337f35e 10158+
4bf69007
AM
10159+extern int vc_add_dlimit_x32(uint32_t, void __user *);
10160+extern int vc_rem_dlimit_x32(uint32_t, void __user *);
2380c486 10161+
d33d7b00
AM
10162+extern int vc_set_dlimit_x32(uint32_t, void __user *);
10163+extern int vc_get_dlimit_x32(uint32_t, void __user *);
d337f35e 10164+
d33d7b00 10165+#endif /* CONFIG_COMPAT */
d337f35e 10166+
4bf69007 10167+#endif /* _VSERVER_DLIMIT_CMD_H */
8de2f54c 10168diff -NurpP --minimal linux-4.4.111/include/linux/vserver/global.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/global.h
f19bd705 10169--- linux-4.4.111/include/linux/vserver/global.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10170+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/global.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00 10171@@ -0,0 +1,19 @@
4bf69007
AM
10172+#ifndef _VSERVER_GLOBAL_H
10173+#define _VSERVER_GLOBAL_H
d337f35e 10174+
d337f35e 10175+
d33d7b00
AM
10176+extern atomic_t vx_global_ctotal;
10177+extern atomic_t vx_global_cactive;
d337f35e 10178+
d33d7b00
AM
10179+extern atomic_t nx_global_ctotal;
10180+extern atomic_t nx_global_cactive;
d337f35e 10181+
d33d7b00
AM
10182+extern atomic_t vs_global_nsproxy;
10183+extern atomic_t vs_global_fs;
10184+extern atomic_t vs_global_mnt_ns;
10185+extern atomic_t vs_global_uts_ns;
10186+extern atomic_t vs_global_user_ns;
10187+extern atomic_t vs_global_pid_ns;
d337f35e
JR
10188+
10189+
4bf69007 10190+#endif /* _VSERVER_GLOBAL_H */
8de2f54c 10191diff -NurpP --minimal linux-4.4.111/include/linux/vserver/history.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/history.h
f19bd705 10192--- linux-4.4.111/include/linux/vserver/history.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10193+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/history.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00 10194@@ -0,0 +1,197 @@
4bf69007
AM
10195+#ifndef _VSERVER_HISTORY_H
10196+#define _VSERVER_HISTORY_H
d337f35e 10197+
d337f35e 10198+
d33d7b00
AM
10199+enum {
10200+ VXH_UNUSED = 0,
10201+ VXH_THROW_OOPS = 1,
d337f35e 10202+
d33d7b00
AM
10203+ VXH_GET_VX_INFO,
10204+ VXH_PUT_VX_INFO,
10205+ VXH_INIT_VX_INFO,
10206+ VXH_SET_VX_INFO,
10207+ VXH_CLR_VX_INFO,
10208+ VXH_CLAIM_VX_INFO,
10209+ VXH_RELEASE_VX_INFO,
10210+ VXH_ALLOC_VX_INFO,
10211+ VXH_DEALLOC_VX_INFO,
10212+ VXH_HASH_VX_INFO,
10213+ VXH_UNHASH_VX_INFO,
10214+ VXH_LOC_VX_INFO,
10215+ VXH_LOOKUP_VX_INFO,
10216+ VXH_CREATE_VX_INFO,
10217+};
d337f35e 10218+
d33d7b00
AM
10219+struct _vxhe_vxi {
10220+ struct vx_info *ptr;
10221+ unsigned xid;
10222+ unsigned usecnt;
10223+ unsigned tasks;
10224+};
d337f35e 10225+
d33d7b00
AM
10226+struct _vxhe_set_clr {
10227+ void *data;
10228+};
d337f35e 10229+
d33d7b00
AM
10230+struct _vxhe_loc_lookup {
10231+ unsigned arg;
10232+};
d337f35e 10233+
d33d7b00
AM
10234+struct _vx_hist_entry {
10235+ void *loc;
10236+ unsigned short seq;
10237+ unsigned short type;
10238+ struct _vxhe_vxi vxi;
10239+ union {
10240+ struct _vxhe_set_clr sc;
10241+ struct _vxhe_loc_lookup ll;
10242+ };
3bac966d 10243+};
d337f35e 10244+
d33d7b00 10245+#ifdef CONFIG_VSERVER_HISTORY
d337f35e 10246+
d33d7b00 10247+extern unsigned volatile int vxh_active;
d337f35e 10248+
d33d7b00 10249+struct _vx_hist_entry *vxh_advance(void *loc);
d337f35e 10250+
d337f35e 10251+
d33d7b00
AM
10252+static inline
10253+void __vxh_copy_vxi(struct _vx_hist_entry *entry, struct vx_info *vxi)
10254+{
10255+ entry->vxi.ptr = vxi;
10256+ if (vxi) {
10257+ entry->vxi.usecnt = atomic_read(&vxi->vx_usecnt);
10258+ entry->vxi.tasks = atomic_read(&vxi->vx_tasks);
10259+ entry->vxi.xid = vxi->vx_id;
10260+ }
10261+}
d337f35e 10262+
d337f35e 10263+
d33d7b00 10264+#define __HERE__ current_text_addr()
d337f35e 10265+
d33d7b00
AM
10266+#define __VXH_BODY(__type, __data, __here) \
10267+ struct _vx_hist_entry *entry; \
10268+ \
10269+ preempt_disable(); \
10270+ entry = vxh_advance(__here); \
10271+ __data; \
10272+ entry->type = __type; \
10273+ preempt_enable();
d337f35e 10274+
d337f35e 10275+
d33d7b00 10276+ /* pass vxi only */
d337f35e 10277+
d33d7b00
AM
10278+#define __VXH_SMPL \
10279+ __vxh_copy_vxi(entry, vxi)
d337f35e 10280+
d33d7b00
AM
10281+static inline
10282+void __vxh_smpl(struct vx_info *vxi, int __type, void *__here)
10283+{
10284+ __VXH_BODY(__type, __VXH_SMPL, __here)
10285+}
d337f35e 10286+
d33d7b00 10287+ /* pass vxi and data (void *) */
d337f35e 10288+
d33d7b00
AM
10289+#define __VXH_DATA \
10290+ __vxh_copy_vxi(entry, vxi); \
10291+ entry->sc.data = data
d337f35e 10292+
d33d7b00
AM
10293+static inline
10294+void __vxh_data(struct vx_info *vxi, void *data,
10295+ int __type, void *__here)
3bac966d 10296+{
d33d7b00 10297+ __VXH_BODY(__type, __VXH_DATA, __here)
3bac966d 10298+}
d337f35e 10299+
d33d7b00 10300+ /* pass vxi and arg (long) */
d337f35e 10301+
d33d7b00
AM
10302+#define __VXH_LONG \
10303+ __vxh_copy_vxi(entry, vxi); \
10304+ entry->ll.arg = arg
d337f35e 10305+
d33d7b00
AM
10306+static inline
10307+void __vxh_long(struct vx_info *vxi, long arg,
10308+ int __type, void *__here)
10309+{
10310+ __VXH_BODY(__type, __VXH_LONG, __here)
10311+}
d337f35e 10312+
d337f35e 10313+
d33d7b00
AM
10314+static inline
10315+void __vxh_throw_oops(void *__here)
10316+{
10317+ __VXH_BODY(VXH_THROW_OOPS, {}, __here);
10318+ /* prevent further acquisition */
10319+ vxh_active = 0;
10320+}
d337f35e 10321+
d337f35e 10322+
d33d7b00 10323+#define vxh_throw_oops() __vxh_throw_oops(__HERE__);
d337f35e 10324+
d33d7b00
AM
10325+#define __vxh_get_vx_info(v, h) __vxh_smpl(v, VXH_GET_VX_INFO, h);
10326+#define __vxh_put_vx_info(v, h) __vxh_smpl(v, VXH_PUT_VX_INFO, h);
d337f35e 10327+
d33d7b00
AM
10328+#define __vxh_init_vx_info(v, d, h) \
10329+ __vxh_data(v, d, VXH_INIT_VX_INFO, h);
10330+#define __vxh_set_vx_info(v, d, h) \
10331+ __vxh_data(v, d, VXH_SET_VX_INFO, h);
10332+#define __vxh_clr_vx_info(v, d, h) \
10333+ __vxh_data(v, d, VXH_CLR_VX_INFO, h);
d337f35e 10334+
d33d7b00
AM
10335+#define __vxh_claim_vx_info(v, d, h) \
10336+ __vxh_data(v, d, VXH_CLAIM_VX_INFO, h);
10337+#define __vxh_release_vx_info(v, d, h) \
10338+ __vxh_data(v, d, VXH_RELEASE_VX_INFO, h);
d337f35e 10339+
d33d7b00
AM
10340+#define vxh_alloc_vx_info(v) \
10341+ __vxh_smpl(v, VXH_ALLOC_VX_INFO, __HERE__);
10342+#define vxh_dealloc_vx_info(v) \
10343+ __vxh_smpl(v, VXH_DEALLOC_VX_INFO, __HERE__);
d337f35e 10344+
d33d7b00
AM
10345+#define vxh_hash_vx_info(v) \
10346+ __vxh_smpl(v, VXH_HASH_VX_INFO, __HERE__);
10347+#define vxh_unhash_vx_info(v) \
10348+ __vxh_smpl(v, VXH_UNHASH_VX_INFO, __HERE__);
d337f35e 10349+
d33d7b00
AM
10350+#define vxh_loc_vx_info(v, l) \
10351+ __vxh_long(v, l, VXH_LOC_VX_INFO, __HERE__);
10352+#define vxh_lookup_vx_info(v, l) \
10353+ __vxh_long(v, l, VXH_LOOKUP_VX_INFO, __HERE__);
10354+#define vxh_create_vx_info(v, l) \
10355+ __vxh_long(v, l, VXH_CREATE_VX_INFO, __HERE__);
d337f35e 10356+
d33d7b00 10357+extern void vxh_dump_history(void);
d337f35e 10358+
d337f35e 10359+
d33d7b00 10360+#else /* CONFIG_VSERVER_HISTORY */
2380c486 10361+
d33d7b00 10362+#define __HERE__ 0
d337f35e 10363+
d33d7b00 10364+#define vxh_throw_oops() do { } while (0)
d337f35e 10365+
d33d7b00
AM
10366+#define __vxh_get_vx_info(v, h) do { } while (0)
10367+#define __vxh_put_vx_info(v, h) do { } while (0)
d337f35e 10368+
d33d7b00
AM
10369+#define __vxh_init_vx_info(v, d, h) do { } while (0)
10370+#define __vxh_set_vx_info(v, d, h) do { } while (0)
10371+#define __vxh_clr_vx_info(v, d, h) do { } while (0)
d337f35e 10372+
d33d7b00
AM
10373+#define __vxh_claim_vx_info(v, d, h) do { } while (0)
10374+#define __vxh_release_vx_info(v, d, h) do { } while (0)
3bac966d 10375+
d33d7b00
AM
10376+#define vxh_alloc_vx_info(v) do { } while (0)
10377+#define vxh_dealloc_vx_info(v) do { } while (0)
d337f35e 10378+
d33d7b00
AM
10379+#define vxh_hash_vx_info(v) do { } while (0)
10380+#define vxh_unhash_vx_info(v) do { } while (0)
d337f35e 10381+
d33d7b00
AM
10382+#define vxh_loc_vx_info(v, l) do { } while (0)
10383+#define vxh_lookup_vx_info(v, l) do { } while (0)
10384+#define vxh_create_vx_info(v, l) do { } while (0)
d337f35e 10385+
d33d7b00 10386+#define vxh_dump_history() do { } while (0)
d337f35e 10387+
d337f35e 10388+
d33d7b00 10389+#endif /* CONFIG_VSERVER_HISTORY */
d337f35e 10390+
4bf69007 10391+#endif /* _VSERVER_HISTORY_H */
8de2f54c 10392diff -NurpP --minimal linux-4.4.111/include/linux/vserver/inode.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/inode.h
f19bd705 10393--- linux-4.4.111/include/linux/vserver/inode.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10394+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/inode.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10395@@ -0,0 +1,19 @@
10396+#ifndef _VSERVER_INODE_H
10397+#define _VSERVER_INODE_H
d337f35e 10398+
4bf69007 10399+#include <uapi/vserver/inode.h>
d337f35e 10400+
d337f35e 10401+
d33d7b00
AM
10402+#ifdef CONFIG_VSERVER_PROC_SECURE
10403+#define IATTR_PROC_DEFAULT ( IATTR_ADMIN | IATTR_HIDE )
10404+#define IATTR_PROC_SYMLINK ( IATTR_ADMIN )
10405+#else
10406+#define IATTR_PROC_DEFAULT ( IATTR_ADMIN )
10407+#define IATTR_PROC_SYMLINK ( IATTR_ADMIN )
10408+#endif
d337f35e 10409+
d33d7b00 10410+#define vx_hide_check(c, m) (((m) & IATTR_HIDE) ? vx_check(c, m) : 1)
d337f35e 10411+
4bf69007 10412+#else /* _VSERVER_INODE_H */
3bac966d 10413+#warning duplicate inclusion
4bf69007 10414+#endif /* _VSERVER_INODE_H */
8de2f54c 10415diff -NurpP --minimal linux-4.4.111/include/linux/vserver/inode_cmd.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/inode_cmd.h
f19bd705 10416--- linux-4.4.111/include/linux/vserver/inode_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10417+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/inode_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10418@@ -0,0 +1,36 @@
10419+#ifndef _VSERVER_INODE_CMD_H
10420+#define _VSERVER_INODE_CMD_H
d337f35e 10421+
4bf69007 10422+#include <uapi/vserver/inode_cmd.h>
d337f35e 10423+
d337f35e
JR
10424+
10425+
d33d7b00 10426+#ifdef CONFIG_COMPAT
d337f35e 10427+
d33d7b00 10428+#include <asm/compat.h>
d337f35e 10429+
d33d7b00
AM
10430+struct vcmd_ctx_iattr_v1_x32 {
10431+ compat_uptr_t name_ptr;
10432+ uint32_t tag;
10433+ uint32_t flags;
10434+ uint32_t mask;
10435+};
d337f35e 10436+
d33d7b00 10437+#endif /* CONFIG_COMPAT */
d337f35e 10438+
d33d7b00 10439+#include <linux/compiler.h>
d337f35e 10440+
d33d7b00
AM
10441+extern int vc_get_iattr(void __user *);
10442+extern int vc_set_iattr(void __user *);
d337f35e 10443+
d33d7b00
AM
10444+extern int vc_fget_iattr(uint32_t, void __user *);
10445+extern int vc_fset_iattr(uint32_t, void __user *);
d337f35e 10446+
d33d7b00 10447+#ifdef CONFIG_COMPAT
d337f35e 10448+
d33d7b00
AM
10449+extern int vc_get_iattr_x32(void __user *);
10450+extern int vc_set_iattr_x32(void __user *);
d337f35e 10451+
d33d7b00 10452+#endif /* CONFIG_COMPAT */
d337f35e 10453+
4bf69007 10454+#endif /* _VSERVER_INODE_CMD_H */
8de2f54c 10455diff -NurpP --minimal linux-4.4.111/include/linux/vserver/limit.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/limit.h
f19bd705 10456--- linux-4.4.111/include/linux/vserver/limit.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10457+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/limit.h 2018-01-09 16:36:32.000000000 +0000
927ca606 10458@@ -0,0 +1,67 @@
4bf69007
AM
10459+#ifndef _VSERVER_LIMIT_H
10460+#define _VSERVER_LIMIT_H
d337f35e 10461+
4bf69007 10462+#include <uapi/vserver/limit.h>
d337f35e 10463+
d337f35e 10464+
d33d7b00 10465+#define VLIM_NOCHECK ((1L << VLIMIT_DENTRY) | (1L << RLIMIT_RSS))
d337f35e 10466+
d33d7b00 10467+/* keep in sync with CRLIM_INFINITY */
d337f35e 10468+
d33d7b00 10469+#define VLIM_INFINITY (~0ULL)
d337f35e 10470+
d33d7b00
AM
10471+#include <asm/atomic.h>
10472+#include <asm/resource.h>
d337f35e 10473+
d33d7b00
AM
10474+#ifndef RLIM_INFINITY
10475+#warning RLIM_INFINITY is undefined
10476+#endif
d337f35e 10477+
d33d7b00 10478+#define __rlim_val(l, r, v) ((l)->res[r].v)
d337f35e 10479+
d33d7b00
AM
10480+#define __rlim_soft(l, r) __rlim_val(l, r, soft)
10481+#define __rlim_hard(l, r) __rlim_val(l, r, hard)
d337f35e 10482+
d33d7b00
AM
10483+#define __rlim_rcur(l, r) __rlim_val(l, r, rcur)
10484+#define __rlim_rmin(l, r) __rlim_val(l, r, rmin)
10485+#define __rlim_rmax(l, r) __rlim_val(l, r, rmax)
d337f35e 10486+
d33d7b00
AM
10487+#define __rlim_lhit(l, r) __rlim_val(l, r, lhit)
10488+#define __rlim_hit(l, r) atomic_inc(&__rlim_lhit(l, r))
d337f35e 10489+
d33d7b00
AM
10490+typedef atomic_long_t rlim_atomic_t;
10491+typedef unsigned long rlim_t;
d337f35e 10492+
d33d7b00
AM
10493+#define __rlim_get(l, r) atomic_long_read(&__rlim_rcur(l, r))
10494+#define __rlim_set(l, r, v) atomic_long_set(&__rlim_rcur(l, r), v)
10495+#define __rlim_inc(l, r) atomic_long_inc(&__rlim_rcur(l, r))
10496+#define __rlim_dec(l, r) atomic_long_dec(&__rlim_rcur(l, r))
10497+#define __rlim_add(l, r, v) atomic_long_add(v, &__rlim_rcur(l, r))
10498+#define __rlim_sub(l, r, v) atomic_long_sub(v, &__rlim_rcur(l, r))
d337f35e 10499+
d337f35e 10500+
d33d7b00
AM
10501+#if (RLIM_INFINITY == VLIM_INFINITY)
10502+#define VX_VLIM(r) ((long long)(long)(r))
10503+#define VX_RLIM(v) ((rlim_t)(v))
3bac966d 10504+#else
d33d7b00
AM
10505+#define VX_VLIM(r) (((r) == RLIM_INFINITY) \
10506+ ? VLIM_INFINITY : (long long)(r))
10507+#define VX_RLIM(v) (((v) == VLIM_INFINITY) \
10508+ ? RLIM_INFINITY : (rlim_t)(v))
3bac966d 10509+#endif
d337f35e 10510+
d33d7b00 10511+struct sysinfo;
d337f35e 10512+
927ca606 10513+#ifdef CONFIG_MEMCG
d33d7b00
AM
10514+void vx_vsi_meminfo(struct sysinfo *);
10515+void vx_vsi_swapinfo(struct sysinfo *);
10516+long vx_vsi_cached(struct sysinfo *);
927ca606
AM
10517+#else /* !CONFIG_MEMCG */
10518+#define vx_vsi_meminfo(s) do { } while (0)
10519+#define vx_vsi_swapinfo(s) do { } while (0)
10520+#define vx_vsi_cached(s) (0L)
10521+#endif /* !CONFIG_MEMCG */
d337f35e 10522+
d33d7b00 10523+#define NUM_LIMITS 24
d337f35e 10524+
4bf69007 10525+#endif /* _VSERVER_LIMIT_H */
8de2f54c 10526diff -NurpP --minimal linux-4.4.111/include/linux/vserver/limit_cmd.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/limit_cmd.h
f19bd705 10527--- linux-4.4.111/include/linux/vserver/limit_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10528+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/limit_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10529@@ -0,0 +1,35 @@
10530+#ifndef _VSERVER_LIMIT_CMD_H
10531+#define _VSERVER_LIMIT_CMD_H
d337f35e 10532+
4bf69007 10533+#include <uapi/vserver/limit_cmd.h>
d337f35e 10534+
d337f35e 10535+
d33d7b00 10536+#ifdef CONFIG_IA32_EMULATION
d337f35e 10537+
d33d7b00
AM
10538+struct vcmd_ctx_rlimit_v0_x32 {
10539+ uint32_t id;
10540+ uint64_t minimum;
10541+ uint64_t softlimit;
10542+ uint64_t maximum;
10543+} __attribute__ ((packed));
d337f35e 10544+
d33d7b00 10545+#endif /* CONFIG_IA32_EMULATION */
d337f35e 10546+
d33d7b00 10547+#include <linux/compiler.h>
d337f35e 10548+
d33d7b00
AM
10549+extern int vc_get_rlimit_mask(uint32_t, void __user *);
10550+extern int vc_get_rlimit(struct vx_info *, void __user *);
10551+extern int vc_set_rlimit(struct vx_info *, void __user *);
10552+extern int vc_reset_hits(struct vx_info *, void __user *);
10553+extern int vc_reset_minmax(struct vx_info *, void __user *);
d337f35e 10554+
d33d7b00 10555+extern int vc_rlimit_stat(struct vx_info *, void __user *);
d337f35e 10556+
d33d7b00 10557+#ifdef CONFIG_IA32_EMULATION
d337f35e 10558+
d33d7b00
AM
10559+extern int vc_get_rlimit_x32(struct vx_info *, void __user *);
10560+extern int vc_set_rlimit_x32(struct vx_info *, void __user *);
adc1caaa 10561+
d33d7b00 10562+#endif /* CONFIG_IA32_EMULATION */
d337f35e 10563+
4bf69007 10564+#endif /* _VSERVER_LIMIT_CMD_H */
8de2f54c 10565diff -NurpP --minimal linux-4.4.111/include/linux/vserver/limit_def.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/limit_def.h
f19bd705 10566--- linux-4.4.111/include/linux/vserver/limit_def.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10567+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/limit_def.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00 10568@@ -0,0 +1,47 @@
4bf69007
AM
10569+#ifndef _VSERVER_LIMIT_DEF_H
10570+#define _VSERVER_LIMIT_DEF_H
d337f35e 10571+
d33d7b00
AM
10572+#include <asm/atomic.h>
10573+#include <asm/resource.h>
d337f35e 10574+
d33d7b00 10575+#include "limit.h"
d337f35e 10576+
d337f35e 10577+
d33d7b00
AM
10578+struct _vx_res_limit {
10579+ rlim_t soft; /* Context soft limit */
10580+ rlim_t hard; /* Context hard limit */
d337f35e 10581+
d33d7b00
AM
10582+ rlim_atomic_t rcur; /* Current value */
10583+ rlim_t rmin; /* Context minimum */
10584+ rlim_t rmax; /* Context maximum */
d337f35e 10585+
d33d7b00
AM
10586+ atomic_t lhit; /* Limit hits */
10587+};
d337f35e 10588+
d33d7b00 10589+/* context sub struct */
2380c486 10590+
d33d7b00
AM
10591+struct _vx_limit {
10592+ struct _vx_res_limit res[NUM_LIMITS];
10593+};
adc1caaa 10594+
d33d7b00 10595+#ifdef CONFIG_VSERVER_DEBUG
adc1caaa 10596+
d33d7b00 10597+static inline void __dump_vx_limit(struct _vx_limit *limit)
3bac966d 10598+{
d33d7b00 10599+ int i;
d337f35e 10600+
d33d7b00
AM
10601+ printk("\t_vx_limit:");
10602+ for (i = 0; i < NUM_LIMITS; i++) {
10603+ printk("\t [%2d] = %8lu %8lu/%8lu, %8ld/%8ld, %8d\n",
10604+ i, (unsigned long)__rlim_get(limit, i),
10605+ (unsigned long)__rlim_rmin(limit, i),
10606+ (unsigned long)__rlim_rmax(limit, i),
10607+ (long)__rlim_soft(limit, i),
10608+ (long)__rlim_hard(limit, i),
10609+ atomic_read(&__rlim_lhit(limit, i)));
10610+ }
3bac966d 10611+}
d337f35e 10612+
d33d7b00 10613+#endif
d337f35e 10614+
4bf69007 10615+#endif /* _VSERVER_LIMIT_DEF_H */
8de2f54c 10616diff -NurpP --minimal linux-4.4.111/include/linux/vserver/limit_int.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/limit_int.h
f19bd705 10617--- linux-4.4.111/include/linux/vserver/limit_int.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10618+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/limit_int.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10619@@ -0,0 +1,193 @@
10620+#ifndef _VSERVER_LIMIT_INT_H
10621+#define _VSERVER_LIMIT_INT_H
d337f35e 10622+
d33d7b00
AM
10623+#define VXD_RCRES_COND(r) VXD_CBIT(cres, r)
10624+#define VXD_RLIMIT_COND(r) VXD_CBIT(limit, r)
d337f35e 10625+
d33d7b00 10626+extern const char *vlimit_name[NUM_LIMITS];
2380c486 10627+
d33d7b00
AM
10628+static inline void __vx_acc_cres(struct vx_info *vxi,
10629+ int res, int dir, void *_data, char *_file, int _line)
10630+{
10631+ if (VXD_RCRES_COND(res))
10632+ vxlprintk(1, "vx_acc_cres[%5d,%s,%2d]: %5ld%s (%p)",
10633+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
10634+ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
10635+ (dir > 0) ? "++" : "--", _data, _file, _line);
10636+ if (!vxi)
10637+ return;
d337f35e 10638+
d33d7b00
AM
10639+ if (dir > 0)
10640+ __rlim_inc(&vxi->limit, res);
10641+ else
10642+ __rlim_dec(&vxi->limit, res);
10643+}
d337f35e 10644+
d33d7b00
AM
10645+static inline void __vx_add_cres(struct vx_info *vxi,
10646+ int res, int amount, void *_data, char *_file, int _line)
10647+{
10648+ if (VXD_RCRES_COND(res))
10649+ vxlprintk(1, "vx_add_cres[%5d,%s,%2d]: %5ld += %5d (%p)",
10650+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
10651+ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
10652+ amount, _data, _file, _line);
10653+ if (amount == 0)
10654+ return;
10655+ if (!vxi)
10656+ return;
10657+ __rlim_add(&vxi->limit, res, amount);
10658+}
d337f35e 10659+
3bac966d 10660+static inline
d33d7b00 10661+int __vx_cres_adjust_max(struct _vx_limit *limit, int res, rlim_t value)
3bac966d 10662+{
d33d7b00 10663+ int cond = (value > __rlim_rmax(limit, res));
d337f35e 10664+
d33d7b00
AM
10665+ if (cond)
10666+ __rlim_rmax(limit, res) = value;
10667+ return cond;
3bac966d 10668+}
d337f35e 10669+
3bac966d 10670+static inline
d33d7b00 10671+int __vx_cres_adjust_min(struct _vx_limit *limit, int res, rlim_t value)
3bac966d 10672+{
d33d7b00 10673+ int cond = (value < __rlim_rmin(limit, res));
d337f35e 10674+
d33d7b00
AM
10675+ if (cond)
10676+ __rlim_rmin(limit, res) = value;
10677+ return cond;
3bac966d 10678+}
d337f35e 10679+
3bac966d 10680+static inline
d33d7b00 10681+void __vx_cres_fixup(struct _vx_limit *limit, int res, rlim_t value)
3bac966d 10682+{
d33d7b00
AM
10683+ if (!__vx_cres_adjust_max(limit, res, value))
10684+ __vx_cres_adjust_min(limit, res, value);
3bac966d 10685+}
d337f35e 10686+
2380c486 10687+
d33d7b00
AM
10688+/* return values:
10689+ +1 ... no limit hit
10690+ -1 ... over soft limit
10691+ 0 ... over hard limit */
d337f35e 10692+
d33d7b00
AM
10693+static inline int __vx_cres_avail(struct vx_info *vxi,
10694+ int res, int num, char *_file, int _line)
3bac966d 10695+{
d33d7b00
AM
10696+ struct _vx_limit *limit;
10697+ rlim_t value;
d337f35e 10698+
d33d7b00
AM
10699+ if (VXD_RLIMIT_COND(res))
10700+ vxlprintk(1, "vx_cres_avail[%5d,%s,%2d]: %5ld/%5ld > %5ld + %5d",
10701+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
10702+ (vxi ? (long)__rlim_soft(&vxi->limit, res) : -1),
10703+ (vxi ? (long)__rlim_hard(&vxi->limit, res) : -1),
10704+ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
10705+ num, _file, _line);
10706+ if (!vxi)
3bac966d 10707+ return 1;
d337f35e 10708+
d33d7b00
AM
10709+ limit = &vxi->limit;
10710+ value = __rlim_get(limit, res);
d337f35e 10711+
d33d7b00
AM
10712+ if (!__vx_cres_adjust_max(limit, res, value))
10713+ __vx_cres_adjust_min(limit, res, value);
d337f35e 10714+
d33d7b00 10715+ if (num == 0)
3bac966d 10716+ return 1;
d337f35e 10717+
d33d7b00
AM
10718+ if (__rlim_soft(limit, res) == RLIM_INFINITY)
10719+ return -1;
10720+ if (value + num <= __rlim_soft(limit, res))
10721+ return -1;
d337f35e 10722+
d33d7b00 10723+ if (__rlim_hard(limit, res) == RLIM_INFINITY)
3bac966d 10724+ return 1;
d33d7b00 10725+ if (value + num <= __rlim_hard(limit, res))
3bac966d 10726+ return 1;
d33d7b00
AM
10727+
10728+ __rlim_hit(limit, res);
3bac966d
AM
10729+ return 0;
10730+}
d337f35e 10731+
d337f35e 10732+
d33d7b00 10733+static const int VLA_RSS[] = { RLIMIT_RSS, VLIMIT_ANON, VLIMIT_MAPPED, 0 };
d337f35e 10734+
3bac966d 10735+static inline
d33d7b00 10736+rlim_t __vx_cres_array_sum(struct _vx_limit *limit, const int *array)
3bac966d 10737+{
d33d7b00
AM
10738+ rlim_t value, sum = 0;
10739+ int res;
d337f35e 10740+
d33d7b00
AM
10741+ while ((res = *array++)) {
10742+ value = __rlim_get(limit, res);
10743+ __vx_cres_fixup(limit, res, value);
10744+ sum += value;
10745+ }
10746+ return sum;
3bac966d 10747+}
d337f35e 10748+
3bac966d 10749+static inline
d33d7b00 10750+rlim_t __vx_cres_array_fixup(struct _vx_limit *limit, const int *array)
3bac966d 10751+{
d33d7b00
AM
10752+ rlim_t value = __vx_cres_array_sum(limit, array + 1);
10753+ int res = *array;
d337f35e 10754+
d33d7b00
AM
10755+ if (value == __rlim_get(limit, res))
10756+ return value;
10757+
10758+ __rlim_set(limit, res, value);
10759+ /* now adjust min/max */
10760+ if (!__vx_cres_adjust_max(limit, res, value))
10761+ __vx_cres_adjust_min(limit, res, value);
10762+
10763+ return value;
3bac966d 10764+}
d337f35e 10765+
d33d7b00
AM
10766+static inline int __vx_cres_array_avail(struct vx_info *vxi,
10767+ const int *array, int num, char *_file, int _line)
3bac966d 10768+{
d33d7b00
AM
10769+ struct _vx_limit *limit;
10770+ rlim_t value = 0;
10771+ int res;
10772+
10773+ if (num == 0)
3bac966d 10774+ return 1;
d33d7b00 10775+ if (!vxi)
3bac966d 10776+ return 1;
d337f35e 10777+
d33d7b00
AM
10778+ limit = &vxi->limit;
10779+ res = *array;
10780+ value = __vx_cres_array_sum(limit, array + 1);
d337f35e 10781+
d33d7b00
AM
10782+ __rlim_set(limit, res, value);
10783+ __vx_cres_fixup(limit, res, value);
10784+
10785+ return __vx_cres_avail(vxi, res, num, _file, _line);
3bac966d 10786+}
d337f35e 10787+
d337f35e 10788+
d33d7b00 10789+static inline void vx_limit_fixup(struct _vx_limit *limit, int id)
3bac966d 10790+{
d33d7b00
AM
10791+ rlim_t value;
10792+ int res;
d337f35e 10793+
d33d7b00
AM
10794+ /* complex resources first */
10795+ if ((id < 0) || (id == RLIMIT_RSS))
10796+ __vx_cres_array_fixup(limit, VLA_RSS);
d337f35e 10797+
d33d7b00
AM
10798+ for (res = 0; res < NUM_LIMITS; res++) {
10799+ if ((id > 0) && (res != id))
10800+ continue;
10801+
10802+ value = __rlim_get(limit, res);
10803+ __vx_cres_fixup(limit, res, value);
10804+
10805+ /* not supposed to happen, maybe warn? */
10806+ if (__rlim_rmax(limit, res) > __rlim_hard(limit, res))
10807+ __rlim_rmax(limit, res) = __rlim_hard(limit, res);
10808+ }
3bac966d 10809+}
d337f35e
JR
10810+
10811+
4bf69007 10812+#endif /* _VSERVER_LIMIT_INT_H */
8de2f54c 10813diff -NurpP --minimal linux-4.4.111/include/linux/vserver/monitor.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/monitor.h
f19bd705 10814--- linux-4.4.111/include/linux/vserver/monitor.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10815+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/monitor.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10816@@ -0,0 +1,6 @@
10817+#ifndef _VSERVER_MONITOR_H
10818+#define _VSERVER_MONITOR_H
d337f35e 10819+
4bf69007 10820+#include <uapi/vserver/monitor.h>
d337f35e 10821+
4bf69007 10822+#endif /* _VSERVER_MONITOR_H */
8de2f54c 10823diff -NurpP --minimal linux-4.4.111/include/linux/vserver/network.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/network.h
f19bd705 10824--- linux-4.4.111/include/linux/vserver/network.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10825+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/network.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10826@@ -0,0 +1,76 @@
10827+#ifndef _VSERVER_NETWORK_H
10828+#define _VSERVER_NETWORK_H
d337f35e 10829+
d337f35e 10830+
4bf69007
AM
10831+#include <linux/list.h>
10832+#include <linux/spinlock.h>
10833+#include <linux/rcupdate.h>
10834+#include <linux/in.h>
10835+#include <linux/in6.h>
10836+#include <asm/atomic.h>
10837+#include <uapi/vserver/network.h>
d337f35e 10838+
4bf69007
AM
10839+struct nx_addr_v4 {
10840+ struct nx_addr_v4 *next;
10841+ struct in_addr ip[2];
10842+ struct in_addr mask;
10843+ uint16_t type;
10844+ uint16_t flags;
10845+};
d337f35e 10846+
4bf69007
AM
10847+struct nx_addr_v6 {
10848+ struct nx_addr_v6 *next;
10849+ struct in6_addr ip;
10850+ struct in6_addr mask;
10851+ uint32_t prefix;
10852+ uint16_t type;
10853+ uint16_t flags;
10854+};
d337f35e 10855+
4bf69007
AM
10856+struct nx_info {
10857+ struct hlist_node nx_hlist; /* linked list of nxinfos */
61333608 10858+ vnid_t nx_id; /* vnet id */
4bf69007
AM
10859+ atomic_t nx_usecnt; /* usage count */
10860+ atomic_t nx_tasks; /* tasks count */
10861+ int nx_state; /* context state */
d337f35e 10862+
4bf69007
AM
10863+ uint64_t nx_flags; /* network flag word */
10864+ uint64_t nx_ncaps; /* network capabilities */
d337f35e 10865+
4bf69007
AM
10866+ spinlock_t addr_lock; /* protect address changes */
10867+ struct in_addr v4_lback; /* Loopback address */
10868+ struct in_addr v4_bcast; /* Broadcast address */
10869+ struct nx_addr_v4 v4; /* First/Single ipv4 address */
10870+#ifdef CONFIG_IPV6
10871+ struct nx_addr_v6 v6; /* First/Single ipv6 address */
10872+#endif
10873+ char nx_name[65]; /* network context name */
d33d7b00 10874+};
d337f35e 10875+
d337f35e 10876+
4bf69007 10877+/* status flags */
d337f35e 10878+
4bf69007
AM
10879+#define NXS_HASHED 0x0001
10880+#define NXS_SHUTDOWN 0x0100
10881+#define NXS_RELEASED 0x8000
d337f35e 10882+
4bf69007 10883+extern struct nx_info *lookup_nx_info(int);
d337f35e 10884+
4bf69007 10885+extern int get_nid_list(int, unsigned int *, int);
61333608 10886+extern int nid_is_hashed(vnid_t);
d337f35e 10887+
4bf69007 10888+extern int nx_migrate_task(struct task_struct *, struct nx_info *);
d337f35e 10889+
4bf69007 10890+extern long vs_net_change(struct nx_info *, unsigned int);
d337f35e 10891+
4bf69007 10892+struct sock;
d337f35e 10893+
d337f35e 10894+
4bf69007
AM
10895+#define NX_IPV4(n) ((n)->v4.type != NXA_TYPE_NONE)
10896+#ifdef CONFIG_IPV6
10897+#define NX_IPV6(n) ((n)->v6.type != NXA_TYPE_NONE)
10898+#else
10899+#define NX_IPV6(n) (0)
10900+#endif
d337f35e 10901+
4bf69007 10902+#endif /* _VSERVER_NETWORK_H */
8de2f54c 10903diff -NurpP --minimal linux-4.4.111/include/linux/vserver/network_cmd.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/network_cmd.h
f19bd705 10904--- linux-4.4.111/include/linux/vserver/network_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10905+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/network_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10906@@ -0,0 +1,37 @@
10907+#ifndef _VSERVER_NETWORK_CMD_H
10908+#define _VSERVER_NETWORK_CMD_H
d337f35e 10909+
4bf69007 10910+#include <uapi/vserver/network_cmd.h>
d337f35e 10911+
4bf69007 10912+extern int vc_task_nid(uint32_t);
d337f35e 10913+
4bf69007 10914+extern int vc_nx_info(struct nx_info *, void __user *);
d337f35e 10915+
4bf69007
AM
10916+extern int vc_net_create(uint32_t, void __user *);
10917+extern int vc_net_migrate(struct nx_info *, void __user *);
d337f35e 10918+
4bf69007
AM
10919+extern int vc_net_add(struct nx_info *, void __user *);
10920+extern int vc_net_remove(struct nx_info *, void __user *);
d337f35e 10921+
4bf69007
AM
10922+extern int vc_net_add_ipv4_v1(struct nx_info *, void __user *);
10923+extern int vc_net_add_ipv4(struct nx_info *, void __user *);
d337f35e 10924+
4bf69007
AM
10925+extern int vc_net_rem_ipv4_v1(struct nx_info *, void __user *);
10926+extern int vc_net_rem_ipv4(struct nx_info *, void __user *);
d337f35e 10927+
4bf69007
AM
10928+extern int vc_net_add_ipv6(struct nx_info *, void __user *);
10929+extern int vc_net_remove_ipv6(struct nx_info *, void __user *);
d337f35e 10930+
4bf69007
AM
10931+extern int vc_add_match_ipv4(struct nx_info *, void __user *);
10932+extern int vc_get_match_ipv4(struct nx_info *, void __user *);
d33d7b00 10933+
4bf69007
AM
10934+extern int vc_add_match_ipv6(struct nx_info *, void __user *);
10935+extern int vc_get_match_ipv6(struct nx_info *, void __user *);
d337f35e 10936+
4bf69007
AM
10937+extern int vc_get_nflags(struct nx_info *, void __user *);
10938+extern int vc_set_nflags(struct nx_info *, void __user *);
d337f35e 10939+
4bf69007
AM
10940+extern int vc_get_ncaps(struct nx_info *, void __user *);
10941+extern int vc_set_ncaps(struct nx_info *, void __user *);
d337f35e 10942+
4bf69007 10943+#endif /* _VSERVER_CONTEXT_CMD_H */
8de2f54c 10944diff -NurpP --minimal linux-4.4.111/include/linux/vserver/percpu.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/percpu.h
f19bd705 10945--- linux-4.4.111/include/linux/vserver/percpu.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10946+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/percpu.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10947@@ -0,0 +1,14 @@
10948+#ifndef _VSERVER_PERCPU_H
10949+#define _VSERVER_PERCPU_H
d337f35e 10950+
4bf69007
AM
10951+#include "cvirt_def.h"
10952+#include "sched_def.h"
d337f35e 10953+
4bf69007
AM
10954+struct _vx_percpu {
10955+ struct _vx_cvirt_pc cvirt;
10956+ struct _vx_sched_pc sched;
10957+};
9795bf04 10958+
4bf69007 10959+#define PERCPU_PERCTX (sizeof(struct _vx_percpu))
d337f35e 10960+
4bf69007 10961+#endif /* _VSERVER_PERCPU_H */
8de2f54c 10962diff -NurpP --minimal linux-4.4.111/include/linux/vserver/pid.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/pid.h
f19bd705 10963--- linux-4.4.111/include/linux/vserver/pid.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 10964+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/pid.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10965@@ -0,0 +1,51 @@
10966+#ifndef _VSERVER_PID_H
10967+#define _VSERVER_PID_H
d337f35e 10968+
4bf69007 10969+/* pid faking stuff */
d337f35e 10970+
4bf69007
AM
10971+#define vx_info_map_pid(v, p) \
10972+ __vx_info_map_pid((v), (p), __func__, __FILE__, __LINE__)
10973+#define vx_info_map_tgid(v,p) vx_info_map_pid(v,p)
10974+#define vx_map_pid(p) vx_info_map_pid(current_vx_info(), p)
10975+#define vx_map_tgid(p) vx_map_pid(p)
d337f35e 10976+
4bf69007
AM
10977+static inline int __vx_info_map_pid(struct vx_info *vxi, int pid,
10978+ const char *func, const char *file, int line)
10979+{
10980+ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
10981+ vxfprintk(VXD_CBIT(cvirt, 2),
10982+ "vx_map_tgid: %p/%llx: %d -> %d",
10983+ vxi, (long long)vxi->vx_flags, pid,
10984+ (pid && pid == vxi->vx_initpid) ? 1 : pid,
10985+ func, file, line);
10986+ if (pid == 0)
10987+ return 0;
10988+ if (pid == vxi->vx_initpid)
10989+ return 1;
10990+ }
10991+ return pid;
10992+}
d337f35e 10993+
4bf69007
AM
10994+#define vx_info_rmap_pid(v, p) \
10995+ __vx_info_rmap_pid((v), (p), __func__, __FILE__, __LINE__)
10996+#define vx_rmap_pid(p) vx_info_rmap_pid(current_vx_info(), p)
10997+#define vx_rmap_tgid(p) vx_rmap_pid(p)
d337f35e 10998+
4bf69007
AM
10999+static inline int __vx_info_rmap_pid(struct vx_info *vxi, int pid,
11000+ const char *func, const char *file, int line)
11001+{
11002+ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
11003+ vxfprintk(VXD_CBIT(cvirt, 2),
11004+ "vx_rmap_tgid: %p/%llx: %d -> %d",
11005+ vxi, (long long)vxi->vx_flags, pid,
11006+ (pid == 1) ? vxi->vx_initpid : pid,
11007+ func, file, line);
11008+ if ((pid == 1) && vxi->vx_initpid)
11009+ return vxi->vx_initpid;
11010+ if (pid == vxi->vx_initpid)
11011+ return ~0U;
11012+ }
11013+ return pid;
11014+}
d337f35e 11015+
4bf69007 11016+#endif
8de2f54c 11017diff -NurpP --minimal linux-4.4.111/include/linux/vserver/sched.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/sched.h
f19bd705 11018--- linux-4.4.111/include/linux/vserver/sched.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11019+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/sched.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11020@@ -0,0 +1,23 @@
11021+#ifndef _VSERVER_SCHED_H
11022+#define _VSERVER_SCHED_H
d337f35e 11023+
d337f35e 11024+
d33d7b00 11025+#ifdef __KERNEL__
d337f35e 11026+
4bf69007 11027+struct timespec;
d337f35e 11028+
4bf69007 11029+void vx_vsi_uptime(struct timespec *, struct timespec *);
d337f35e
JR
11030+
11031+
4bf69007 11032+struct vx_info;
d337f35e 11033+
4bf69007 11034+void vx_update_load(struct vx_info *);
d337f35e 11035+
d337f35e 11036+
4bf69007
AM
11037+void vx_update_sched_param(struct _vx_sched *sched,
11038+ struct _vx_sched_pc *sched_pc);
d337f35e 11039+
4bf69007
AM
11040+#endif /* __KERNEL__ */
11041+#else /* _VSERVER_SCHED_H */
11042+#warning duplicate inclusion
11043+#endif /* _VSERVER_SCHED_H */
8de2f54c 11044diff -NurpP --minimal linux-4.4.111/include/linux/vserver/sched_cmd.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/sched_cmd.h
f19bd705 11045--- linux-4.4.111/include/linux/vserver/sched_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11046+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/sched_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11047@@ -0,0 +1,11 @@
11048+#ifndef _VSERVER_SCHED_CMD_H
11049+#define _VSERVER_SCHED_CMD_H
2380c486 11050+
2380c486 11051+
4bf69007
AM
11052+#include <linux/compiler.h>
11053+#include <uapi/vserver/sched_cmd.h>
d337f35e 11054+
4bf69007
AM
11055+extern int vc_set_prio_bias(struct vx_info *, void __user *);
11056+extern int vc_get_prio_bias(struct vx_info *, void __user *);
d337f35e 11057+
4bf69007 11058+#endif /* _VSERVER_SCHED_CMD_H */
8de2f54c 11059diff -NurpP --minimal linux-4.4.111/include/linux/vserver/sched_def.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/sched_def.h
f19bd705 11060--- linux-4.4.111/include/linux/vserver/sched_def.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11061+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/sched_def.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11062@@ -0,0 +1,38 @@
11063+#ifndef _VSERVER_SCHED_DEF_H
11064+#define _VSERVER_SCHED_DEF_H
d33d7b00 11065+
4bf69007
AM
11066+#include <linux/spinlock.h>
11067+#include <linux/jiffies.h>
11068+#include <linux/cpumask.h>
11069+#include <asm/atomic.h>
11070+#include <asm/param.h>
d33d7b00 11071+
d337f35e 11072+
4bf69007 11073+/* context sub struct */
d337f35e 11074+
4bf69007
AM
11075+struct _vx_sched {
11076+ int prio_bias; /* bias offset for priority */
d337f35e 11077+
4bf69007
AM
11078+ cpumask_t update; /* CPUs which should update */
11079+};
d337f35e 11080+
4bf69007
AM
11081+struct _vx_sched_pc {
11082+ int prio_bias; /* bias offset for priority */
d337f35e 11083+
4bf69007
AM
11084+ uint64_t user_ticks; /* token tick events */
11085+ uint64_t sys_ticks; /* token tick events */
11086+ uint64_t hold_ticks; /* token ticks paused */
11087+};
d337f35e 11088+
d337f35e 11089+
4bf69007 11090+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 11091+
4bf69007
AM
11092+static inline void __dump_vx_sched(struct _vx_sched *sched)
11093+{
11094+ printk("\t_vx_sched:\n");
11095+ printk("\t priority = %4d\n", sched->prio_bias);
11096+}
d337f35e 11097+
4bf69007
AM
11098+#endif
11099+
11100+#endif /* _VSERVER_SCHED_DEF_H */
8de2f54c 11101diff -NurpP --minimal linux-4.4.111/include/linux/vserver/signal.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/signal.h
f19bd705 11102--- linux-4.4.111/include/linux/vserver/signal.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11103+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/signal.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11104@@ -0,0 +1,14 @@
11105+#ifndef _VSERVER_SIGNAL_H
11106+#define _VSERVER_SIGNAL_H
d337f35e 11107+
d337f35e 11108+
d33d7b00 11109+#ifdef __KERNEL__
4bf69007
AM
11110+
11111+struct vx_info;
11112+
11113+int vx_info_kill(struct vx_info *, int, int);
d337f35e 11114+
d33d7b00 11115+#endif /* __KERNEL__ */
4bf69007
AM
11116+#else /* _VSERVER_SIGNAL_H */
11117+#warning duplicate inclusion
11118+#endif /* _VSERVER_SIGNAL_H */
8de2f54c 11119diff -NurpP --minimal linux-4.4.111/include/linux/vserver/signal_cmd.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/signal_cmd.h
f19bd705 11120--- linux-4.4.111/include/linux/vserver/signal_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11121+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/signal_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11122@@ -0,0 +1,14 @@
11123+#ifndef _VSERVER_SIGNAL_CMD_H
11124+#define _VSERVER_SIGNAL_CMD_H
d337f35e 11125+
4bf69007 11126+#include <uapi/vserver/signal_cmd.h>
d337f35e 11127+
d337f35e 11128+
4bf69007
AM
11129+extern int vc_ctx_kill(struct vx_info *, void __user *);
11130+extern int vc_wait_exit(struct vx_info *, void __user *);
d337f35e
JR
11131+
11132+
4bf69007
AM
11133+extern int vc_get_pflags(uint32_t pid, void __user *);
11134+extern int vc_set_pflags(uint32_t pid, void __user *);
adc1caaa 11135+
4bf69007 11136+#endif /* _VSERVER_SIGNAL_CMD_H */
8de2f54c 11137diff -NurpP --minimal linux-4.4.111/include/linux/vserver/space.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/space.h
f19bd705 11138--- linux-4.4.111/include/linux/vserver/space.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11139+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/space.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11140@@ -0,0 +1,12 @@
11141+#ifndef _VSERVER_SPACE_H
11142+#define _VSERVER_SPACE_H
d337f35e 11143+
4bf69007 11144+#include <linux/types.h>
d337f35e 11145+
4bf69007 11146+struct vx_info;
d337f35e 11147+
4bf69007 11148+int vx_set_space(struct vx_info *vxi, unsigned long mask, unsigned index);
9f7054f1 11149+
4bf69007
AM
11150+#else /* _VSERVER_SPACE_H */
11151+#warning duplicate inclusion
11152+#endif /* _VSERVER_SPACE_H */
8de2f54c 11153diff -NurpP --minimal linux-4.4.111/include/linux/vserver/space_cmd.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/space_cmd.h
f19bd705 11154--- linux-4.4.111/include/linux/vserver/space_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11155+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/space_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11156@@ -0,0 +1,13 @@
11157+#ifndef _VSERVER_SPACE_CMD_H
11158+#define _VSERVER_SPACE_CMD_H
9f7054f1 11159+
4bf69007 11160+#include <uapi/vserver/space_cmd.h>
d337f35e 11161+
d337f35e 11162+
4bf69007
AM
11163+extern int vc_enter_space_v1(struct vx_info *, void __user *);
11164+extern int vc_set_space_v1(struct vx_info *, void __user *);
11165+extern int vc_enter_space(struct vx_info *, void __user *);
11166+extern int vc_set_space(struct vx_info *, void __user *);
11167+extern int vc_get_space_mask(void __user *, int);
d337f35e 11168+
4bf69007 11169+#endif /* _VSERVER_SPACE_CMD_H */
8de2f54c 11170diff -NurpP --minimal linux-4.4.111/include/linux/vserver/switch.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/switch.h
f19bd705 11171--- linux-4.4.111/include/linux/vserver/switch.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11172+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/switch.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11173@@ -0,0 +1,8 @@
11174+#ifndef _VSERVER_SWITCH_H
11175+#define _VSERVER_SWITCH_H
d337f35e 11176+
d337f35e 11177+
4bf69007
AM
11178+#include <linux/errno.h>
11179+#include <uapi/vserver/switch.h>
2380c486 11180+
4bf69007 11181+#endif /* _VSERVER_SWITCH_H */
8de2f54c 11182diff -NurpP --minimal linux-4.4.111/include/linux/vserver/tag.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/tag.h
f19bd705 11183--- linux-4.4.111/include/linux/vserver/tag.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11184+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/tag.h 2018-01-09 16:36:32.000000000 +0000
a4a22af8 11185@@ -0,0 +1,160 @@
4bf69007
AM
11186+#ifndef _DX_TAG_H
11187+#define _DX_TAG_H
d337f35e 11188+
4bf69007 11189+#include <linux/types.h>
a4a22af8 11190+#include <linux/uidgid.h>
d337f35e 11191+
d337f35e 11192+
4bf69007 11193+#define DX_TAG(in) (IS_TAGGED(in))
9f7054f1 11194+
d337f35e 11195+
4bf69007
AM
11196+#ifdef CONFIG_TAG_NFSD
11197+#define DX_TAG_NFSD 1
11198+#else
11199+#define DX_TAG_NFSD 0
11200+#endif
2380c486 11201+
2380c486 11202+
4bf69007 11203+#ifdef CONFIG_TAGGING_NONE
d337f35e 11204+
4bf69007
AM
11205+#define MAX_UID 0xFFFFFFFF
11206+#define MAX_GID 0xFFFFFFFF
d337f35e 11207+
4bf69007 11208+#define INOTAG_TAG(cond, uid, gid, tag) (0)
d337f35e 11209+
4bf69007
AM
11210+#define TAGINO_UID(cond, uid, tag) (uid)
11211+#define TAGINO_GID(cond, gid, tag) (gid)
d337f35e 11212+
4bf69007 11213+#endif
d337f35e 11214+
d337f35e 11215+
4bf69007 11216+#ifdef CONFIG_TAGGING_GID16
d337f35e 11217+
4bf69007
AM
11218+#define MAX_UID 0xFFFFFFFF
11219+#define MAX_GID 0x0000FFFF
d337f35e 11220+
4bf69007
AM
11221+#define INOTAG_TAG(cond, uid, gid, tag) \
11222+ ((cond) ? (((gid) >> 16) & 0xFFFF) : 0)
d337f35e 11223+
4bf69007
AM
11224+#define TAGINO_UID(cond, uid, tag) (uid)
11225+#define TAGINO_GID(cond, gid, tag) \
11226+ ((cond) ? (((gid) & 0xFFFF) | ((tag) << 16)) : (gid))
d337f35e 11227+
4bf69007 11228+#endif
d337f35e 11229+
d337f35e 11230+
4bf69007 11231+#ifdef CONFIG_TAGGING_ID24
d337f35e 11232+
4bf69007
AM
11233+#define MAX_UID 0x00FFFFFF
11234+#define MAX_GID 0x00FFFFFF
d337f35e 11235+
4bf69007
AM
11236+#define INOTAG_TAG(cond, uid, gid, tag) \
11237+ ((cond) ? ((((uid) >> 16) & 0xFF00) | (((gid) >> 24) & 0xFF)) : 0)
d337f35e 11238+
4bf69007
AM
11239+#define TAGINO_UID(cond, uid, tag) \
11240+ ((cond) ? (((uid) & 0xFFFFFF) | (((tag) & 0xFF00) << 16)) : (uid))
11241+#define TAGINO_GID(cond, gid, tag) \
11242+ ((cond) ? (((gid) & 0xFFFFFF) | (((tag) & 0x00FF) << 24)) : (gid))
d337f35e 11243+
4bf69007 11244+#endif
d337f35e 11245+
d337f35e 11246+
4bf69007 11247+#ifdef CONFIG_TAGGING_UID16
d337f35e 11248+
4bf69007
AM
11249+#define MAX_UID 0x0000FFFF
11250+#define MAX_GID 0xFFFFFFFF
3bac966d 11251+
4bf69007
AM
11252+#define INOTAG_TAG(cond, uid, gid, tag) \
11253+ ((cond) ? (((uid) >> 16) & 0xFFFF) : 0)
d337f35e 11254+
4bf69007
AM
11255+#define TAGINO_UID(cond, uid, tag) \
11256+ ((cond) ? (((uid) & 0xFFFF) | ((tag) << 16)) : (uid))
11257+#define TAGINO_GID(cond, gid, tag) (gid)
d337f35e 11258+
d33d7b00 11259+#endif
d337f35e
JR
11260+
11261+
4bf69007 11262+#ifdef CONFIG_TAGGING_INTERN
d337f35e 11263+
4bf69007
AM
11264+#define MAX_UID 0xFFFFFFFF
11265+#define MAX_GID 0xFFFFFFFF
d337f35e 11266+
4bf69007
AM
11267+#define INOTAG_TAG(cond, uid, gid, tag) \
11268+ ((cond) ? (tag) : 0)
d337f35e 11269+
4bf69007
AM
11270+#define TAGINO_UID(cond, uid, tag) (uid)
11271+#define TAGINO_GID(cond, gid, tag) (gid)
d337f35e 11272+
4bf69007 11273+#endif
d337f35e 11274+
d337f35e 11275+
4bf69007
AM
11276+#ifndef CONFIG_TAGGING_NONE
11277+#define dx_current_fstag(sb) \
11278+ ((sb)->s_flags & MS_TAGGED ? dx_current_tag() : 0)
11279+#else
11280+#define dx_current_fstag(sb) (0)
11281+#endif
d337f35e 11282+
4bf69007
AM
11283+#ifndef CONFIG_TAGGING_INTERN
11284+#define TAGINO_TAG(cond, tag) (0)
11285+#else
11286+#define TAGINO_TAG(cond, tag) ((cond) ? (tag) : 0)
11287+#endif
d337f35e 11288+
a4a22af8
AM
11289+#define TAGINO_KUID(cond, kuid, ktag) \
11290+ KUIDT_INIT(TAGINO_UID(cond, __kuid_val(kuid), __ktag_val(ktag)))
11291+#define TAGINO_KGID(cond, kgid, ktag) \
11292+ KGIDT_INIT(TAGINO_GID(cond, __kgid_val(kgid), __ktag_val(ktag)))
11293+#define TAGINO_KTAG(cond, ktag) \
11294+ KTAGT_INIT(TAGINO_TAG(cond, __ktag_val(ktag)))
11295+
11296+
4bf69007
AM
11297+#define INOTAG_UID(cond, uid, gid) \
11298+ ((cond) ? ((uid) & MAX_UID) : (uid))
11299+#define INOTAG_GID(cond, uid, gid) \
11300+ ((cond) ? ((gid) & MAX_GID) : (gid))
d337f35e 11301+
a4a22af8
AM
11302+#define INOTAG_KUID(cond, kuid, kgid) \
11303+ KUIDT_INIT(INOTAG_UID(cond, __kuid_val(kuid), __kgid_val(kgid)))
11304+#define INOTAG_KGID(cond, kuid, kgid) \
11305+ KGIDT_INIT(INOTAG_GID(cond, __kuid_val(kuid), __kgid_val(kgid)))
11306+#define INOTAG_KTAG(cond, kuid, kgid, ktag) \
11307+ KTAGT_INIT(INOTAG_TAG(cond, \
11308+ __kuid_val(kuid), __kgid_val(kgid), __ktag_val(ktag)))
11309+
d337f35e 11310+
4bf69007 11311+static inline uid_t dx_map_uid(uid_t uid)
3bac966d 11312+{
4bf69007
AM
11313+ if ((uid > MAX_UID) && (uid != -1))
11314+ uid = -2;
11315+ return (uid & MAX_UID);
d33d7b00 11316+}
d337f35e 11317+
4bf69007
AM
11318+static inline gid_t dx_map_gid(gid_t gid)
11319+{
11320+ if ((gid > MAX_GID) && (gid != -1))
11321+ gid = -2;
11322+ return (gid & MAX_GID);
11323+}
d337f35e 11324+
4bf69007
AM
11325+struct peer_tag {
11326+ int32_t xid;
11327+ int32_t nid;
d33d7b00 11328+};
d337f35e 11329+
4bf69007 11330+#define dx_notagcheck(sb) ((sb) && ((sb)->s_flags & MS_NOTAGCHECK))
2380c486 11331+
61333608 11332+int dx_parse_tag(char *string, vtag_t *tag, int remove, int *mnt_flags,
4bf69007 11333+ unsigned long *flags);
d337f35e 11334+
4bf69007 11335+#ifdef CONFIG_PROPAGATE
d337f35e 11336+
4bf69007 11337+void __dx_propagate_tag(struct nameidata *nd, struct inode *inode);
d337f35e 11338+
4bf69007 11339+#define dx_propagate_tag(n, i) __dx_propagate_tag(n, i)
d337f35e 11340+
4bf69007
AM
11341+#else
11342+#define dx_propagate_tag(n, i) do { } while (0)
11343+#endif
d337f35e 11344+
4bf69007 11345+#endif /* _DX_TAG_H */
8de2f54c 11346diff -NurpP --minimal linux-4.4.111/include/linux/vserver/tag_cmd.h linux-4.4.111-vs2.3.9.5/include/linux/vserver/tag_cmd.h
f19bd705 11347--- linux-4.4.111/include/linux/vserver/tag_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11348+++ linux-4.4.111-vs2.3.9.5/include/linux/vserver/tag_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11349@@ -0,0 +1,10 @@
11350+#ifndef _VSERVER_TAG_CMD_H
11351+#define _VSERVER_TAG_CMD_H
d337f35e 11352+
4bf69007 11353+#include <uapi/vserver/tag_cmd.h>
d337f35e 11354+
4bf69007 11355+extern int vc_task_tag(uint32_t);
3bac966d 11356+
4bf69007 11357+extern int vc_tag_migrate(uint32_t);
3bac966d 11358+
4bf69007 11359+#endif /* _VSERVER_TAG_CMD_H */
8de2f54c 11360diff -NurpP --minimal linux-4.4.111/include/net/addrconf.h linux-4.4.111-vs2.3.9.5/include/net/addrconf.h
f19bd705 11361--- linux-4.4.111/include/net/addrconf.h 2018-01-11 07:57:48.000000000 +0000
8de2f54c 11362+++ linux-4.4.111-vs2.3.9.5/include/net/addrconf.h 2018-01-09 16:36:32.000000000 +0000
927ca606 11363@@ -84,7 +84,7 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str
c2e5f7c8
JR
11364
11365 int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev,
11366 const struct in6_addr *daddr, unsigned int srcprefs,
11367- struct in6_addr *saddr);
11368+ struct in6_addr *saddr, struct nx_info *nxi);
11369 int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
bb20add7 11370 u32 banned_flags);
c2e5f7c8 11371 int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
8de2f54c 11372diff -NurpP --minimal linux-4.4.111/include/net/af_unix.h linux-4.4.111-vs2.3.9.5/include/net/af_unix.h
f19bd705 11373--- linux-4.4.111/include/net/af_unix.h 2018-01-11 07:57:48.000000000 +0000
8de2f54c 11374+++ linux-4.4.111-vs2.3.9.5/include/net/af_unix.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11375@@ -4,6 +4,7 @@
11376 #include <linux/socket.h>
11377 #include <linux/un.h>
11378 #include <linux/mutex.h>
927ca606 11379+// #include <linux/vs_base.h>
4bf69007
AM
11380 #include <net/sock.h>
11381
927ca606 11382 void unix_inflight(struct user_struct *user, struct file *fp);
8de2f54c 11383diff -NurpP --minimal linux-4.4.111/include/net/inet_timewait_sock.h linux-4.4.111-vs2.3.9.5/include/net/inet_timewait_sock.h
f19bd705 11384--- linux-4.4.111/include/net/inet_timewait_sock.h 2016-07-05 04:15:11.000000000 +0000
8de2f54c 11385+++ linux-4.4.111-vs2.3.9.5/include/net/inet_timewait_sock.h 2018-01-09 16:40:17.000000000 +0000
927ca606 11386@@ -71,6 +71,10 @@ struct inet_timewait_sock {
b00e13aa 11387 #define tw_num __tw_common.skc_num
927ca606
AM
11388 #define tw_cookie __tw_common.skc_cookie
11389 #define tw_dr __tw_common.skc_tw_dr
4bf69007
AM
11390+#define tw_xid __tw_common.skc_xid
11391+#define tw_vx_info __tw_common.skc_vx_info
11392+#define tw_nid __tw_common.skc_nid
11393+#define tw_nx_info __tw_common.skc_nx_info
b00e13aa 11394
4bf69007
AM
11395 int tw_timeout;
11396 volatile unsigned char tw_substate;
8de2f54c 11397diff -NurpP --minimal linux-4.4.111/include/net/ip6_route.h linux-4.4.111-vs2.3.9.5/include/net/ip6_route.h
f19bd705 11398--- linux-4.4.111/include/net/ip6_route.h 2018-01-11 07:57:49.000000000 +0000
8de2f54c 11399+++ linux-4.4.111-vs2.3.9.5/include/net/ip6_route.h 2018-01-09 16:36:32.000000000 +0000
927ca606 11400@@ -90,7 +90,7 @@ int ip6_del_rt(struct rt6_info *);
c2e5f7c8
JR
11401
11402 int ip6_route_get_saddr(struct net *net, struct rt6_info *rt,
11403 const struct in6_addr *daddr, unsigned int prefs,
11404- struct in6_addr *saddr);
11405+ struct in6_addr *saddr, struct nx_info *nxi);
11406
11407 struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
11408 const struct in6_addr *saddr, int oif, int flags);
8de2f54c 11409diff -NurpP --minimal linux-4.4.111/include/net/route.h linux-4.4.111-vs2.3.9.5/include/net/route.h
f19bd705 11410--- linux-4.4.111/include/net/route.h 2016-07-05 04:15:11.000000000 +0000
8de2f54c 11411+++ linux-4.4.111-vs2.3.9.5/include/net/route.h 2018-01-09 16:39:47.000000000 +0000
927ca606 11412@@ -223,6 +223,9 @@ static inline void ip_rt_put(struct rtab
b00e13aa 11413 dst_release(&rt->dst);
4bf69007
AM
11414 }
11415
11416+#include <linux/vs_base.h>
11417+#include <linux/vs_inet.h>
d337f35e 11418+
4bf69007
AM
11419 #define IPTOS_RT_MASK (IPTOS_TOS_MASK & ~3)
11420
11421 extern const __u8 ip_tos2prio[16];
927ca606 11422@@ -270,6 +273,9 @@ static inline void ip_route_connect_init
4bf69007
AM
11423 protocol, flow_flags, dst, src, dport, sport);
11424 }
11425
11426+extern struct rtable *ip_v4_find_src(struct net *net, struct nx_info *,
11427+ struct flowi4 *);
d337f35e 11428+
4bf69007
AM
11429 static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
11430 __be32 dst, __be32 src, u32 tos,
11431 int oif, u8 protocol,
927ca606 11432@@ -278,6 +284,7 @@ static inline struct rtable *ip_route_co
4bf69007
AM
11433 {
11434 struct net *net = sock_net(sk);
11435 struct rtable *rt;
11436+ struct nx_info *nx_info = current_nx_info();
11437
11438 ip_route_connect_init(fl4, dst, src, tos, oif, protocol,
f15949f2 11439 sport, dport, sk);
927ca606 11440@@ -291,7 +298,21 @@ static inline struct rtable *ip_route_co
4bf69007 11441
927ca606
AM
11442 src = fl4->saddr;
11443 }
4bf69007 11444- if (!dst || !src) {
927ca606 11445+
4bf69007
AM
11446+ if (sk)
11447+ nx_info = sk->sk_nx_info;
d337f35e 11448+
4bf69007
AM
11449+ vxdprintk(VXD_CBIT(net, 4),
11450+ "ip_route_connect(%p) %p,%p;%lx",
11451+ sk, nx_info, sk->sk_socket,
11452+ (sk->sk_socket?sk->sk_socket->flags:0));
d337f35e 11453+
4bf69007
AM
11454+ rt = ip_v4_find_src(net, nx_info, fl4);
11455+ if (IS_ERR(rt))
11456+ return rt;
11457+ ip_rt_put(rt);
d337f35e 11458+
4bf69007
AM
11459+ if (!fl4->daddr || !fl4->saddr) {
11460 rt = __ip_route_output_key(net, fl4);
11461 if (IS_ERR(rt))
11462 return rt;
8de2f54c 11463diff -NurpP --minimal linux-4.4.111/include/net/sock.h linux-4.4.111-vs2.3.9.5/include/net/sock.h
f19bd705 11464--- linux-4.4.111/include/net/sock.h 2018-01-11 07:57:49.000000000 +0000
8de2f54c 11465+++ linux-4.4.111-vs2.3.9.5/include/net/sock.h 2018-01-09 16:41:40.000000000 +0000
927ca606
AM
11466@@ -201,6 +201,10 @@ struct sock_common {
11467 struct in6_addr skc_v6_daddr;
11468 struct in6_addr skc_v6_rcv_saddr;
4bf69007 11469 #endif
61333608 11470+ vxid_t skc_xid;
4bf69007 11471+ struct vx_info *skc_vx_info;
61333608 11472+ vnid_t skc_nid;
4bf69007 11473+ struct nx_info *skc_nx_info;
c2e5f7c8 11474
927ca606
AM
11475 atomic64_t skc_cookie;
11476
11477@@ -349,8 +353,12 @@ struct sock {
4bf69007
AM
11478 #define sk_prot __sk_common.skc_prot
11479 #define sk_net __sk_common.skc_net
c2e5f7c8
JR
11480 #define sk_v6_daddr __sk_common.skc_v6_daddr
11481-#define sk_v6_rcv_saddr __sk_common.skc_v6_rcv_saddr
11482+#define sk_v6_rcv_saddr __sk_common.skc_v6_rcv_saddr
927ca606 11483 #define sk_cookie __sk_common.skc_cookie
4bf69007
AM
11484+#define sk_xid __sk_common.skc_xid
11485+#define sk_vx_info __sk_common.skc_vx_info
11486+#define sk_nid __sk_common.skc_nid
11487+#define sk_nx_info __sk_common.skc_nx_info
927ca606
AM
11488 #define sk_incoming_cpu __sk_common.skc_incoming_cpu
11489 #define sk_flags __sk_common.skc_flags
11490 #define sk_rxhash __sk_common.skc_rxhash
8de2f54c 11491diff -NurpP --minimal linux-4.4.111/include/uapi/Kbuild linux-4.4.111-vs2.3.9.5/include/uapi/Kbuild
f19bd705 11492--- linux-4.4.111/include/uapi/Kbuild 2015-04-12 22:12:50.000000000 +0000
8de2f54c 11493+++ linux-4.4.111-vs2.3.9.5/include/uapi/Kbuild 2018-01-09 16:36:32.000000000 +0000
bb20add7 11494@@ -13,3 +13,4 @@ header-y += drm/
4bf69007
AM
11495 header-y += xen/
11496 header-y += scsi/
bb20add7 11497 header-y += misc/
4bf69007 11498+header-y += vserver/
8de2f54c 11499diff -NurpP --minimal linux-4.4.111/include/uapi/linux/capability.h linux-4.4.111-vs2.3.9.5/include/uapi/linux/capability.h
f19bd705 11500--- linux-4.4.111/include/uapi/linux/capability.h 2015-04-12 22:12:50.000000000 +0000
8de2f54c 11501+++ linux-4.4.111-vs2.3.9.5/include/uapi/linux/capability.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11502@@ -259,6 +259,7 @@ struct vfs_cap_data {
11503 arbitrary SCSI commands */
11504 /* Allow setting encryption key on loopback filesystem */
11505 /* Allow setting zone reclaim policy */
11506+/* Allow the selection of a security context */
11507
11508 #define CAP_SYS_ADMIN 21
11509
bb20add7 11510@@ -354,7 +355,12 @@ struct vfs_cap_data {
4bf69007 11511
bb20add7 11512 #define CAP_LAST_CAP CAP_AUDIT_READ
4bf69007
AM
11513
11514-#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
11515+/* Allow context manipulations */
11516+/* Allow changing context info on files */
d337f35e 11517+
4bf69007 11518+#define CAP_CONTEXT 63
d337f35e 11519+
4bf69007
AM
11520+#define cap_valid(x) ((x) >= 0 && ((x) <= CAP_LAST_CAP || (x) == CAP_CONTEXT))
11521
11522 /*
11523 * Bit location of each capability (used by user-space library and kernel)
8de2f54c 11524diff -NurpP --minimal linux-4.4.111/include/uapi/linux/fs.h linux-4.4.111-vs2.3.9.5/include/uapi/linux/fs.h
f19bd705 11525--- linux-4.4.111/include/uapi/linux/fs.h 2016-07-05 04:15:11.000000000 +0000
8de2f54c 11526+++ linux-4.4.111-vs2.3.9.5/include/uapi/linux/fs.h 2018-01-09 16:47:48.000000000 +0000
927ca606 11527@@ -91,6 +91,9 @@ struct inodes_stat_t {
4bf69007
AM
11528 #define MS_I_VERSION (1<<23) /* Update inode I_version field */
11529 #define MS_STRICTATIME (1<<24) /* Always perform atime updates */
927ca606 11530 #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */
b00e13aa
AM
11531+#define MS_TAGGED (1<<8) /* use generic inode tagging */
11532+#define MS_NOTAGCHECK (1<<9) /* don't check tags */
927ca606 11533+#define MS_TAGID (1<<26) /* use specific tag for this mount */
b00e13aa
AM
11534
11535 /* These sb flags are internal to the kernel */
09be7631 11536 #define MS_NOSEC (1<<28)
927ca606 11537@@ -197,12 +200,15 @@ struct inodes_stat_t {
4bf69007
AM
11538 #define FS_EXTENT_FL 0x00080000 /* Extents */
11539 #define FS_DIRECTIO_FL 0x00100000 /* Use direct i/o */
11540 #define FS_NOCOW_FL 0x00800000 /* Do not cow file */
11541+#define FS_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */
927ca606 11542 #define FS_PROJINHERIT_FL 0x20000000 /* Create with parents projid */
4bf69007
AM
11543 #define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
11544
11545-#define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
11546-#define FS_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
927ca606 11547-
4bf69007
AM
11548+#define FS_BARRIER_FL 0x04000000 /* Barrier for chroot() */
11549+#define FS_COW_FL 0x20000000 /* Copy on Write marker */
927ca606 11550+
4bf69007
AM
11551+#define FS_FL_USER_VISIBLE 0x0103DFFF /* User visible flags */
11552+#define FS_FL_USER_MODIFIABLE 0x010380FF /* User modifiable flags */
11553
11554 #define SYNC_FILE_RANGE_WAIT_BEFORE 1
11555 #define SYNC_FILE_RANGE_WRITE 2
8de2f54c 11556diff -NurpP --minimal linux-4.4.111/include/uapi/linux/gfs2_ondisk.h linux-4.4.111-vs2.3.9.5/include/uapi/linux/gfs2_ondisk.h
f19bd705 11557--- linux-4.4.111/include/uapi/linux/gfs2_ondisk.h 2015-04-12 22:12:50.000000000 +0000
8de2f54c 11558+++ linux-4.4.111-vs2.3.9.5/include/uapi/linux/gfs2_ondisk.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11559@@ -225,6 +225,9 @@ enum {
11560 gfs2fl_Sync = 8,
11561 gfs2fl_System = 9,
11562 gfs2fl_TopLevel = 10,
11563+ gfs2fl_IXUnlink = 16,
11564+ gfs2fl_Barrier = 17,
11565+ gfs2fl_Cow = 18,
11566 gfs2fl_TruncInProg = 29,
11567 gfs2fl_InheritDirectio = 30,
11568 gfs2fl_InheritJdata = 31,
11569@@ -242,6 +245,9 @@ enum {
11570 #define GFS2_DIF_SYNC 0x00000100
11571 #define GFS2_DIF_SYSTEM 0x00000200 /* New in gfs2 */
11572 #define GFS2_DIF_TOPDIR 0x00000400 /* New in gfs2 */
11573+#define GFS2_DIF_IXUNLINK 0x00010000
11574+#define GFS2_DIF_BARRIER 0x00020000
11575+#define GFS2_DIF_COW 0x00040000
11576 #define GFS2_DIF_TRUNC_IN_PROG 0x20000000 /* New in gfs2 */
11577 #define GFS2_DIF_INHERIT_DIRECTIO 0x40000000 /* only in gfs1 */
11578 #define GFS2_DIF_INHERIT_JDATA 0x80000000
8de2f54c 11579diff -NurpP --minimal linux-4.4.111/include/uapi/linux/if_tun.h linux-4.4.111-vs2.3.9.5/include/uapi/linux/if_tun.h
f19bd705 11580--- linux-4.4.111/include/uapi/linux/if_tun.h 2015-10-29 09:21:42.000000000 +0000
8de2f54c 11581+++ linux-4.4.111-vs2.3.9.5/include/uapi/linux/if_tun.h 2018-01-09 16:46:34.000000000 +0000
927ca606
AM
11582@@ -56,6 +56,7 @@
11583 */
11584 #define TUNSETVNETBE _IOW('T', 222, int)
11585 #define TUNGETVNETBE _IOR('T', 223, int)
11586+#define TUNSETNID _IOW('T', 224, int)
4bf69007
AM
11587
11588 /* TUNSETIFF ifr flags */
11589 #define IFF_TUN 0x0001
8de2f54c 11590diff -NurpP --minimal linux-4.4.111/include/uapi/linux/major.h linux-4.4.111-vs2.3.9.5/include/uapi/linux/major.h
f19bd705 11591--- linux-4.4.111/include/uapi/linux/major.h 2015-04-12 22:12:50.000000000 +0000
8de2f54c 11592+++ linux-4.4.111-vs2.3.9.5/include/uapi/linux/major.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11593@@ -15,6 +15,7 @@
11594 #define HD_MAJOR IDE0_MAJOR
11595 #define PTY_SLAVE_MAJOR 3
11596 #define TTY_MAJOR 4
11597+#define VROOT_MAJOR 4
11598 #define TTYAUX_MAJOR 5
11599 #define LP_MAJOR 6
11600 #define VCS_MAJOR 7
8de2f54c 11601diff -NurpP --minimal linux-4.4.111/include/uapi/linux/nfs_mount.h linux-4.4.111-vs2.3.9.5/include/uapi/linux/nfs_mount.h
f19bd705 11602--- linux-4.4.111/include/uapi/linux/nfs_mount.h 2015-04-12 22:12:50.000000000 +0000
8de2f54c 11603+++ linux-4.4.111-vs2.3.9.5/include/uapi/linux/nfs_mount.h 2018-01-09 16:36:33.000000000 +0000
4bf69007 11604@@ -63,7 +63,8 @@ struct nfs_mount_data {
c2e5f7c8 11605 #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 non-text parsed mount data only */
4bf69007
AM
11606 #define NFS_MOUNT_NORDIRPLUS 0x4000 /* 5 */
11607 #define NFS_MOUNT_UNSHARED 0x8000 /* 5 */
11608-#define NFS_MOUNT_FLAGMASK 0xFFFF
11609+#define NFS_MOUNT_TAGGED 0x10000 /* context tagging */
11610+#define NFS_MOUNT_FLAGMASK 0x1FFFF
11611
11612 /* The following are for internal use only */
11613 #define NFS_MOUNT_LOOKUP_CACHE_NONEG 0x10000
8de2f54c 11614diff -NurpP --minimal linux-4.4.111/include/uapi/linux/reboot.h linux-4.4.111-vs2.3.9.5/include/uapi/linux/reboot.h
f19bd705 11615--- linux-4.4.111/include/uapi/linux/reboot.h 2015-04-12 22:12:50.000000000 +0000
8de2f54c 11616+++ linux-4.4.111-vs2.3.9.5/include/uapi/linux/reboot.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11617@@ -33,7 +33,7 @@
11618 #define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
11619 #define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2
11620 #define LINUX_REBOOT_CMD_KEXEC 0x45584543
11621-
11622+#define LINUX_REBOOT_CMD_OOM 0xDEADBEEF
11623
11624
11625 #endif /* _UAPI_LINUX_REBOOT_H */
8de2f54c 11626diff -NurpP --minimal linux-4.4.111/include/uapi/linux/sysctl.h linux-4.4.111-vs2.3.9.5/include/uapi/linux/sysctl.h
f19bd705 11627--- linux-4.4.111/include/uapi/linux/sysctl.h 2015-04-12 22:12:50.000000000 +0000
8de2f54c 11628+++ linux-4.4.111-vs2.3.9.5/include/uapi/linux/sysctl.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11629@@ -60,6 +60,7 @@ enum
11630 CTL_ABI=9, /* Binary emulation */
11631 CTL_CPU=10, /* CPU stuff (speed scaling, etc) */
11632 CTL_ARLAN=254, /* arlan wireless driver */
11633+ CTL_VSERVER=4242, /* Linux-VServer debug */
11634 CTL_S390DBF=5677, /* s390 debug */
11635 CTL_SUNRPC=7249, /* sunrpc debug */
11636 CTL_PM=9899, /* frv power management */
11637@@ -94,6 +95,7 @@ enum
11638
11639 KERN_PANIC=15, /* int: panic timeout */
11640 KERN_REALROOTDEV=16, /* real root device to mount after initrd */
11641+ KERN_VSHELPER=17, /* string: path to vshelper policy agent */
11642
11643 KERN_SPARC_REBOOT=21, /* reboot command on Sparc */
11644 KERN_CTLALTDEL=22, /* int: allow ctl-alt-del to reboot */
8de2f54c 11645diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/Kbuild linux-4.4.111-vs2.3.9.5/include/uapi/vserver/Kbuild
f19bd705 11646--- linux-4.4.111/include/uapi/vserver/Kbuild 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11647+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/Kbuild 2018-01-09 16:36:33.000000000 +0000
4bf69007 11648@@ -0,0 +1,9 @@
d337f35e 11649+
4bf69007
AM
11650+header-y += context_cmd.h network_cmd.h space_cmd.h \
11651+ cacct_cmd.h cvirt_cmd.h limit_cmd.h dlimit_cmd.h \
11652+ inode_cmd.h tag_cmd.h sched_cmd.h signal_cmd.h \
11653+ debug_cmd.h device_cmd.h
2380c486 11654+
4bf69007
AM
11655+header-y += switch.h context.h network.h monitor.h \
11656+ limit.h inode.h device.h
2380c486 11657+
8de2f54c 11658diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/cacct_cmd.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/cacct_cmd.h
f19bd705 11659--- linux-4.4.111/include/uapi/vserver/cacct_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11660+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/cacct_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11661@@ -0,0 +1,15 @@
11662+#ifndef _UAPI_VS_CACCT_CMD_H
11663+#define _UAPI_VS_CACCT_CMD_H
d337f35e
JR
11664+
11665+
4bf69007 11666+/* virtual host info name commands */
d337f35e 11667+
4bf69007 11668+#define VCMD_sock_stat VC_CMD(VSTAT, 5, 0)
d337f35e 11669+
4bf69007
AM
11670+struct vcmd_sock_stat_v0 {
11671+ uint32_t field;
11672+ uint32_t count[3];
11673+ uint64_t total[3];
11674+};
d337f35e 11675+
4bf69007 11676+#endif /* _UAPI_VS_CACCT_CMD_H */
8de2f54c 11677diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/context.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/context.h
f19bd705 11678--- linux-4.4.111/include/uapi/vserver/context.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11679+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/context.h 2018-01-09 16:36:33.000000000 +0000
b00e13aa 11680@@ -0,0 +1,81 @@
4bf69007
AM
11681+#ifndef _UAPI_VS_CONTEXT_H
11682+#define _UAPI_VS_CONTEXT_H
d337f35e 11683+
4bf69007
AM
11684+#include <linux/types.h>
11685+#include <linux/capability.h>
d337f35e
JR
11686+
11687+
4bf69007 11688+/* context flags */
d337f35e 11689+
4bf69007
AM
11690+#define VXF_INFO_SCHED 0x00000002
11691+#define VXF_INFO_NPROC 0x00000004
11692+#define VXF_INFO_PRIVATE 0x00000008
d337f35e 11693+
4bf69007
AM
11694+#define VXF_INFO_INIT 0x00000010
11695+#define VXF_INFO_HIDE 0x00000020
11696+#define VXF_INFO_ULIMIT 0x00000040
11697+#define VXF_INFO_NSPACE 0x00000080
d337f35e 11698+
4bf69007
AM
11699+#define VXF_SCHED_HARD 0x00000100
11700+#define VXF_SCHED_PRIO 0x00000200
11701+#define VXF_SCHED_PAUSE 0x00000400
2380c486 11702+
4bf69007
AM
11703+#define VXF_VIRT_MEM 0x00010000
11704+#define VXF_VIRT_UPTIME 0x00020000
11705+#define VXF_VIRT_CPU 0x00040000
11706+#define VXF_VIRT_LOAD 0x00080000
11707+#define VXF_VIRT_TIME 0x00100000
d337f35e 11708+
4bf69007
AM
11709+#define VXF_HIDE_MOUNT 0x01000000
11710+/* was VXF_HIDE_NETIF 0x02000000 */
11711+#define VXF_HIDE_VINFO 0x04000000
d337f35e 11712+
4bf69007
AM
11713+#define VXF_STATE_SETUP (1ULL << 32)
11714+#define VXF_STATE_INIT (1ULL << 33)
11715+#define VXF_STATE_ADMIN (1ULL << 34)
d337f35e 11716+
4bf69007
AM
11717+#define VXF_SC_HELPER (1ULL << 36)
11718+#define VXF_REBOOT_KILL (1ULL << 37)
11719+#define VXF_PERSISTENT (1ULL << 38)
d337f35e 11720+
4bf69007
AM
11721+#define VXF_FORK_RSS (1ULL << 48)
11722+#define VXF_PROLIFIC (1ULL << 49)
d337f35e 11723+
4bf69007 11724+#define VXF_IGNEG_NICE (1ULL << 52)
d337f35e 11725+
4bf69007 11726+#define VXF_ONE_TIME (0x0007ULL << 32)
d337f35e 11727+
4bf69007 11728+#define VXF_INIT_SET (VXF_STATE_SETUP | VXF_STATE_INIT | VXF_STATE_ADMIN)
d337f35e
JR
11729+
11730+
4bf69007 11731+/* context migration */
d337f35e 11732+
4bf69007
AM
11733+#define VXM_SET_INIT 0x00000001
11734+#define VXM_SET_REAPER 0x00000002
d337f35e 11735+
4bf69007 11736+/* context caps */
d337f35e 11737+
4bf69007
AM
11738+#define VXC_SET_UTSNAME 0x00000001
11739+#define VXC_SET_RLIMIT 0x00000002
11740+#define VXC_FS_SECURITY 0x00000004
11741+#define VXC_FS_TRUSTED 0x00000008
11742+#define VXC_TIOCSTI 0x00000010
2380c486 11743+
4bf69007
AM
11744+/* was VXC_RAW_ICMP 0x00000100 */
11745+#define VXC_SYSLOG 0x00001000
11746+#define VXC_OOM_ADJUST 0x00002000
11747+#define VXC_AUDIT_CONTROL 0x00004000
d337f35e 11748+
c2e5f7c8
JR
11749+#define VXC_SECURE_MOUNT 0x00010000
11750+/* #define VXC_SECURE_REMOUNT 0x00020000 */
4bf69007 11751+#define VXC_BINARY_MOUNT 0x00040000
b00e13aa 11752+#define VXC_DEV_MOUNT 0x00080000
d337f35e 11753+
4bf69007
AM
11754+#define VXC_QUOTA_CTL 0x00100000
11755+#define VXC_ADMIN_MAPPER 0x00200000
11756+#define VXC_ADMIN_CLOOP 0x00400000
d337f35e 11757+
4bf69007
AM
11758+#define VXC_KTHREAD 0x01000000
11759+#define VXC_NAMESPACE 0x02000000
d337f35e 11760+
4bf69007 11761+#endif /* _UAPI_VS_CONTEXT_H */
8de2f54c 11762diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/context_cmd.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/context_cmd.h
f19bd705 11763--- linux-4.4.111/include/uapi/vserver/context_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11764+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/context_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11765@@ -0,0 +1,115 @@
11766+#ifndef _UAPI_VS_CONTEXT_CMD_H
11767+#define _UAPI_VS_CONTEXT_CMD_H
d33d7b00
AM
11768+
11769+
4bf69007 11770+/* vinfo commands */
3bac966d 11771+
4bf69007 11772+#define VCMD_task_xid VC_CMD(VINFO, 1, 0)
3bac966d 11773+
3bac966d 11774+
4bf69007 11775+#define VCMD_vx_info VC_CMD(VINFO, 5, 0)
3bac966d 11776+
4bf69007
AM
11777+struct vcmd_vx_info_v0 {
11778+ uint32_t xid;
11779+ uint32_t initpid;
11780+ /* more to come */
11781+};
3bac966d
AM
11782+
11783+
4bf69007 11784+#define VCMD_ctx_stat VC_CMD(VSTAT, 0, 0)
3bac966d 11785+
4bf69007
AM
11786+struct vcmd_ctx_stat_v0 {
11787+ uint32_t usecnt;
11788+ uint32_t tasks;
11789+ /* more to come */
11790+};
3bac966d 11791+
3bac966d 11792+
4bf69007 11793+/* context commands */
3bac966d 11794+
4bf69007
AM
11795+#define VCMD_ctx_create_v0 VC_CMD(VPROC, 1, 0)
11796+#define VCMD_ctx_create VC_CMD(VPROC, 1, 1)
3bac966d 11797+
4bf69007
AM
11798+struct vcmd_ctx_create {
11799+ uint64_t flagword;
11800+};
3bac966d 11801+
4bf69007
AM
11802+#define VCMD_ctx_migrate_v0 VC_CMD(PROCMIG, 1, 0)
11803+#define VCMD_ctx_migrate VC_CMD(PROCMIG, 1, 1)
3bac966d 11804+
4bf69007
AM
11805+struct vcmd_ctx_migrate {
11806+ uint64_t flagword;
11807+};
3bac966d 11808+
d33d7b00 11809+
d33d7b00 11810+
4bf69007 11811+/* flag commands */
d33d7b00 11812+
4bf69007
AM
11813+#define VCMD_get_cflags VC_CMD(FLAGS, 1, 0)
11814+#define VCMD_set_cflags VC_CMD(FLAGS, 2, 0)
d33d7b00 11815+
4bf69007
AM
11816+struct vcmd_ctx_flags_v0 {
11817+ uint64_t flagword;
11818+ uint64_t mask;
11819+};
3bac966d
AM
11820+
11821+
3bac966d 11822+
4bf69007 11823+/* context caps commands */
3bac966d 11824+
4bf69007
AM
11825+#define VCMD_get_ccaps VC_CMD(FLAGS, 3, 1)
11826+#define VCMD_set_ccaps VC_CMD(FLAGS, 4, 1)
d33d7b00 11827+
4bf69007
AM
11828+struct vcmd_ctx_caps_v1 {
11829+ uint64_t ccaps;
11830+ uint64_t cmask;
11831+};
d33d7b00 11832+
d33d7b00
AM
11833+
11834+
4bf69007 11835+/* bcaps commands */
d33d7b00 11836+
4bf69007
AM
11837+#define VCMD_get_bcaps VC_CMD(FLAGS, 9, 0)
11838+#define VCMD_set_bcaps VC_CMD(FLAGS, 10, 0)
d33d7b00 11839+
4bf69007
AM
11840+struct vcmd_bcaps {
11841+ uint64_t bcaps;
11842+ uint64_t bmask;
11843+};
3bac966d 11844+
d33d7b00 11845+
d33d7b00 11846+
4bf69007 11847+/* umask commands */
d33d7b00 11848+
4bf69007
AM
11849+#define VCMD_get_umask VC_CMD(FLAGS, 13, 0)
11850+#define VCMD_set_umask VC_CMD(FLAGS, 14, 0)
3bac966d 11851+
4bf69007
AM
11852+struct vcmd_umask {
11853+ uint64_t umask;
11854+ uint64_t mask;
11855+};
d33d7b00 11856+
d33d7b00
AM
11857+
11858+
4bf69007 11859+/* wmask commands */
d33d7b00 11860+
4bf69007
AM
11861+#define VCMD_get_wmask VC_CMD(FLAGS, 15, 0)
11862+#define VCMD_set_wmask VC_CMD(FLAGS, 16, 0)
d33d7b00 11863+
4bf69007
AM
11864+struct vcmd_wmask {
11865+ uint64_t wmask;
11866+ uint64_t mask;
d33d7b00
AM
11867+};
11868+
d33d7b00 11869+
d33d7b00 11870+
4bf69007 11871+/* OOM badness */
d33d7b00 11872+
4bf69007
AM
11873+#define VCMD_get_badness VC_CMD(MEMCTRL, 5, 0)
11874+#define VCMD_set_badness VC_CMD(MEMCTRL, 6, 0)
d33d7b00 11875+
4bf69007
AM
11876+struct vcmd_badness_v0 {
11877+ int64_t bias;
11878+};
d33d7b00 11879+
4bf69007 11880+#endif /* _UAPI_VS_CONTEXT_CMD_H */
8de2f54c 11881diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/cvirt_cmd.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/cvirt_cmd.h
f19bd705 11882--- linux-4.4.111/include/uapi/vserver/cvirt_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11883+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/cvirt_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11884@@ -0,0 +1,41 @@
11885+#ifndef _UAPI_VS_CVIRT_CMD_H
11886+#define _UAPI_VS_CVIRT_CMD_H
d33d7b00 11887+
d33d7b00 11888+
4bf69007 11889+/* virtual host info name commands */
d33d7b00 11890+
4bf69007
AM
11891+#define VCMD_set_vhi_name VC_CMD(VHOST, 1, 0)
11892+#define VCMD_get_vhi_name VC_CMD(VHOST, 2, 0)
d33d7b00 11893+
4bf69007
AM
11894+struct vcmd_vhi_name_v0 {
11895+ uint32_t field;
11896+ char name[65];
11897+};
d33d7b00 11898+
d33d7b00 11899+
4bf69007
AM
11900+enum vhi_name_field {
11901+ VHIN_CONTEXT = 0,
11902+ VHIN_SYSNAME,
11903+ VHIN_NODENAME,
11904+ VHIN_RELEASE,
11905+ VHIN_VERSION,
11906+ VHIN_MACHINE,
11907+ VHIN_DOMAINNAME,
11908+};
d33d7b00 11909+
d33d7b00 11910+
d33d7b00 11911+
4bf69007 11912+#define VCMD_virt_stat VC_CMD(VSTAT, 3, 0)
d33d7b00 11913+
4bf69007
AM
11914+struct vcmd_virt_stat_v0 {
11915+ uint64_t offset;
11916+ uint64_t uptime;
11917+ uint32_t nr_threads;
11918+ uint32_t nr_running;
11919+ uint32_t nr_uninterruptible;
11920+ uint32_t nr_onhold;
11921+ uint32_t nr_forks;
11922+ uint32_t load[3];
11923+};
2380c486 11924+
4bf69007 11925+#endif /* _UAPI_VS_CVIRT_CMD_H */
8de2f54c 11926diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/debug_cmd.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/debug_cmd.h
f19bd705 11927--- linux-4.4.111/include/uapi/vserver/debug_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11928+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/debug_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11929@@ -0,0 +1,24 @@
11930+#ifndef _UAPI_VS_DEBUG_CMD_H
11931+#define _UAPI_VS_DEBUG_CMD_H
537831f9 11932+
537831f9 11933+
4bf69007 11934+/* debug commands */
537831f9 11935+
4bf69007 11936+#define VCMD_dump_history VC_CMD(DEBUG, 1, 0)
537831f9 11937+
4bf69007
AM
11938+#define VCMD_read_history VC_CMD(DEBUG, 5, 0)
11939+#define VCMD_read_monitor VC_CMD(DEBUG, 6, 0)
537831f9 11940+
4bf69007
AM
11941+struct vcmd_read_history_v0 {
11942+ uint32_t index;
11943+ uint32_t count;
11944+ char __user *data;
11945+};
537831f9 11946+
4bf69007
AM
11947+struct vcmd_read_monitor_v0 {
11948+ uint32_t index;
11949+ uint32_t count;
11950+ char __user *data;
11951+};
537831f9 11952+
4bf69007 11953+#endif /* _UAPI_VS_DEBUG_CMD_H */
8de2f54c 11954diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/device.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/device.h
f19bd705 11955--- linux-4.4.111/include/uapi/vserver/device.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11956+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/device.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11957@@ -0,0 +1,12 @@
11958+#ifndef _UAPI_VS_DEVICE_H
11959+#define _UAPI_VS_DEVICE_H
d337f35e 11960+
d337f35e 11961+
4bf69007
AM
11962+#define DATTR_CREATE 0x00000001
11963+#define DATTR_OPEN 0x00000002
d337f35e 11964+
4bf69007 11965+#define DATTR_REMAP 0x00000010
d337f35e 11966+
4bf69007 11967+#define DATTR_MASK 0x00000013
ec22aa5c 11968+
4bf69007 11969+#endif /* _UAPI_VS_DEVICE_H */
8de2f54c 11970diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/device_cmd.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/device_cmd.h
f19bd705 11971--- linux-4.4.111/include/uapi/vserver/device_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11972+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/device_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11973@@ -0,0 +1,16 @@
11974+#ifndef _UAPI_VS_DEVICE_CMD_H
11975+#define _UAPI_VS_DEVICE_CMD_H
2380c486 11976+
1163e6ab 11977+
4bf69007 11978+/* device vserver commands */
1163e6ab 11979+
4bf69007
AM
11980+#define VCMD_set_mapping VC_CMD(DEVICE, 1, 0)
11981+#define VCMD_unset_mapping VC_CMD(DEVICE, 2, 0)
e915af4e 11982+
4bf69007
AM
11983+struct vcmd_set_mapping_v0 {
11984+ const char __user *device;
11985+ const char __user *target;
11986+ uint32_t flags;
11987+};
e915af4e 11988+
4bf69007 11989+#endif /* _UAPI_VS_DEVICE_CMD_H */
8de2f54c 11990diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/dlimit_cmd.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/dlimit_cmd.h
f19bd705 11991--- linux-4.4.111/include/uapi/vserver/dlimit_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 11992+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/dlimit_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11993@@ -0,0 +1,67 @@
11994+#ifndef _UAPI_VS_DLIMIT_CMD_H
11995+#define _UAPI_VS_DLIMIT_CMD_H
e915af4e 11996+
42bc425c 11997+
4bf69007 11998+/* dlimit vserver commands */
d337f35e 11999+
4bf69007
AM
12000+#define VCMD_add_dlimit VC_CMD(DLIMIT, 1, 0)
12001+#define VCMD_rem_dlimit VC_CMD(DLIMIT, 2, 0)
d337f35e 12002+
4bf69007
AM
12003+#define VCMD_set_dlimit VC_CMD(DLIMIT, 5, 0)
12004+#define VCMD_get_dlimit VC_CMD(DLIMIT, 6, 0)
d337f35e 12005+
4bf69007
AM
12006+struct vcmd_ctx_dlimit_base_v0 {
12007+ const char __user *name;
12008+ uint32_t flags;
12009+};
12010+
12011+struct vcmd_ctx_dlimit_v0 {
12012+ const char __user *name;
12013+ uint32_t space_used; /* used space in kbytes */
12014+ uint32_t space_total; /* maximum space in kbytes */
12015+ uint32_t inodes_used; /* used inodes */
12016+ uint32_t inodes_total; /* maximum inodes */
12017+ uint32_t reserved; /* reserved for root in % */
12018+ uint32_t flags;
12019+};
12020+
12021+#define CDLIM_UNSET ((uint32_t)0UL)
12022+#define CDLIM_INFINITY ((uint32_t)~0UL)
12023+#define CDLIM_KEEP ((uint32_t)~1UL)
12024+
12025+#define DLIME_UNIT 0
12026+#define DLIME_KILO 1
12027+#define DLIME_MEGA 2
12028+#define DLIME_GIGA 3
12029+
12030+#define DLIMF_SHIFT 0x10
12031+
12032+#define DLIMS_USED 0
12033+#define DLIMS_TOTAL 2
12034+
12035+static inline
12036+uint64_t dlimit_space_32to64(uint32_t val, uint32_t flags, int shift)
2380c486 12037+{
4bf69007
AM
12038+ int exp = (flags & DLIMF_SHIFT) ?
12039+ (flags >> shift) & DLIME_GIGA : DLIME_KILO;
12040+ return ((uint64_t)val) << (10 * exp);
2380c486
JR
12041+}
12042+
4bf69007
AM
12043+static inline
12044+uint32_t dlimit_space_64to32(uint64_t val, uint32_t *flags, int shift)
2380c486 12045+{
4bf69007 12046+ int exp = 0;
ec22aa5c 12047+
4bf69007
AM
12048+ if (*flags & DLIMF_SHIFT) {
12049+ while (val > (1LL << 32) && (exp < 3)) {
12050+ val >>= 10;
12051+ exp++;
12052+ }
12053+ *flags &= ~(DLIME_GIGA << shift);
12054+ *flags |= exp << shift;
12055+ } else
12056+ val >>= 10;
12057+ return val;
2380c486
JR
12058+}
12059+
4bf69007 12060+#endif /* _UAPI_VS_DLIMIT_CMD_H */
8de2f54c 12061diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/inode.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/inode.h
f19bd705 12062--- linux-4.4.111/include/uapi/vserver/inode.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 12063+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/inode.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12064@@ -0,0 +1,23 @@
12065+#ifndef _UAPI_VS_INODE_H
12066+#define _UAPI_VS_INODE_H
2380c486 12067+
d337f35e 12068+
4bf69007 12069+#define IATTR_TAG 0x01000000
2380c486 12070+
4bf69007
AM
12071+#define IATTR_ADMIN 0x00000001
12072+#define IATTR_WATCH 0x00000002
12073+#define IATTR_HIDE 0x00000004
12074+#define IATTR_FLAGS 0x00000007
2380c486 12075+
4bf69007
AM
12076+#define IATTR_BARRIER 0x00010000
12077+#define IATTR_IXUNLINK 0x00020000
12078+#define IATTR_IMMUTABLE 0x00040000
12079+#define IATTR_COW 0x00080000
d337f35e 12080+
ec22aa5c 12081+
4bf69007 12082+/* inode ioctls */
ec22aa5c 12083+
4bf69007
AM
12084+#define FIOC_GETXFLG _IOR('x', 5, long)
12085+#define FIOC_SETXFLG _IOW('x', 6, long)
d337f35e 12086+
4bf69007 12087+#endif /* _UAPI_VS_INODE_H */
8de2f54c 12088diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/inode_cmd.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/inode_cmd.h
f19bd705 12089--- linux-4.4.111/include/uapi/vserver/inode_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 12090+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/inode_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12091@@ -0,0 +1,26 @@
12092+#ifndef _UAPI_VS_INODE_CMD_H
12093+#define _UAPI_VS_INODE_CMD_H
d337f35e 12094+
db55b927 12095+
4bf69007 12096+/* inode vserver commands */
2c8c5bc5 12097+
4bf69007
AM
12098+#define VCMD_get_iattr VC_CMD(INODE, 1, 1)
12099+#define VCMD_set_iattr VC_CMD(INODE, 2, 1)
2bf5ad28 12100+
4bf69007
AM
12101+#define VCMD_fget_iattr VC_CMD(INODE, 3, 0)
12102+#define VCMD_fset_iattr VC_CMD(INODE, 4, 0)
4a036bed 12103+
4bf69007
AM
12104+struct vcmd_ctx_iattr_v1 {
12105+ const char __user *name;
12106+ uint32_t tag;
12107+ uint32_t flags;
12108+ uint32_t mask;
12109+};
4a036bed 12110+
4bf69007
AM
12111+struct vcmd_ctx_fiattr_v0 {
12112+ uint32_t tag;
12113+ uint32_t flags;
12114+ uint32_t mask;
12115+};
4a036bed 12116+
4bf69007 12117+#endif /* _UAPI_VS_INODE_CMD_H */
8de2f54c 12118diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/limit.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/limit.h
f19bd705 12119--- linux-4.4.111/include/uapi/vserver/limit.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 12120+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/limit.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12121@@ -0,0 +1,14 @@
12122+#ifndef _UAPI_VS_LIMIT_H
12123+#define _UAPI_VS_LIMIT_H
4a036bed 12124+
42bc425c 12125+
4bf69007
AM
12126+#define VLIMIT_NSOCK 16
12127+#define VLIMIT_OPENFD 17
12128+#define VLIMIT_ANON 18
12129+#define VLIMIT_SHMEM 19
12130+#define VLIMIT_SEMARY 20
12131+#define VLIMIT_NSEMS 21
12132+#define VLIMIT_DENTRY 22
12133+#define VLIMIT_MAPPED 23
adc1caaa 12134+
4bf69007 12135+#endif /* _UAPI_VS_LIMIT_H */
8de2f54c 12136diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/limit_cmd.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/limit_cmd.h
f19bd705 12137--- linux-4.4.111/include/uapi/vserver/limit_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 12138+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/limit_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12139@@ -0,0 +1,40 @@
12140+#ifndef _UAPI_VS_LIMIT_CMD_H
12141+#define _UAPI_VS_LIMIT_CMD_H
adc1caaa 12142+
adc1caaa 12143+
4bf69007 12144+/* rlimit vserver commands */
adc1caaa 12145+
4bf69007
AM
12146+#define VCMD_get_rlimit VC_CMD(RLIMIT, 1, 0)
12147+#define VCMD_set_rlimit VC_CMD(RLIMIT, 2, 0)
12148+#define VCMD_get_rlimit_mask VC_CMD(RLIMIT, 3, 0)
12149+#define VCMD_reset_hits VC_CMD(RLIMIT, 7, 0)
12150+#define VCMD_reset_minmax VC_CMD(RLIMIT, 9, 0)
adc1caaa 12151+
4bf69007
AM
12152+struct vcmd_ctx_rlimit_v0 {
12153+ uint32_t id;
12154+ uint64_t minimum;
12155+ uint64_t softlimit;
12156+ uint64_t maximum;
12157+};
d33d7b00 12158+
4bf69007
AM
12159+struct vcmd_ctx_rlimit_mask_v0 {
12160+ uint32_t minimum;
12161+ uint32_t softlimit;
12162+ uint32_t maximum;
12163+};
d33d7b00 12164+
4bf69007 12165+#define VCMD_rlimit_stat VC_CMD(VSTAT, 1, 0)
d33d7b00 12166+
4bf69007
AM
12167+struct vcmd_rlimit_stat_v0 {
12168+ uint32_t id;
12169+ uint32_t hits;
12170+ uint64_t value;
12171+ uint64_t minimum;
12172+ uint64_t maximum;
12173+};
d33d7b00 12174+
4bf69007
AM
12175+#define CRLIM_UNSET (0ULL)
12176+#define CRLIM_INFINITY (~0ULL)
12177+#define CRLIM_KEEP (~1ULL)
d33d7b00 12178+
4bf69007 12179+#endif /* _UAPI_VS_LIMIT_CMD_H */
8de2f54c 12180diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/monitor.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/monitor.h
f19bd705 12181--- linux-4.4.111/include/uapi/vserver/monitor.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 12182+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/monitor.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12183@@ -0,0 +1,96 @@
12184+#ifndef _UAPI_VS_MONITOR_H
12185+#define _UAPI_VS_MONITOR_H
d33d7b00 12186+
4bf69007 12187+#include <linux/types.h>
d33d7b00 12188+
d33d7b00 12189+
4bf69007
AM
12190+enum {
12191+ VXM_UNUSED = 0,
d33d7b00 12192+
4bf69007 12193+ VXM_SYNC = 0x10,
d33d7b00 12194+
4bf69007
AM
12195+ VXM_UPDATE = 0x20,
12196+ VXM_UPDATE_1,
12197+ VXM_UPDATE_2,
d33d7b00 12198+
4bf69007
AM
12199+ VXM_RQINFO_1 = 0x24,
12200+ VXM_RQINFO_2,
d33d7b00 12201+
4bf69007
AM
12202+ VXM_ACTIVATE = 0x40,
12203+ VXM_DEACTIVATE,
12204+ VXM_IDLE,
d33d7b00 12205+
4bf69007
AM
12206+ VXM_HOLD = 0x44,
12207+ VXM_UNHOLD,
d33d7b00 12208+
4bf69007
AM
12209+ VXM_MIGRATE = 0x48,
12210+ VXM_RESCHED,
d33d7b00 12211+
4bf69007
AM
12212+ /* all other bits are flags */
12213+ VXM_SCHED = 0x80,
12214+};
d33d7b00 12215+
4bf69007
AM
12216+struct _vxm_update_1 {
12217+ uint32_t tokens_max;
12218+ uint32_t fill_rate;
12219+ uint32_t interval;
12220+};
d33d7b00 12221+
4bf69007
AM
12222+struct _vxm_update_2 {
12223+ uint32_t tokens_min;
12224+ uint32_t fill_rate;
12225+ uint32_t interval;
12226+};
d33d7b00 12227+
4bf69007
AM
12228+struct _vxm_rqinfo_1 {
12229+ uint16_t running;
12230+ uint16_t onhold;
12231+ uint16_t iowait;
12232+ uint16_t uintr;
12233+ uint32_t idle_tokens;
12234+};
d33d7b00 12235+
4bf69007
AM
12236+struct _vxm_rqinfo_2 {
12237+ uint32_t norm_time;
12238+ uint32_t idle_time;
12239+ uint32_t idle_skip;
12240+};
d33d7b00 12241+
4bf69007
AM
12242+struct _vxm_sched {
12243+ uint32_t tokens;
12244+ uint32_t norm_time;
12245+ uint32_t idle_time;
12246+};
d33d7b00 12247+
4bf69007
AM
12248+struct _vxm_task {
12249+ uint16_t pid;
12250+ uint16_t state;
12251+};
d33d7b00 12252+
4bf69007
AM
12253+struct _vxm_event {
12254+ uint32_t jif;
12255+ union {
12256+ uint32_t seq;
12257+ uint32_t sec;
12258+ };
12259+ union {
12260+ uint32_t tokens;
12261+ uint32_t nsec;
12262+ struct _vxm_task tsk;
12263+ };
12264+};
61b0c03f 12265+
4bf69007
AM
12266+struct _vx_mon_entry {
12267+ uint16_t type;
12268+ uint16_t xid;
12269+ union {
12270+ struct _vxm_event ev;
12271+ struct _vxm_sched sd;
12272+ struct _vxm_update_1 u1;
12273+ struct _vxm_update_2 u2;
12274+ struct _vxm_rqinfo_1 q1;
12275+ struct _vxm_rqinfo_2 q2;
12276+ };
12277+};
d33d7b00 12278+
4bf69007 12279+#endif /* _UAPI_VS_MONITOR_H */
8de2f54c 12280diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/network.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/network.h
f19bd705 12281--- linux-4.4.111/include/uapi/vserver/network.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 12282+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/network.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12283@@ -0,0 +1,76 @@
12284+#ifndef _UAPI_VS_NETWORK_H
12285+#define _UAPI_VS_NETWORK_H
d33d7b00 12286+
4bf69007 12287+#include <linux/types.h>
d33d7b00 12288+
d33d7b00 12289+
4bf69007 12290+#define MAX_N_CONTEXT 65535 /* Arbitrary limit */
d33d7b00 12291+
d33d7b00 12292+
4bf69007 12293+/* network flags */
d33d7b00 12294+
4bf69007 12295+#define NXF_INFO_PRIVATE 0x00000008
d33d7b00 12296+
4bf69007
AM
12297+#define NXF_SINGLE_IP 0x00000100
12298+#define NXF_LBACK_REMAP 0x00000200
12299+#define NXF_LBACK_ALLOW 0x00000400
d33d7b00 12300+
4bf69007
AM
12301+#define NXF_HIDE_NETIF 0x02000000
12302+#define NXF_HIDE_LBACK 0x04000000
265d6dcc 12303+
4bf69007
AM
12304+#define NXF_STATE_SETUP (1ULL << 32)
12305+#define NXF_STATE_ADMIN (1ULL << 34)
d33d7b00 12306+
4bf69007
AM
12307+#define NXF_SC_HELPER (1ULL << 36)
12308+#define NXF_PERSISTENT (1ULL << 38)
d33d7b00 12309+
4bf69007 12310+#define NXF_ONE_TIME (0x0005ULL << 32)
d33d7b00 12311+
d33d7b00 12312+
4bf69007 12313+#define NXF_INIT_SET (__nxf_init_set())
d33d7b00 12314+
4bf69007
AM
12315+static inline uint64_t __nxf_init_set(void) {
12316+ return NXF_STATE_ADMIN
12317+#ifdef CONFIG_VSERVER_AUTO_LBACK
12318+ | NXF_LBACK_REMAP
12319+ | NXF_HIDE_LBACK
12320+#endif
12321+#ifdef CONFIG_VSERVER_AUTO_SINGLE
12322+ | NXF_SINGLE_IP
12323+#endif
12324+ | NXF_HIDE_NETIF;
12325+}
d33d7b00 12326+
d33d7b00 12327+
4bf69007 12328+/* network caps */
d33d7b00 12329+
4bf69007 12330+#define NXC_TUN_CREATE 0x00000001
d33d7b00 12331+
4bf69007 12332+#define NXC_RAW_ICMP 0x00000100
d33d7b00 12333+
4bf69007 12334+#define NXC_MULTICAST 0x00001000
d33d7b00 12335+
adc1caaa 12336+
4bf69007 12337+/* address types */
adc1caaa 12338+
4bf69007
AM
12339+#define NXA_TYPE_IPV4 0x0001
12340+#define NXA_TYPE_IPV6 0x0002
adc1caaa 12341+
4bf69007
AM
12342+#define NXA_TYPE_NONE 0x0000
12343+#define NXA_TYPE_ANY 0x00FF
adc1caaa 12344+
4bf69007
AM
12345+#define NXA_TYPE_ADDR 0x0010
12346+#define NXA_TYPE_MASK 0x0020
12347+#define NXA_TYPE_RANGE 0x0040
adc1caaa 12348+
4bf69007 12349+#define NXA_MASK_ALL (NXA_TYPE_ADDR | NXA_TYPE_MASK | NXA_TYPE_RANGE)
adc1caaa 12350+
4bf69007
AM
12351+#define NXA_MOD_BCAST 0x0100
12352+#define NXA_MOD_LBACK 0x0200
adc1caaa 12353+
4bf69007 12354+#define NXA_LOOPBACK 0x1000
2380c486 12355+
4bf69007
AM
12356+#define NXA_MASK_BIND (NXA_MASK_ALL | NXA_MOD_BCAST | NXA_MOD_LBACK)
12357+#define NXA_MASK_SHOW (NXA_MASK_ALL | NXA_LOOPBACK)
2380c486 12358+
4bf69007 12359+#endif /* _UAPI_VS_NETWORK_H */
8de2f54c 12360diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/network_cmd.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/network_cmd.h
f19bd705 12361--- linux-4.4.111/include/uapi/vserver/network_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 12362+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/network_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12363@@ -0,0 +1,123 @@
12364+#ifndef _UAPI_VS_NETWORK_CMD_H
12365+#define _UAPI_VS_NETWORK_CMD_H
2380c486 12366+
2380c486 12367+
4bf69007 12368+/* vinfo commands */
2380c486 12369+
4bf69007 12370+#define VCMD_task_nid VC_CMD(VINFO, 2, 0)
2380c486 12371+
2380c486 12372+
4bf69007 12373+#define VCMD_nx_info VC_CMD(VINFO, 6, 0)
2380c486 12374+
4bf69007
AM
12375+struct vcmd_nx_info_v0 {
12376+ uint32_t nid;
12377+ /* more to come */
12378+};
2380c486 12379+
2380c486 12380+
4bf69007
AM
12381+#include <linux/in.h>
12382+#include <linux/in6.h>
2380c486 12383+
4bf69007
AM
12384+#define VCMD_net_create_v0 VC_CMD(VNET, 1, 0)
12385+#define VCMD_net_create VC_CMD(VNET, 1, 1)
2380c486 12386+
4bf69007
AM
12387+struct vcmd_net_create {
12388+ uint64_t flagword;
12389+};
2380c486 12390+
4bf69007 12391+#define VCMD_net_migrate VC_CMD(NETMIG, 1, 0)
2380c486 12392+
4bf69007
AM
12393+#define VCMD_net_add VC_CMD(NETALT, 1, 0)
12394+#define VCMD_net_remove VC_CMD(NETALT, 2, 0)
2380c486 12395+
4bf69007
AM
12396+struct vcmd_net_addr_v0 {
12397+ uint16_t type;
12398+ uint16_t count;
12399+ struct in_addr ip[4];
12400+ struct in_addr mask[4];
12401+};
2380c486 12402+
4bf69007
AM
12403+#define VCMD_net_add_ipv4_v1 VC_CMD(NETALT, 1, 1)
12404+#define VCMD_net_rem_ipv4_v1 VC_CMD(NETALT, 2, 1)
2380c486 12405+
4bf69007
AM
12406+struct vcmd_net_addr_ipv4_v1 {
12407+ uint16_t type;
12408+ uint16_t flags;
12409+ struct in_addr ip;
12410+ struct in_addr mask;
12411+};
2380c486 12412+
4bf69007
AM
12413+#define VCMD_net_add_ipv4 VC_CMD(NETALT, 1, 2)
12414+#define VCMD_net_rem_ipv4 VC_CMD(NETALT, 2, 2)
2380c486 12415+
4bf69007
AM
12416+struct vcmd_net_addr_ipv4_v2 {
12417+ uint16_t type;
12418+ uint16_t flags;
12419+ struct in_addr ip;
12420+ struct in_addr ip2;
12421+ struct in_addr mask;
12422+};
2380c486 12423+
4bf69007
AM
12424+#define VCMD_net_add_ipv6 VC_CMD(NETALT, 3, 1)
12425+#define VCMD_net_remove_ipv6 VC_CMD(NETALT, 4, 1)
2380c486 12426+
4bf69007
AM
12427+struct vcmd_net_addr_ipv6_v1 {
12428+ uint16_t type;
12429+ uint16_t flags;
12430+ uint32_t prefix;
12431+ struct in6_addr ip;
12432+ struct in6_addr mask;
12433+};
2380c486 12434+
4bf69007
AM
12435+#define VCMD_add_match_ipv4 VC_CMD(NETALT, 5, 0)
12436+#define VCMD_get_match_ipv4 VC_CMD(NETALT, 6, 0)
2380c486 12437+
4bf69007
AM
12438+struct vcmd_match_ipv4_v0 {
12439+ uint16_t type;
12440+ uint16_t flags;
12441+ uint16_t parent;
12442+ uint16_t prefix;
12443+ struct in_addr ip;
12444+ struct in_addr ip2;
12445+ struct in_addr mask;
12446+};
2380c486 12447+
4bf69007
AM
12448+#define VCMD_add_match_ipv6 VC_CMD(NETALT, 7, 0)
12449+#define VCMD_get_match_ipv6 VC_CMD(NETALT, 8, 0)
2380c486 12450+
4bf69007
AM
12451+struct vcmd_match_ipv6_v0 {
12452+ uint16_t type;
12453+ uint16_t flags;
12454+ uint16_t parent;
12455+ uint16_t prefix;
12456+ struct in6_addr ip;
12457+ struct in6_addr ip2;
12458+ struct in6_addr mask;
12459+};
2380c486 12460+
2380c486 12461+
2380c486 12462+
2380c486 12463+
4bf69007 12464+/* flag commands */
2380c486 12465+
4bf69007
AM
12466+#define VCMD_get_nflags VC_CMD(FLAGS, 5, 0)
12467+#define VCMD_set_nflags VC_CMD(FLAGS, 6, 0)
2380c486 12468+
4bf69007
AM
12469+struct vcmd_net_flags_v0 {
12470+ uint64_t flagword;
12471+ uint64_t mask;
12472+};
2380c486 12473+
2380c486 12474+
ab30d09f 12475+
4bf69007 12476+/* network caps commands */
ab30d09f 12477+
4bf69007
AM
12478+#define VCMD_get_ncaps VC_CMD(FLAGS, 7, 0)
12479+#define VCMD_set_ncaps VC_CMD(FLAGS, 8, 0)
ec22aa5c 12480+
4bf69007
AM
12481+struct vcmd_net_caps_v0 {
12482+ uint64_t ncaps;
12483+ uint64_t cmask;
12484+};
3bac966d 12485+
4bf69007 12486+#endif /* _UAPI_VS_NETWORK_CMD_H */
8de2f54c 12487diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/sched_cmd.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/sched_cmd.h
f19bd705 12488--- linux-4.4.111/include/uapi/vserver/sched_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 12489+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/sched_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12490@@ -0,0 +1,13 @@
12491+#ifndef _UAPI_VS_SCHED_CMD_H
12492+#define _UAPI_VS_SCHED_CMD_H
d337f35e 12493+
d337f35e 12494+
4bf69007
AM
12495+struct vcmd_prio_bias {
12496+ int32_t cpu_id;
12497+ int32_t prio_bias;
12498+};
2380c486 12499+
4bf69007
AM
12500+#define VCMD_set_prio_bias VC_CMD(SCHED, 4, 0)
12501+#define VCMD_get_prio_bias VC_CMD(SCHED, 5, 0)
d337f35e 12502+
4bf69007 12503+#endif /* _UAPI_VS_SCHED_CMD_H */
8de2f54c 12504diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/signal_cmd.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/signal_cmd.h
f19bd705 12505--- linux-4.4.111/include/uapi/vserver/signal_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 12506+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/signal_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12507@@ -0,0 +1,31 @@
12508+#ifndef _UAPI_VS_SIGNAL_CMD_H
12509+#define _UAPI_VS_SIGNAL_CMD_H
d337f35e 12510+
d337f35e 12511+
4bf69007 12512+/* signalling vserver commands */
d337f35e 12513+
4bf69007
AM
12514+#define VCMD_ctx_kill VC_CMD(PROCTRL, 1, 0)
12515+#define VCMD_wait_exit VC_CMD(EVENT, 99, 0)
d337f35e 12516+
4bf69007
AM
12517+struct vcmd_ctx_kill_v0 {
12518+ int32_t pid;
12519+ int32_t sig;
12520+};
d337f35e 12521+
4bf69007
AM
12522+struct vcmd_wait_exit_v0 {
12523+ int32_t reboot_cmd;
12524+ int32_t exit_code;
12525+};
d337f35e 12526+
d337f35e 12527+
4bf69007 12528+/* process alteration commands */
ab30d09f 12529+
4bf69007
AM
12530+#define VCMD_get_pflags VC_CMD(PROCALT, 5, 0)
12531+#define VCMD_set_pflags VC_CMD(PROCALT, 6, 0)
d337f35e 12532+
4bf69007
AM
12533+struct vcmd_pflags_v0 {
12534+ uint32_t flagword;
12535+ uint32_t mask;
12536+};
3bac966d 12537+
4bf69007 12538+#endif /* _UAPI_VS_SIGNAL_CMD_H */
8de2f54c 12539diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/space_cmd.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/space_cmd.h
f19bd705 12540--- linux-4.4.111/include/uapi/vserver/space_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 12541+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/space_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12542@@ -0,0 +1,28 @@
12543+#ifndef _UAPI_VS_SPACE_CMD_H
12544+#define _UAPI_VS_SPACE_CMD_H
d337f35e 12545+
d337f35e 12546+
4bf69007
AM
12547+#define VCMD_enter_space_v0 VC_CMD(PROCALT, 1, 0)
12548+#define VCMD_enter_space_v1 VC_CMD(PROCALT, 1, 1)
12549+#define VCMD_enter_space VC_CMD(PROCALT, 1, 2)
2380c486 12550+
4bf69007
AM
12551+#define VCMD_set_space_v0 VC_CMD(PROCALT, 3, 0)
12552+#define VCMD_set_space_v1 VC_CMD(PROCALT, 3, 1)
12553+#define VCMD_set_space VC_CMD(PROCALT, 3, 2)
d337f35e 12554+
4bf69007 12555+#define VCMD_get_space_mask_v0 VC_CMD(PROCALT, 4, 0)
d337f35e 12556+
4bf69007
AM
12557+#define VCMD_get_space_mask VC_CMD(VSPACE, 0, 1)
12558+#define VCMD_get_space_default VC_CMD(VSPACE, 1, 0)
d337f35e 12559+
d337f35e 12560+
4bf69007
AM
12561+struct vcmd_space_mask_v1 {
12562+ uint64_t mask;
12563+};
d337f35e 12564+
4bf69007
AM
12565+struct vcmd_space_mask_v2 {
12566+ uint64_t mask;
12567+ uint32_t index;
12568+};
d337f35e 12569+
4bf69007 12570+#endif /* _UAPI_VS_SPACE_CMD_H */
8de2f54c 12571diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/switch.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/switch.h
f19bd705 12572--- linux-4.4.111/include/uapi/vserver/switch.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 12573+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/switch.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12574@@ -0,0 +1,90 @@
12575+#ifndef _UAPI_VS_SWITCH_H
12576+#define _UAPI_VS_SWITCH_H
d337f35e 12577+
4bf69007 12578+#include <linux/types.h>
d337f35e 12579+
d337f35e 12580+
4bf69007
AM
12581+#define VC_CATEGORY(c) (((c) >> 24) & 0x3F)
12582+#define VC_COMMAND(c) (((c) >> 16) & 0xFF)
12583+#define VC_VERSION(c) ((c) & 0xFFF)
d337f35e 12584+
4bf69007
AM
12585+#define VC_CMD(c, i, v) ((((VC_CAT_ ## c) & 0x3F) << 24) \
12586+ | (((i) & 0xFF) << 16) | ((v) & 0xFFF))
d337f35e 12587+
4bf69007 12588+/*
d337f35e 12589+
4bf69007 12590+ Syscall Matrix V2.8
d337f35e 12591+
4bf69007
AM
12592+ |VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|
12593+ |STATS |DESTROY|ALTER |CHANGE |LIMIT |TEST | | | |
12594+ |INFO |SETUP | |MOVE | | | | | |
12595+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12596+ SYSTEM |VERSION|VSETUP |VHOST | | | | |DEVICE | |
12597+ HOST | 00| 01| 02| 03| 04| 05| | 06| 07|
12598+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12599+ CPU | |VPROC |PROCALT|PROCMIG|PROCTRL| | |SCHED. | |
12600+ PROCESS| 08| 09| 10| 11| 12| 13| | 14| 15|
12601+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12602+ MEMORY | | | | |MEMCTRL| | |SWAP | |
12603+ | 16| 17| 18| 19| 20| 21| | 22| 23|
12604+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12605+ NETWORK| |VNET |NETALT |NETMIG |NETCTL | | |SERIAL | |
12606+ | 24| 25| 26| 27| 28| 29| | 30| 31|
12607+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12608+ DISK | | | |TAGMIG |DLIMIT | | |INODE | |
12609+ VFS | 32| 33| 34| 35| 36| 37| | 38| 39|
12610+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12611+ OTHER |VSTAT | | | | | | |VINFO | |
12612+ | 40| 41| 42| 43| 44| 45| | 46| 47|
12613+ =======+=======+=======+=======+=======+=======+=======+ +=======+=======+
12614+ SPECIAL|EVENT | | | |FLAGS | | |VSPACE | |
12615+ | 48| 49| 50| 51| 52| 53| | 54| 55|
12616+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12617+ SPECIAL|DEBUG | | | |RLIMIT |SYSCALL| | |COMPAT |
12618+ | 56| 57| 58| 59| 60|TEST 61| | 62| 63|
12619+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
d337f35e 12620+
4bf69007 12621+*/
d337f35e 12622+
4bf69007 12623+#define VC_CAT_VERSION 0
d337f35e 12624+
4bf69007
AM
12625+#define VC_CAT_VSETUP 1
12626+#define VC_CAT_VHOST 2
d337f35e 12627+
4bf69007 12628+#define VC_CAT_DEVICE 6
d337f35e 12629+
4bf69007
AM
12630+#define VC_CAT_VPROC 9
12631+#define VC_CAT_PROCALT 10
12632+#define VC_CAT_PROCMIG 11
12633+#define VC_CAT_PROCTRL 12
d337f35e 12634+
4bf69007
AM
12635+#define VC_CAT_SCHED 14
12636+#define VC_CAT_MEMCTRL 20
d337f35e 12637+
4bf69007
AM
12638+#define VC_CAT_VNET 25
12639+#define VC_CAT_NETALT 26
12640+#define VC_CAT_NETMIG 27
12641+#define VC_CAT_NETCTRL 28
d337f35e 12642+
4bf69007
AM
12643+#define VC_CAT_TAGMIG 35
12644+#define VC_CAT_DLIMIT 36
12645+#define VC_CAT_INODE 38
d337f35e 12646+
4bf69007
AM
12647+#define VC_CAT_VSTAT 40
12648+#define VC_CAT_VINFO 46
12649+#define VC_CAT_EVENT 48
d337f35e 12650+
4bf69007
AM
12651+#define VC_CAT_FLAGS 52
12652+#define VC_CAT_VSPACE 54
12653+#define VC_CAT_DEBUG 56
12654+#define VC_CAT_RLIMIT 60
d337f35e 12655+
4bf69007
AM
12656+#define VC_CAT_SYSTEST 61
12657+#define VC_CAT_COMPAT 63
d337f35e 12658+
4bf69007 12659+/* query version */
d337f35e 12660+
4bf69007
AM
12661+#define VCMD_get_version VC_CMD(VERSION, 0, 0)
12662+#define VCMD_get_vci VC_CMD(VERSION, 1, 0)
2380c486 12663+
4bf69007 12664+#endif /* _UAPI_VS_SWITCH_H */
8de2f54c 12665diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/tag_cmd.h linux-4.4.111-vs2.3.9.5/include/uapi/vserver/tag_cmd.h
f19bd705 12666--- linux-4.4.111/include/uapi/vserver/tag_cmd.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 12667+++ linux-4.4.111-vs2.3.9.5/include/uapi/vserver/tag_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12668@@ -0,0 +1,14 @@
12669+#ifndef _UAPI_VS_TAG_CMD_H
12670+#define _UAPI_VS_TAG_CMD_H
d337f35e 12671+
d337f35e 12672+
4bf69007 12673+/* vinfo commands */
d337f35e 12674+
4bf69007 12675+#define VCMD_task_tag VC_CMD(VINFO, 3, 0)
d337f35e
JR
12676+
12677+
4bf69007 12678+/* context commands */
d337f35e 12679+
4bf69007 12680+#define VCMD_tag_migrate VC_CMD(TAGMIG, 1, 0)
2380c486 12681+
4bf69007 12682+#endif /* _UAPI_VS_TAG_CMD_H */
8de2f54c 12683diff -NurpP --minimal linux-4.4.111/init/Kconfig linux-4.4.111-vs2.3.9.5/init/Kconfig
f19bd705 12684--- linux-4.4.111/init/Kconfig 2016-07-05 04:15:12.000000000 +0000
8de2f54c 12685+++ linux-4.4.111-vs2.3.9.5/init/Kconfig 2018-01-09 16:36:33.000000000 +0000
927ca606 12686@@ -927,6 +927,7 @@ config NUMA_BALANCING_DEFAULT_ENABLED
4bf69007 12687 menuconfig CGROUPS
927ca606 12688 bool "Control Group support"
265de2f7 12689 select KERNFS
4bf69007
AM
12690+ default y
12691 help
12692 This option adds support for grouping sets of processes together, for
12693 use with process control subsystems such as Cpusets, CFS, memory
8de2f54c 12694diff -NurpP --minimal linux-4.4.111/init/main.c linux-4.4.111-vs2.3.9.5/init/main.c
f19bd705 12695--- linux-4.4.111/init/main.c 2018-01-11 07:57:51.000000000 +0000
8de2f54c 12696+++ linux-4.4.111-vs2.3.9.5/init/main.c 2018-01-09 16:58:21.000000000 +0000
927ca606
AM
12697@@ -82,6 +82,7 @@
12698 #include <linux/proc_ns.h>
12699 #include <linux/io.h>
12700 #include <linux/kaiser.h>
4bf69007
AM
12701+#include <linux/vserver/percpu.h>
12702
12703 #include <asm/io.h>
12704 #include <asm/bugs.h>
8de2f54c 12705diff -NurpP --minimal linux-4.4.111/ipc/mqueue.c linux-4.4.111-vs2.3.9.5/ipc/mqueue.c
f19bd705 12706--- linux-4.4.111/ipc/mqueue.c 2018-01-11 07:57:51.000000000 +0000
8de2f54c 12707+++ linux-4.4.111-vs2.3.9.5/ipc/mqueue.c 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12708@@ -35,6 +35,8 @@
12709 #include <linux/ipc_namespace.h>
12710 #include <linux/user_namespace.h>
12711 #include <linux/slab.h>
12712+#include <linux/vs_context.h>
12713+#include <linux/vs_limit.h>
12714
12715 #include <net/sock.h>
12716 #include "util.h"
927ca606 12717@@ -75,6 +77,7 @@ struct mqueue_inode_info {
bb20add7 12718 struct pid *notify_owner;
4bf69007
AM
12719 struct user_namespace *notify_user_ns;
12720 struct user_struct *user; /* user who created, for accounting */
12721+ struct vx_info *vxi;
12722 struct sock *notify_sock;
12723 struct sk_buff *notify_cookie;
12724
927ca606 12725@@ -230,6 +233,7 @@ static struct inode *mqueue_get_inode(st
4bf69007
AM
12726 if (S_ISREG(mode)) {
12727 struct mqueue_inode_info *info;
12728 unsigned long mq_bytes, mq_treesize;
12729+ struct vx_info *vxi = current_vx_info();
12730
12731 inode->i_fop = &mqueue_file_operations;
12732 inode->i_size = FILENT_SIZE;
927ca606 12733@@ -243,6 +247,7 @@ static struct inode *mqueue_get_inode(st
4bf69007
AM
12734 info->notify_user_ns = NULL;
12735 info->qsize = 0;
12736 info->user = NULL; /* set when all is ok */
12737+ info->vxi = NULL;
12738 info->msg_tree = RB_ROOT;
12739 info->node_cache = NULL;
12740 memset(&info->attr, 0, sizeof(info->attr));
927ca606 12741@@ -276,17 +281,20 @@ static struct inode *mqueue_get_inode(st
4bf69007
AM
12742
12743 spin_lock(&mq_lock);
12744 if (u->mq_bytes + mq_bytes < u->mq_bytes ||
12745- u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE)) {
12746+ u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE) ||
12747+ !vx_ipcmsg_avail(vxi, mq_bytes)) {
12748 spin_unlock(&mq_lock);
12749 /* mqueue_evict_inode() releases info->messages */
12750 ret = -EMFILE;
12751 goto out_inode;
12752 }
12753 u->mq_bytes += mq_bytes;
12754+ vx_ipcmsg_add(vxi, u, mq_bytes);
12755 spin_unlock(&mq_lock);
12756
12757 /* all is ok */
12758 info->user = get_uid(u);
12759+ info->vxi = get_vx_info(vxi);
12760 } else if (S_ISDIR(mode)) {
12761 inc_nlink(inode);
12762 /* Some things misbehave if size == 0 on a directory */
927ca606 12763@@ -398,8 +406,11 @@ static void mqueue_evict_inode(struct in
4bf69007
AM
12764
12765 user = info->user;
12766 if (user) {
12767+ struct vx_info *vxi = info->vxi;
d337f35e 12768+
4bf69007
AM
12769 spin_lock(&mq_lock);
12770 user->mq_bytes -= mq_bytes;
12771+ vx_ipcmsg_sub(vxi, user, mq_bytes);
12772 /*
12773 * get_ns_from_inode() ensures that the
12774 * (ipc_ns = sb->s_fs_info) is either a valid ipc_ns
927ca606 12775@@ -409,6 +420,7 @@ static void mqueue_evict_inode(struct in
4bf69007
AM
12776 if (ipc_ns)
12777 ipc_ns->mq_queues_count--;
12778 spin_unlock(&mq_lock);
12779+ put_vx_info(vxi);
12780 free_uid(user);
12781 }
12782 if (ipc_ns)
8de2f54c 12783diff -NurpP --minimal linux-4.4.111/ipc/msg.c linux-4.4.111-vs2.3.9.5/ipc/msg.c
f19bd705 12784--- linux-4.4.111/ipc/msg.c 2018-01-11 07:57:51.000000000 +0000
8de2f54c 12785+++ linux-4.4.111-vs2.3.9.5/ipc/msg.c 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12786@@ -37,6 +37,7 @@
12787 #include <linux/rwsem.h>
12788 #include <linux/nsproxy.h>
12789 #include <linux/ipc_namespace.h>
12790+#include <linux/vs_base.h>
12791
12792 #include <asm/current.h>
bb20add7
AM
12793 #include <linux/uaccess.h>
12794@@ -129,6 +130,7 @@ static int newque(struct ipc_namespace *
4bf69007
AM
12795
12796 msq->q_perm.mode = msgflg & S_IRWXUGO;
12797 msq->q_perm.key = key;
12798+ msq->q_perm.xid = vx_current_xid();
12799
12800 msq->q_perm.security = NULL;
12801 retval = security_msg_queue_alloc(msq);
8de2f54c 12802diff -NurpP --minimal linux-4.4.111/ipc/sem.c linux-4.4.111-vs2.3.9.5/ipc/sem.c
f19bd705 12803--- linux-4.4.111/ipc/sem.c 2018-01-11 07:57:51.000000000 +0000
8de2f54c 12804+++ linux-4.4.111-vs2.3.9.5/ipc/sem.c 2018-01-09 16:36:33.000000000 +0000
bb20add7 12805@@ -85,6 +85,8 @@
4bf69007
AM
12806 #include <linux/rwsem.h>
12807 #include <linux/nsproxy.h>
12808 #include <linux/ipc_namespace.h>
12809+#include <linux/vs_base.h>
12810+#include <linux/vs_limit.h>
12811
bb20add7 12812 #include <linux/uaccess.h>
4bf69007 12813 #include "util.h"
927ca606 12814@@ -533,6 +535,7 @@ static int newary(struct ipc_namespace *
4bf69007
AM
12815
12816 sma->sem_perm.mode = (semflg & S_IRWXUGO);
12817 sma->sem_perm.key = key;
12818+ sma->sem_perm.xid = vx_current_xid();
12819
12820 sma->sem_perm.security = NULL;
12821 retval = security_sem_alloc(sma);
927ca606 12822@@ -563,6 +566,9 @@ static int newary(struct ipc_namespace *
4bf69007
AM
12823 return id;
12824 }
12825 ns->used_sems += nsems;
12826+ /* FIXME: obsoleted? */
12827+ vx_semary_inc(sma);
12828+ vx_nsems_add(sma, nsems);
12829
bb20add7
AM
12830 sem_unlock(sma, -1);
12831 rcu_read_unlock();
927ca606 12832@@ -1151,6 +1157,9 @@ static void freeary(struct ipc_namespace
4bf69007
AM
12833
12834 wake_up_sem_queue_do(&tasks);
12835 ns->used_sems -= sma->sem_nsems;
12836+ /* FIXME: obsoleted? */
12837+ vx_nsems_sub(sma, sma->sem_nsems);
12838+ vx_semary_dec(sma);
926e38e0 12839 ipc_rcu_putref(sma, sem_rcu_free);
4bf69007 12840 }
926e38e0 12841
8de2f54c 12842diff -NurpP --minimal linux-4.4.111/ipc/shm.c linux-4.4.111-vs2.3.9.5/ipc/shm.c
f19bd705 12843--- linux-4.4.111/ipc/shm.c 2018-01-11 07:57:51.000000000 +0000
8de2f54c 12844+++ linux-4.4.111-vs2.3.9.5/ipc/shm.c 2018-01-09 16:36:33.000000000 +0000
c2e5f7c8 12845@@ -42,6 +42,8 @@
4bf69007
AM
12846 #include <linux/nsproxy.h>
12847 #include <linux/mount.h>
12848 #include <linux/ipc_namespace.h>
12849+#include <linux/vs_context.h>
12850+#include <linux/vs_limit.h>
12851
bb20add7 12852 #include <linux/uaccess.h>
4bf69007 12853
927ca606 12854@@ -228,10 +230,14 @@ static void shm_open(struct vm_area_stru
4bf69007
AM
12855 static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
12856 {
c2e5f7c8 12857 struct file *shm_file;
4bf69007
AM
12858+ struct vx_info *vxi = lookup_vx_info(shp->shm_perm.xid);
12859+ int numpages = (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
c2e5f7c8
JR
12860
12861 shm_file = shp->shm_file;
12862 shp->shm_file = NULL;
12863- ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
4bf69007
AM
12864+ vx_ipcshm_sub(vxi, shp, numpages);
12865+ ns->shm_tot -= numpages;
d337f35e 12866+
4bf69007
AM
12867 shm_rmid(ns, shp);
12868 shm_unlock(shp);
c2e5f7c8 12869 if (!is_file_hugepages(shm_file))
927ca606
AM
12870@@ -240,6 +246,7 @@ static void shm_destroy(struct ipc_names
12871 user_shm_unlock(i_size_read(file_inode(shm_file)),
12872 shp->mlock_user);
c2e5f7c8 12873 fput(shm_file);
4bf69007 12874+ put_vx_info(vxi);
926e38e0 12875 ipc_rcu_putref(shp, shm_rcu_free);
4bf69007
AM
12876 }
12877
927ca606 12878@@ -537,11 +544,15 @@ static int newseg(struct ipc_namespace *
bb20add7 12879 ns->shm_tot + numpages > ns->shm_ctlall)
4bf69007
AM
12880 return -ENOSPC;
12881
12882+ if (!vx_ipcshm_avail(current_vx_info(), numpages))
12883+ return -ENOSPC;
d337f35e 12884+
4bf69007
AM
12885 shp = ipc_rcu_alloc(sizeof(*shp));
12886 if (!shp)
12887 return -ENOMEM;
12888
12889 shp->shm_perm.key = key;
12890+ shp->shm_perm.xid = vx_current_xid();
12891 shp->shm_perm.mode = (shmflg & S_IRWXUGO);
12892 shp->mlock_user = NULL;
12893
927ca606 12894@@ -612,6 +623,7 @@ static int newseg(struct ipc_namespace *
926e38e0
JR
12895
12896 ipc_unlock_object(&shp->shm_perm);
12897 rcu_read_unlock();
4bf69007
AM
12898+ vx_ipcshm_add(current_vx_info(), key, numpages);
12899 return error;
12900
12901 no_id:
8de2f54c 12902diff -NurpP --minimal linux-4.4.111/kernel/Makefile linux-4.4.111-vs2.3.9.5/kernel/Makefile
f19bd705 12903--- linux-4.4.111/kernel/Makefile 2016-07-05 04:12:38.000000000 +0000
8de2f54c 12904+++ linux-4.4.111-vs2.3.9.5/kernel/Makefile 2018-01-09 16:36:33.000000000 +0000
927ca606 12905@@ -29,6 +29,7 @@ obj-y += printk/
c2e5f7c8
JR
12906 obj-y += irq/
12907 obj-y += rcu/
927ca606 12908 obj-y += livepatch/
4bf69007
AM
12909+obj-y += vserver/
12910
b00e13aa
AM
12911 obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o
12912 obj-$(CONFIG_FREEZER) += freezer.o
8de2f54c 12913diff -NurpP --minimal linux-4.4.111/kernel/auditsc.c linux-4.4.111-vs2.3.9.5/kernel/auditsc.c
f19bd705 12914--- linux-4.4.111/kernel/auditsc.c 2018-01-11 07:57:51.000000000 +0000
8de2f54c 12915+++ linux-4.4.111-vs2.3.9.5/kernel/auditsc.c 2018-01-09 16:36:33.000000000 +0000
927ca606 12916@@ -1962,7 +1962,7 @@ static int audit_set_loginuid_perm(kuid_
c2e5f7c8 12917 if (is_audit_feature_set(AUDIT_FEATURE_LOGINUID_IMMUTABLE))
4bf69007 12918 return -EPERM;
c2e5f7c8 12919 /* it is set, you need permission */
4bf69007
AM
12920- if (!capable(CAP_AUDIT_CONTROL))
12921+ if (!vx_capable(CAP_AUDIT_CONTROL, VXC_AUDIT_CONTROL))
12922 return -EPERM;
c2e5f7c8
JR
12923 /* reject if this is not an unset and we don't allow that */
12924 if (is_audit_feature_set(AUDIT_FEATURE_ONLY_UNSET_LOGINUID) && uid_valid(loginuid))
8de2f54c 12925diff -NurpP --minimal linux-4.4.111/kernel/capability.c linux-4.4.111-vs2.3.9.5/kernel/capability.c
f19bd705 12926--- linux-4.4.111/kernel/capability.c 2018-01-11 07:57:51.000000000 +0000
8de2f54c 12927+++ linux-4.4.111-vs2.3.9.5/kernel/capability.c 2018-01-09 16:36:33.000000000 +0000
bb20add7 12928@@ -17,6 +17,7 @@
4bf69007
AM
12929 #include <linux/syscalls.h>
12930 #include <linux/pid_namespace.h>
12931 #include <linux/user_namespace.h>
12932+#include <linux/vs_context.h>
12933 #include <asm/uaccess.h>
12934
12935 /*
927ca606 12936@@ -107,6 +108,7 @@ static int cap_validate_magic(cap_user_h
4bf69007
AM
12937 return 0;
12938 }
12939
2380c486 12940+
4bf69007
AM
12941 /*
12942 * The only thing that can change the capabilities of the current
12943 * process is the current process. As such, we can't be in this code
927ca606 12944@@ -344,6 +346,8 @@ bool has_ns_capability_noaudit(struct ta
4bf69007
AM
12945 return (ret == 0);
12946 }
12947
12948+#include <linux/vserver/base.h>
d337f35e 12949+
4bf69007
AM
12950 /**
12951 * has_capability_noaudit - Does a task have a capability (unaudited) in the
12952 * initial user ns
8de2f54c 12953diff -NurpP --minimal linux-4.4.111/kernel/compat.c linux-4.4.111-vs2.3.9.5/kernel/compat.c
f19bd705 12954--- linux-4.4.111/kernel/compat.c 2015-07-06 20:41:43.000000000 +0000
8de2f54c 12955+++ linux-4.4.111-vs2.3.9.5/kernel/compat.c 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12956@@ -27,6 +27,7 @@
12957 #include <linux/times.h>
12958 #include <linux/ptrace.h>
12959 #include <linux/gfp.h>
12960+#include <linux/vs_time.h>
12961
12962 #include <asm/uaccess.h>
12963
927ca606 12964@@ -1059,7 +1060,7 @@ COMPAT_SYSCALL_DEFINE1(stime, compat_tim
4bf69007
AM
12965 if (err)
12966 return err;
12967
12968- do_settimeofday(&tv);
12969+ vx_settimeofday(&tv);
12970 return 0;
12971 }
12972
8de2f54c 12973diff -NurpP --minimal linux-4.4.111/kernel/cred.c linux-4.4.111-vs2.3.9.5/kernel/cred.c
f19bd705 12974--- linux-4.4.111/kernel/cred.c 2018-01-11 07:57:51.000000000 +0000
8de2f54c 12975+++ linux-4.4.111-vs2.3.9.5/kernel/cred.c 2018-01-09 16:36:33.000000000 +0000
927ca606 12976@@ -64,31 +64,6 @@ struct cred init_cred = {
b00e13aa 12977 .group_info = &init_groups,
4bf69007
AM
12978 };
12979
12980-static inline void set_cred_subscribers(struct cred *cred, int n)
12981-{
12982-#ifdef CONFIG_DEBUG_CREDENTIALS
12983- atomic_set(&cred->subscribers, n);
12984-#endif
12985-}
12986-
12987-static inline int read_cred_subscribers(const struct cred *cred)
12988-{
12989-#ifdef CONFIG_DEBUG_CREDENTIALS
12990- return atomic_read(&cred->subscribers);
12991-#else
12992- return 0;
12993-#endif
12994-}
12995-
12996-static inline void alter_cred_subscribers(const struct cred *_cred, int n)
12997-{
12998-#ifdef CONFIG_DEBUG_CREDENTIALS
12999- struct cred *cred = (struct cred *) _cred;
13000-
13001- atomic_add(n, &cred->subscribers);
13002-#endif
13003-}
13004-
13005 /*
b00e13aa 13006 * The RCU callback to actually dispose of a set of credentials
4bf69007 13007 */
927ca606 13008@@ -240,21 +215,16 @@ error:
4bf69007
AM
13009 *
13010 * Call commit_creds() or abort_creds() to clean up.
13011 */
13012-struct cred *prepare_creds(void)
13013+struct cred *__prepare_creds(const struct cred *old)
13014 {
13015- struct task_struct *task = current;
13016- const struct cred *old;
13017 struct cred *new;
13018
13019- validate_process_creds();
13020-
13021 new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
13022 if (!new)
13023 return NULL;
13024
13025 kdebug("prepare_creds() alloc %p", new);
13026
13027- old = task->cred;
13028 memcpy(new, old, sizeof(struct cred));
13029
13030 atomic_set(&new->usage, 1);
927ca606 13031@@ -283,6 +253,13 @@ error:
4bf69007
AM
13032 abort_creds(new);
13033 return NULL;
13034 }
d337f35e 13035+
4bf69007 13036+struct cred *prepare_creds(void)
2380c486 13037+{
4bf69007 13038+ validate_process_creds();
d337f35e 13039+
4bf69007 13040+ return __prepare_creds(current->cred);
2380c486 13041+}
4bf69007
AM
13042 EXPORT_SYMBOL(prepare_creds);
13043
13044 /*
8de2f54c 13045diff -NurpP --minimal linux-4.4.111/kernel/exit.c linux-4.4.111-vs2.3.9.5/kernel/exit.c
f19bd705 13046--- linux-4.4.111/kernel/exit.c 2018-01-11 07:57:51.000000000 +0000
8de2f54c 13047+++ linux-4.4.111-vs2.3.9.5/kernel/exit.c 2018-01-09 16:59:03.000000000 +0000
4bf69007
AM
13048@@ -48,6 +48,10 @@
13049 #include <linux/fs_struct.h>
13050 #include <linux/init_task.h>
13051 #include <linux/perf_event.h>
13052+#include <linux/vs_limit.h>
13053+#include <linux/vs_context.h>
13054+#include <linux/vs_network.h>
13055+#include <linux/vs_pid.h>
13056 #include <trace/events/sched.h>
13057 #include <linux/hw_breakpoint.h>
13058 #include <linux/oom.h>
927ca606 13059@@ -456,14 +460,24 @@ static struct task_struct *find_child_re
4bf69007
AM
13060 {
13061 struct pid_namespace *pid_ns = task_active_pid_ns(father);
927ca606 13062 struct task_struct *reaper = pid_ns->child_reaper;
4bf69007 13063+ struct vx_info *vxi = task_get_vx_info(father);
d337f35e 13064+
4bf69007
AM
13065+ if (vxi) {
13066+ BUG_ON(!vxi->vx_reaper);
13067+ if (vxi->vx_reaper != init_pid_ns.child_reaper &&
927ca606 13068+ vxi->vx_reaper != father) {
4bf69007 13069+ reaper = vxi->vx_reaper;
927ca606
AM
13070+ goto out_put;
13071+ }
13072+ }
4bf69007 13073
927ca606
AM
13074 if (likely(reaper != father))
13075- return reaper;
13076+ goto out_put;
13077
13078 reaper = find_alive_thread(father);
13079 if (reaper) {
13080 pid_ns->child_reaper = reaper;
13081- return reaper;
13082+ goto out_put;
4bf69007
AM
13083 }
13084
927ca606
AM
13085 write_unlock_irq(&tasklist_lock);
13086@@ -474,7 +488,10 @@ static struct task_struct *find_child_re
13087 zap_pid_ns_processes(pid_ns);
13088 write_lock_irq(&tasklist_lock);
13089
13090- return father;
13091+ reaper = father;
4bf69007
AM
13092+out_put:
13093+ put_vx_info(vxi);
13094+ return reaper;
13095 }
13096
13097 /*
927ca606
AM
13098@@ -562,9 +579,13 @@ static void forget_original_parent(struc
13099 return;
bb20add7 13100
927ca606
AM
13101 reaper = find_new_reaper(father, reaper);
13102- list_for_each_entry(p, &father->children, sibling) {
13103+ for (p = list_first_entry(&father->children, struct task_struct, sibling);
13104+ &p->sibling != &father->children; ) {
13105+ struct task_struct *next, *this_reaper = reaper;
13106+ if (p == reaper)
13107+ this_reaper = task_active_pid_ns(reaper)->child_reaper;
13108 for_each_thread(p, t) {
4bf69007 13109- t->real_parent = reaper;
927ca606
AM
13110+ t->real_parent = this_reaper;
13111 BUG_ON((!t->ptrace) != (t->parent == father));
13112 if (likely(!t->ptrace))
13113 t->parent = t->real_parent;
13114@@ -576,10 +597,13 @@ static void forget_original_parent(struc
13115 * If this is a threaded reparent there is no need to
13116 * notify anyone anything has happened.
13117 */
13118- if (!same_thread_group(reaper, father))
13119+ if (!same_thread_group(this_reaper, father))
13120 reparent_leader(father, p, dead);
13121+ next = list_next_entry(p, sibling);
13122+ list_add(&p->sibling, &this_reaper->children);
13123+ p = next;
13124 }
13125- list_splice_tail_init(&father->children, &reaper->children);
13126+ INIT_LIST_HEAD(&father->children);
13127 }
13128
13129 /*
13130@@ -763,6 +787,9 @@ void do_exit(long code)
4bf69007 13131 */
c2e5f7c8 13132 flush_ptrace_hw_breakpoint(tsk);
4bf69007
AM
13133
13134+ /* needs to stay before exit_notify() */
13135+ exit_vx_info_early(tsk, code);
d337f35e 13136+
927ca606 13137 TASKS_RCU(preempt_disable());
bb20add7 13138 TASKS_RCU(tasks_rcu_i = __srcu_read_lock(&tasks_rcu_exit_srcu));
927ca606
AM
13139 TASKS_RCU(preempt_enable());
13140@@ -822,10 +849,15 @@ void do_exit(long code)
4bf69007
AM
13141 smp_mb();
13142 raw_spin_unlock_wait(&tsk->pi_lock);
13143
13144+ /* needs to stay after exit_notify() */
13145+ exit_vx_info(tsk, code);
13146+ exit_nx_info(tsk);
d337f35e 13147+
4bf69007
AM
13148 /* causes final put_task_struct in finish_task_switch(). */
13149 tsk->state = TASK_DEAD;
13150 tsk->flags |= PF_NOFREEZE; /* tell freezer to ignore us */
13151 schedule();
13152+ printk("bad task: %p [%lx]\n", current, current->state);
13153 BUG();
13154 /* Avoid "noreturn function does return". */
13155 for (;;)
8de2f54c 13156diff -NurpP --minimal linux-4.4.111/kernel/fork.c linux-4.4.111-vs2.3.9.5/kernel/fork.c
f19bd705 13157--- linux-4.4.111/kernel/fork.c 2018-01-11 07:57:51.000000000 +0000
8de2f54c 13158+++ linux-4.4.111-vs2.3.9.5/kernel/fork.c 2018-01-09 17:00:00.000000000 +0000
927ca606 13159@@ -76,6 +76,9 @@
09be7631 13160 #include <linux/aio.h>
265de2f7 13161 #include <linux/compiler.h>
927ca606 13162 #include <linux/sysctl.h>
4bf69007
AM
13163+#include <linux/vs_context.h>
13164+#include <linux/vs_network.h>
13165+#include <linux/vs_limit.h>
13166
13167 #include <asm/pgtable.h>
13168 #include <asm/pgalloc.h>
927ca606 13169@@ -227,6 +230,8 @@ void free_task(struct task_struct *tsk)
4bf69007
AM
13170 arch_release_thread_info(tsk->stack);
13171 free_thread_info(tsk->stack);
13172 rt_mutex_debug_task_free(tsk);
13173+ clr_vx_info(&tsk->vx_info);
13174+ clr_nx_info(&tsk->nx_info);
13175 ftrace_graph_exit_task(tsk);
13176 put_seccomp_filter(tsk);
13177 arch_release_task_struct(tsk);
927ca606 13178@@ -1282,6 +1287,8 @@ static struct task_struct *copy_process(
8d50a2ea 13179 {
4bf69007
AM
13180 int retval;
13181 struct task_struct *p;
4bf69007
AM
13182+ struct vx_info *vxi;
13183+ struct nx_info *nxi;
927ca606 13184 void *cgrp_ss_priv[CGROUP_CANFORK_COUNT] = {};
4bf69007
AM
13185
13186 if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
927ca606 13187@@ -1343,7 +1350,12 @@ static struct task_struct *copy_process(
4bf69007
AM
13188 DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
13189 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
13190 #endif
13191+ init_vx_info(&p->vx_info, current_vx_info());
13192+ init_nx_info(&p->nx_info, current_nx_info());
13193+
13194 retval = -EAGAIN;
13195+ if (!vx_nproc_avail(1))
13196+ goto bad_fork_free;
13197 if (atomic_read(&p->real_cred->user->processes) >=
13198 task_rlimit(p, RLIMIT_NPROC)) {
c2e5f7c8 13199 if (p->real_cred->user != INIT_USER &&
927ca606 13200@@ -1640,6 +1652,18 @@ static struct task_struct *copy_process(
4bf69007
AM
13201 total_forks++;
13202 spin_unlock(&current->sighand->siglock);
bb20add7 13203 syscall_tracepoint_update(p);
4bf69007
AM
13204+
13205+ /* p is copy of current */
13206+ vxi = p->vx_info;
13207+ if (vxi) {
13208+ claim_vx_info(vxi, p);
13209+ atomic_inc(&vxi->cvirt.nr_threads);
13210+ atomic_inc(&vxi->cvirt.total_forks);
13211+ vx_nproc_inc(p);
2380c486 13212+ }
4bf69007
AM
13213+ nxi = p->nx_info;
13214+ if (nxi)
13215+ claim_nx_info(nxi, p);
13216 write_unlock_irq(&tasklist_lock);
bb20add7 13217
4bf69007 13218 proc_fork_connector(p);
8de2f54c 13219diff -NurpP --minimal linux-4.4.111/kernel/kthread.c linux-4.4.111-vs2.3.9.5/kernel/kthread.c
f19bd705 13220--- linux-4.4.111/kernel/kthread.c 2018-01-11 07:57:52.000000000 +0000
8de2f54c 13221+++ linux-4.4.111-vs2.3.9.5/kernel/kthread.c 2018-01-09 17:01:06.000000000 +0000
927ca606 13222@@ -19,6 +19,7 @@
4bf69007 13223 #include <linux/ptrace.h>
09be7631 13224 #include <linux/uaccess.h>
927ca606 13225 #include <linux/cgroup.h>
4bf69007
AM
13226+#include <linux/vs_pid.h>
13227 #include <trace/events/sched.h>
13228
13229 static DEFINE_SPINLOCK(kthread_create_lock);
8de2f54c 13230diff -NurpP --minimal linux-4.4.111/kernel/nsproxy.c linux-4.4.111-vs2.3.9.5/kernel/nsproxy.c
f19bd705 13231--- linux-4.4.111/kernel/nsproxy.c 2015-04-12 22:12:50.000000000 +0000
8de2f54c 13232+++ linux-4.4.111-vs2.3.9.5/kernel/nsproxy.c 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
13233@@ -20,11 +20,14 @@
13234 #include <linux/mnt_namespace.h>
13235 #include <linux/utsname.h>
13236 #include <linux/pid_namespace.h>
13237+#include <linux/vserver/global.h>
13238+#include <linux/vserver/debug.h>
13239 #include <net/net_namespace.h>
13240 #include <linux/ipc_namespace.h>
09be7631 13241 #include <linux/proc_ns.h>
4bf69007
AM
13242 #include <linux/file.h>
13243 #include <linux/syscalls.h>
13244+#include "../fs/mount.h"
13245
13246 static struct kmem_cache *nsproxy_cachep;
13247
13248@@ -46,8 +49,11 @@ static inline struct nsproxy *create_nsp
13249 struct nsproxy *nsproxy;
13250
13251 nsproxy = kmem_cache_alloc(nsproxy_cachep, GFP_KERNEL);
13252- if (nsproxy)
13253+ if (nsproxy) {
13254 atomic_set(&nsproxy->count, 1);
13255+ atomic_inc(&vs_global_nsproxy);
13256+ }
13257+ vxdprintk(VXD_CBIT(space, 2), "create_nsproxy = %p[1]", nsproxy);
13258 return nsproxy;
13259 }
13260
b00e13aa 13261@@ -56,9 +62,12 @@ static inline struct nsproxy *create_nsp
4bf69007
AM
13262 * Return the newly created nsproxy. Do not attach this to the task,
13263 * leave it to the caller to do proper locking and attach it to task.
13264 */
13265-static struct nsproxy *create_new_namespaces(unsigned long flags,
b00e13aa
AM
13266- struct task_struct *tsk, struct user_namespace *user_ns,
13267- struct fs_struct *new_fs)
13268+static struct nsproxy *unshare_namespaces(
13269+ unsigned long flags,
13270+ struct nsproxy *orig,
13271+ struct fs_struct *new_fs,
13272+ struct user_namespace *new_user,
13273+ struct pid_namespace *new_pid)
4bf69007
AM
13274 {
13275 struct nsproxy *new_nsp;
13276 int err;
c2e5f7c8 13277@@ -67,32 +76,31 @@ static struct nsproxy *create_new_namesp
4bf69007
AM
13278 if (!new_nsp)
13279 return ERR_PTR(-ENOMEM);
13280
b00e13aa
AM
13281- new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, user_ns, new_fs);
13282+ new_nsp->mnt_ns = copy_mnt_ns(flags, orig->mnt_ns, new_user, new_fs);
4bf69007
AM
13283 if (IS_ERR(new_nsp->mnt_ns)) {
13284 err = PTR_ERR(new_nsp->mnt_ns);
13285 goto out_ns;
13286 }
13287
b00e13aa
AM
13288- new_nsp->uts_ns = copy_utsname(flags, user_ns, tsk->nsproxy->uts_ns);
13289+ new_nsp->uts_ns = copy_utsname(flags, new_user, orig->uts_ns);
4bf69007
AM
13290 if (IS_ERR(new_nsp->uts_ns)) {
13291 err = PTR_ERR(new_nsp->uts_ns);
13292 goto out_uts;
13293 }
13294
b00e13aa
AM
13295- new_nsp->ipc_ns = copy_ipcs(flags, user_ns, tsk->nsproxy->ipc_ns);
13296+ new_nsp->ipc_ns = copy_ipcs(flags, new_user, orig->ipc_ns);
4bf69007
AM
13297 if (IS_ERR(new_nsp->ipc_ns)) {
13298 err = PTR_ERR(new_nsp->ipc_ns);
13299 goto out_ipc;
13300 }
13301
c2e5f7c8
JR
13302- new_nsp->pid_ns_for_children =
13303- copy_pid_ns(flags, user_ns, tsk->nsproxy->pid_ns_for_children);
13304+ new_nsp->pid_ns_for_children = copy_pid_ns(flags, new_user, new_pid);
13305 if (IS_ERR(new_nsp->pid_ns_for_children)) {
13306 err = PTR_ERR(new_nsp->pid_ns_for_children);
4bf69007
AM
13307 goto out_pid;
13308 }
13309
b00e13aa
AM
13310- new_nsp->net_ns = copy_net_ns(flags, user_ns, tsk->nsproxy->net_ns);
13311+ new_nsp->net_ns = copy_net_ns(flags, new_user, orig->net_ns);
4bf69007
AM
13312 if (IS_ERR(new_nsp->net_ns)) {
13313 err = PTR_ERR(new_nsp->net_ns);
13314 goto out_net;
c2e5f7c8 13315@@ -117,6 +125,41 @@ out_ns:
4bf69007
AM
13316 return ERR_PTR(err);
13317 }
13318
13319+static struct nsproxy *create_new_namespaces(unsigned long flags,
b00e13aa
AM
13320+ struct task_struct *tsk, struct user_namespace *user_ns,
13321+ struct fs_struct *new_fs)
13322+
4bf69007
AM
13323+{
13324+ return unshare_namespaces(flags, tsk->nsproxy,
b00e13aa 13325+ new_fs, user_ns, task_active_pid_ns(tsk));
2380c486 13326+}
d337f35e 13327+
4bf69007
AM
13328+/*
13329+ * copies the nsproxy, setting refcount to 1, and grabbing a
13330+ * reference to all contained namespaces.
13331+ */
13332+struct nsproxy *copy_nsproxy(struct nsproxy *orig)
2380c486 13333+{
4bf69007 13334+ struct nsproxy *ns = create_nsproxy();
d337f35e 13335+
4bf69007
AM
13336+ if (ns) {
13337+ memcpy(ns, orig, sizeof(struct nsproxy));
13338+ atomic_set(&ns->count, 1);
d337f35e 13339+
4bf69007
AM
13340+ if (ns->mnt_ns)
13341+ get_mnt_ns(ns->mnt_ns);
13342+ if (ns->uts_ns)
13343+ get_uts_ns(ns->uts_ns);
13344+ if (ns->ipc_ns)
13345+ get_ipc_ns(ns->ipc_ns);
c2e5f7c8
JR
13346+ if (ns->pid_ns_for_children)
13347+ get_pid_ns(ns->pid_ns_for_children);
4bf69007
AM
13348+ if (ns->net_ns)
13349+ get_net(ns->net_ns);
13350+ }
13351+ return ns;
13352+}
d337f35e 13353+
4bf69007
AM
13354 /*
13355 * called from clone. This now handles copy for nsproxy and all
13356 * namespaces therein.
c2e5f7c8 13357@@ -125,7 +168,10 @@ int copy_namespaces(unsigned long flags,
4bf69007
AM
13358 {
13359 struct nsproxy *old_ns = tsk->nsproxy;
b00e13aa 13360 struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns);
4bf69007
AM
13361- struct nsproxy *new_ns;
13362+ struct nsproxy *new_ns = NULL;
c2e5f7c8 13363+
4bf69007
AM
13364+ vxdprintk(VXD_CBIT(space, 7), "copy_namespaces(0x%08lx,%p[%p])",
13365+ flags, tsk, old_ns);
4bf69007 13366
c2e5f7c8
JR
13367 if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
13368 CLONE_NEWPID | CLONE_NEWNET)))) {
13369@@ -133,7 +179,7 @@ int copy_namespaces(unsigned long flags,
4bf69007 13370 return 0;
4bf69007 13371 }
4bf69007 13372
c2e5f7c8
JR
13373- if (!ns_capable(user_ns, CAP_SYS_ADMIN))
13374+ if (!vx_ns_can_unshare(user_ns, CAP_SYS_ADMIN, flags))
13375 return -EPERM;
13376
13377 /*
13378@@ -152,6 +198,9 @@ int copy_namespaces(unsigned long flags,
13379 return PTR_ERR(new_ns);
13380
13381 tsk->nsproxy = new_ns;
4bf69007 13382+ vxdprintk(VXD_CBIT(space, 3),
c2e5f7c8
JR
13383+ "copy_namespaces(0x%08lx,%p[%p]) = [%p]",
13384+ flags, tsk, old_ns, new_ns);
13385 return 0;
4bf69007
AM
13386 }
13387
c2e5f7c8 13388@@ -165,7 +214,9 @@ void free_nsproxy(struct nsproxy *ns)
4bf69007 13389 put_ipc_ns(ns->ipc_ns);
c2e5f7c8
JR
13390 if (ns->pid_ns_for_children)
13391 put_pid_ns(ns->pid_ns_for_children);
4bf69007
AM
13392- put_net(ns->net_ns);
13393+ if (ns->net_ns)
13394+ put_net(ns->net_ns);
13395+ atomic_dec(&vs_global_nsproxy);
13396 kmem_cache_free(nsproxy_cachep, ns);
13397 }
13398
c2e5f7c8 13399@@ -179,12 +230,16 @@ int unshare_nsproxy_namespaces(unsigned
b00e13aa 13400 struct user_namespace *user_ns;
4bf69007
AM
13401 int err = 0;
13402
13403+ vxdprintk(VXD_CBIT(space, 4),
13404+ "unshare_nsproxy_namespaces(0x%08lx,[%p])",
13405+ unshare_flags, current->nsproxy);
d337f35e 13406+
4bf69007 13407 if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
b00e13aa 13408 CLONE_NEWNET | CLONE_NEWPID)))
4bf69007
AM
13409 return 0;
13410
b00e13aa
AM
13411 user_ns = new_cred ? new_cred->user_ns : current_user_ns();
13412- if (!ns_capable(user_ns, CAP_SYS_ADMIN))
13413+ if (!vx_ns_can_unshare(user_ns, CAP_SYS_ADMIN, unshare_flags))
4bf69007
AM
13414 return -EPERM;
13415
b00e13aa 13416 *new_nsp = create_new_namespaces(unshare_flags, current, user_ns,
8de2f54c 13417diff -NurpP --minimal linux-4.4.111/kernel/pid.c linux-4.4.111-vs2.3.9.5/kernel/pid.c
f19bd705 13418--- linux-4.4.111/kernel/pid.c 2018-01-11 07:57:52.000000000 +0000
8de2f54c 13419+++ linux-4.4.111-vs2.3.9.5/kernel/pid.c 2018-01-09 21:54:23.000000000 +0000
09be7631 13420@@ -38,6 +38,7 @@
4bf69007 13421 #include <linux/syscalls.h>
09be7631 13422 #include <linux/proc_ns.h>
b00e13aa 13423 #include <linux/proc_fs.h>
4bf69007
AM
13424+#include <linux/vs_pid.h>
13425
13426 #define pid_hashfn(nr, ns) \
13427 hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
927ca606 13428@@ -379,7 +380,7 @@ EXPORT_SYMBOL_GPL(find_pid_ns);
4bf69007
AM
13429
13430 struct pid *find_vpid(int nr)
13431 {
b00e13aa
AM
13432- return find_pid_ns(nr, task_active_pid_ns(current));
13433+ return find_pid_ns(vx_rmap_pid(nr), task_active_pid_ns(current));
4bf69007
AM
13434 }
13435 EXPORT_SYMBOL_GPL(find_vpid);
13436
927ca606 13437@@ -435,6 +436,9 @@ void transfer_pid(struct task_struct *ol
4bf69007
AM
13438 struct task_struct *pid_task(struct pid *pid, enum pid_type type)
13439 {
13440 struct task_struct *result = NULL;
d337f35e 13441+
927ca606 13442+ if (type == __PIDTYPE_REALPID)
4bf69007
AM
13443+ type = PIDTYPE_PID;
13444 if (pid) {
13445 struct hlist_node *first;
13446 first = rcu_dereference_check(hlist_first_rcu(&pid->tasks[type]),
927ca606
AM
13447@@ -453,7 +457,7 @@ struct task_struct *find_task_by_pid_ns(
13448 {
13449 RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
13450 "find_task_by_pid_ns() needs rcu_read_lock() protection");
4bf69007
AM
13451- return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
13452+ return pid_task(find_pid_ns(vx_rmap_pid(nr), ns), PIDTYPE_PID);
13453 }
13454
13455 struct task_struct *find_task_by_vpid(pid_t vnr)
927ca606 13456@@ -497,7 +501,7 @@ struct pid *find_get_pid(pid_t nr)
4bf69007
AM
13457 }
13458 EXPORT_SYMBOL_GPL(find_get_pid);
13459
13460-pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
13461+pid_t pid_unmapped_nr_ns(struct pid *pid, struct pid_namespace *ns)
13462 {
13463 struct upid *upid;
13464 pid_t nr = 0;
927ca606 13465@@ -511,6 +515,11 @@ pid_t pid_nr_ns(struct pid *pid, struct
4bf69007
AM
13466 }
13467 EXPORT_SYMBOL_GPL(pid_nr_ns);
13468
13469+pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
2380c486 13470+{
4bf69007
AM
13471+ return vx_map_pid(pid_unmapped_nr_ns(pid, ns));
13472+}
d337f35e 13473+
4bf69007
AM
13474 pid_t pid_vnr(struct pid *pid)
13475 {
b00e13aa 13476 return pid_nr_ns(pid, task_active_pid_ns(current));
8de2f54c 13477diff -NurpP --minimal linux-4.4.111/kernel/pid_namespace.c linux-4.4.111-vs2.3.9.5/kernel/pid_namespace.c
f19bd705 13478--- linux-4.4.111/kernel/pid_namespace.c 2018-01-11 07:57:52.000000000 +0000
8de2f54c 13479+++ linux-4.4.111-vs2.3.9.5/kernel/pid_namespace.c 2018-01-09 16:36:33.000000000 +0000
b00e13aa 13480@@ -18,6 +18,7 @@
09be7631 13481 #include <linux/proc_ns.h>
4bf69007
AM
13482 #include <linux/reboot.h>
13483 #include <linux/export.h>
13484+#include <linux/vserver/global.h>
13485
09be7631
JR
13486 struct pid_cache {
13487 int nr_ids;
927ca606
AM
13488@@ -111,6 +112,7 @@ static struct pid_namespace *create_pid_
13489 ns->ns.ops = &pidns_operations;
4bf69007
AM
13490
13491 kref_init(&ns->kref);
13492+ atomic_inc(&vs_global_pid_ns);
13493 ns->level = level;
13494 ns->parent = get_pid_ns(parent_pid_ns);
b00e13aa 13495 ns->user_ns = get_user_ns(user_ns);
927ca606 13496@@ -128,6 +130,7 @@ static struct pid_namespace *create_pid_
c2e5f7c8
JR
13497 out_free_map:
13498 kfree(ns->pidmap[0].page);
13499 out_free:
4bf69007
AM
13500+ atomic_dec(&vs_global_pid_ns);
13501 kmem_cache_free(pid_ns_cachep, ns);
c2e5f7c8
JR
13502 out:
13503 return ERR_PTR(err);
8de2f54c 13504diff -NurpP --minimal linux-4.4.111/kernel/printk/printk.c linux-4.4.111-vs2.3.9.5/kernel/printk/printk.c
f19bd705 13505--- linux-4.4.111/kernel/printk/printk.c 2018-01-11 07:57:52.000000000 +0000
8de2f54c 13506+++ linux-4.4.111-vs2.3.9.5/kernel/printk/printk.c 2018-01-09 16:36:33.000000000 +0000
bb20add7 13507@@ -46,6 +46,7 @@
09be7631 13508 #include <linux/utsname.h>
bb20add7 13509 #include <linux/ctype.h>
927ca606 13510 #include <linux/uio.h>
4bf69007
AM
13511+#include <linux/vs_cvirt.h>
13512
13513 #include <asm/uaccess.h>
13514
927ca606
AM
13515@@ -502,7 +503,7 @@ int check_syslog_permissions(int type, i
13516 goto ok;
4bf69007
AM
13517
13518 if (syslog_action_restricted(type)) {
13519- if (capable(CAP_SYSLOG))
13520+ if (vx_capable(CAP_SYSLOG, VXC_SYSLOG))
927ca606 13521 goto ok;
092a4f51
JR
13522 /*
13523 * For historical reasons, accept CAP_SYS_ADMIN too, with
927ca606 13524@@ -1304,12 +1305,9 @@ int do_syslog(int type, char __user *buf
4bf69007 13525 if (error)
927ca606 13526 goto out;
4bf69007
AM
13527
13528- switch (type) {
13529- case SYSLOG_ACTION_CLOSE: /* Close log */
13530- break;
13531- case SYSLOG_ACTION_OPEN: /* Open log */
13532- break;
13533- case SYSLOG_ACTION_READ: /* Read from log */
13534+ if ((type == SYSLOG_ACTION_READ) ||
13535+ (type == SYSLOG_ACTION_READ_ALL) ||
13536+ (type == SYSLOG_ACTION_READ_CLEAR)) {
13537 error = -EINVAL;
13538 if (!buf || len < 0)
13539 goto out;
927ca606 13540@@ -1320,6 +1318,16 @@ int do_syslog(int type, char __user *buf
4bf69007
AM
13541 error = -EFAULT;
13542 goto out;
13543 }
13544+ }
13545+ if (!vx_check(0, VS_ADMIN|VS_WATCH))
13546+ return vx_do_syslog(type, buf, len);
d337f35e 13547+
4bf69007
AM
13548+ switch (type) {
13549+ case SYSLOG_ACTION_CLOSE: /* Close log */
13550+ break;
13551+ case SYSLOG_ACTION_OPEN: /* Open log */
13552+ break;
13553+ case SYSLOG_ACTION_READ: /* Read from log */
13554 error = wait_event_interruptible(log_wait,
13555 syslog_seq != log_next_seq);
13556 if (error)
927ca606 13557@@ -1332,16 +1340,6 @@ int do_syslog(int type, char __user *buf
4bf69007
AM
13558 /* FALL THRU */
13559 /* Read last kernel messages */
13560 case SYSLOG_ACTION_READ_ALL:
13561- error = -EINVAL;
13562- if (!buf || len < 0)
13563- goto out;
13564- error = 0;
13565- if (!len)
13566- goto out;
13567- if (!access_ok(VERIFY_WRITE, buf, len)) {
13568- error = -EFAULT;
13569- goto out;
13570- }
13571 error = syslog_print_all(buf, len, clear);
13572 break;
13573 /* Clear ring buffer */
8de2f54c 13574diff -NurpP --minimal linux-4.4.111/kernel/ptrace.c linux-4.4.111-vs2.3.9.5/kernel/ptrace.c
f19bd705 13575--- linux-4.4.111/kernel/ptrace.c 2018-01-11 07:57:52.000000000 +0000
8de2f54c 13576+++ linux-4.4.111-vs2.3.9.5/kernel/ptrace.c 2018-01-09 16:36:33.000000000 +0000
09be7631 13577@@ -23,6 +23,7 @@
4bf69007
AM
13578 #include <linux/syscalls.h>
13579 #include <linux/uaccess.h>
13580 #include <linux/regset.h>
13581+#include <linux/vs_context.h>
13582 #include <linux/hw_breakpoint.h>
13583 #include <linux/cn_proc.h>
09be7631 13584 #include <linux/compat.h>
927ca606
AM
13585@@ -295,6 +296,11 @@ ok:
13586 !ptrace_has_cap(mm->user_ns, mode)))
13587 return -EPERM;
b00e13aa 13588
4bf69007
AM
13589+ if (!vx_check(task->xid, VS_ADMIN_P|VS_WATCH_P|VS_IDENT))
13590+ return -EPERM;
13591+ if (!vx_check(task->xid, VS_IDENT) &&
13592+ !task_vx_flags(task, VXF_STATE_ADMIN, 0))
13593+ return -EACCES;
4bf69007
AM
13594 return security_ptrace_access_check(task, mode);
13595 }
b00e13aa 13596
8de2f54c 13597diff -NurpP --minimal linux-4.4.111/kernel/reboot.c linux-4.4.111-vs2.3.9.5/kernel/reboot.c
f19bd705 13598--- linux-4.4.111/kernel/reboot.c 2016-07-05 04:12:39.000000000 +0000
8de2f54c 13599+++ linux-4.4.111-vs2.3.9.5/kernel/reboot.c 2018-01-09 16:36:33.000000000 +0000
c2e5f7c8
JR
13600@@ -16,6 +16,7 @@
13601 #include <linux/syscalls.h>
13602 #include <linux/syscore_ops.h>
13603 #include <linux/uaccess.h>
13604+#include <linux/vs_pid.h>
13605
13606 /*
13607 * this indicates whether you can reboot with ctrl-alt-del: the default is yes
bb20add7 13608@@ -269,6 +270,8 @@ EXPORT_SYMBOL_GPL(kernel_power_off);
c2e5f7c8
JR
13609
13610 static DEFINE_MUTEX(reboot_mutex);
13611
13612+long vs_reboot(unsigned int, void __user *);
13613+
13614 /*
13615 * Reboot system call: for obvious reasons only root may call it,
13616 * and even root needs to set up some magic numbers in the registers
bb20add7 13617@@ -311,6 +314,9 @@ SYSCALL_DEFINE4(reboot, int, magic1, int
c2e5f7c8
JR
13618 if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
13619 cmd = LINUX_REBOOT_CMD_HALT;
13620
13621+ if (!vx_check(0, VS_ADMIN|VS_WATCH))
13622+ return vs_reboot(cmd, arg);
13623+
13624 mutex_lock(&reboot_mutex);
13625 switch (cmd) {
13626 case LINUX_REBOOT_CMD_RESTART:
8de2f54c 13627diff -NurpP --minimal linux-4.4.111/kernel/sched/core.c linux-4.4.111-vs2.3.9.5/kernel/sched/core.c
f19bd705 13628--- linux-4.4.111/kernel/sched/core.c 2018-01-11 07:57:52.000000000 +0000
8de2f54c 13629+++ linux-4.4.111-vs2.3.9.5/kernel/sched/core.c 2018-01-09 16:36:33.000000000 +0000
bb20add7 13630@@ -74,6 +74,8 @@
4bf69007 13631 #include <linux/binfmts.h>
b00e13aa 13632 #include <linux/context_tracking.h>
265de2f7 13633 #include <linux/compiler.h>
4bf69007
AM
13634+#include <linux/vs_sched.h>
13635+#include <linux/vs_cvirt.h>
13636
13637 #include <asm/switch_to.h>
13638 #include <asm/tlb.h>
927ca606 13639@@ -3558,7 +3560,7 @@ SYSCALL_DEFINE1(nice, int, increment)
4bf69007 13640
bb20add7 13641 nice = clamp_val(nice, MIN_NICE, MAX_NICE);
4bf69007
AM
13642 if (increment < 0 && !can_nice(current, nice))
13643- return -EPERM;
13644+ return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
13645
13646 retval = security_task_setnice(current, nice);
13647 if (retval)
8de2f54c 13648diff -NurpP --minimal linux-4.4.111/kernel/sched/cputime.c linux-4.4.111-vs2.3.9.5/kernel/sched/cputime.c
f19bd705 13649--- linux-4.4.111/kernel/sched/cputime.c 2018-01-11 07:57:52.000000000 +0000
8de2f54c 13650+++ linux-4.4.111-vs2.3.9.5/kernel/sched/cputime.c 2018-01-09 16:36:33.000000000 +0000
b00e13aa 13651@@ -4,6 +4,7 @@
4bf69007
AM
13652 #include <linux/kernel_stat.h>
13653 #include <linux/static_key.h>
b00e13aa 13654 #include <linux/context_tracking.h>
4bf69007
AM
13655+#include <linux/vs_sched.h>
13656 #include "sched.h"
13657
13658
bb20add7 13659@@ -135,14 +136,17 @@ static inline void task_group_account_fi
4bf69007
AM
13660 void account_user_time(struct task_struct *p, cputime_t cputime,
13661 cputime_t cputime_scaled)
13662 {
13663+ struct vx_info *vxi = p->vx_info; /* p is _always_ current */
ca5d134c 13664+ int nice = (task_nice(p) > 0);
4bf69007
AM
13665 int index;
13666
13667 /* Add user time to process. */
13668 p->utime += cputime;
13669 p->utimescaled += cputime_scaled;
13670+ vx_account_user(vxi, cputime, nice);
13671 account_group_user_time(p, cputime);
13672
ca5d134c 13673- index = (task_nice(p) > 0) ? CPUTIME_NICE : CPUTIME_USER;
4bf69007
AM
13674+ index = (nice) ? CPUTIME_NICE : CPUTIME_USER;
13675
13676 /* Add user time to cpustat. */
13677 task_group_account_field(p, index, (__force u64) cputime);
bb20add7 13678@@ -189,9 +193,12 @@ static inline
ca5d134c
JR
13679 void __account_system_time(struct task_struct *p, cputime_t cputime,
13680 cputime_t cputime_scaled, int index)
13681 {
13682+ struct vx_info *vxi = p->vx_info; /* p is _always_ current */
13683+
13684 /* Add system time to process. */
13685 p->stime += cputime;
13686 p->stimescaled += cputime_scaled;
13687+ vx_account_system(vxi, cputime, 0 /* do we have idle time? */);
13688 account_group_system_time(p, cputime);
13689
13690 /* Add system time to cpustat. */
8de2f54c 13691diff -NurpP --minimal linux-4.4.111/kernel/sched/fair.c linux-4.4.111-vs2.3.9.5/kernel/sched/fair.c
f19bd705 13692--- linux-4.4.111/kernel/sched/fair.c 2018-01-11 07:57:52.000000000 +0000
8de2f54c 13693+++ linux-4.4.111-vs2.3.9.5/kernel/sched/fair.c 2018-01-09 16:36:33.000000000 +0000
bb20add7 13694@@ -30,6 +30,7 @@
b00e13aa
AM
13695 #include <linux/mempolicy.h>
13696 #include <linux/migrate.h>
13697 #include <linux/task_work.h>
4bf69007
AM
13698+#include <linux/vs_cvirt.h>
13699
13700 #include <trace/events/sched.h>
13701
927ca606 13702@@ -3055,6 +3056,8 @@ enqueue_entity(struct cfs_rq *cfs_rq, st
4bf69007
AM
13703 __enqueue_entity(cfs_rq, se);
13704 se->on_rq = 1;
13705
13706+ if (entity_is_task(se))
13707+ vx_activate_task(task_of(se));
13708 if (cfs_rq->nr_running == 1) {
13709 list_add_leaf_cfs_rq(cfs_rq);
13710 check_enqueue_throttle(cfs_rq);
927ca606 13711@@ -3136,6 +3139,8 @@ dequeue_entity(struct cfs_rq *cfs_rq, st
4bf69007
AM
13712 if (se != cfs_rq->curr)
13713 __dequeue_entity(cfs_rq, se);
13714 se->on_rq = 0;
13715+ if (entity_is_task(se))
13716+ vx_deactivate_task(task_of(se));
4bf69007
AM
13717 account_entity_dequeue(cfs_rq, se);
13718
b00e13aa 13719 /*
8de2f54c 13720diff -NurpP --minimal linux-4.4.111/kernel/signal.c linux-4.4.111-vs2.3.9.5/kernel/signal.c
f19bd705 13721--- linux-4.4.111/kernel/signal.c 2018-01-11 07:57:52.000000000 +0000
8de2f54c 13722+++ linux-4.4.111-vs2.3.9.5/kernel/signal.c 2018-01-11 08:03:00.000000000 +0000
bb20add7 13723@@ -34,6 +34,8 @@
b00e13aa 13724 #include <linux/compat.h>
09be7631 13725 #include <linux/cn_proc.h>
265de2f7 13726 #include <linux/compiler.h>
4bf69007
AM
13727+#include <linux/vs_context.h>
13728+#include <linux/vs_pid.h>
265de2f7 13729
4bf69007
AM
13730 #define CREATE_TRACE_POINTS
13731 #include <trace/events/signal.h>
f19bd705 13732@@ -726,9 +728,18 @@ static int check_kill_permission(int sig
4bf69007
AM
13733 struct pid *sid;
13734 int error;
13735
13736+ vxdprintk(VXD_CBIT(misc, 7),
13737+ "check_kill_permission(%d,%p,%p[#%u,%u])",
13738+ sig, info, t, vx_task_xid(t), t->pid);
d337f35e 13739+
4bf69007
AM
13740 if (!valid_signal(sig))
13741 return -EINVAL;
13742
13743+/* FIXME: needed? if so, why?
13744+ if ((info != SEND_SIG_NOINFO) &&
13745+ (is_si_special(info) || !si_fromuser(info)))
13746+ goto skip; */
d337f35e 13747+
4bf69007
AM
13748 if (!si_fromuser(info))
13749 return 0;
13750
f19bd705 13751@@ -752,6 +763,20 @@ static int check_kill_permission(int sig
4bf69007
AM
13752 }
13753 }
13754
13755+ error = -EPERM;
13756+ if (t->pid == 1 && current->xid)
13757+ return error;
d337f35e 13758+
4bf69007
AM
13759+ error = -ESRCH;
13760+ /* FIXME: we shouldn't return ESRCH ever, to avoid
13761+ loops, maybe ENOENT or EACCES? */
13762+ if (!vx_check(vx_task_xid(t), VS_WATCH_P | VS_IDENT)) {
13763+ vxdprintk(current->xid || VXD_CBIT(misc, 7),
13764+ "signal %d[%p] xid mismatch %p[#%u,%u] xid=#%u",
13765+ sig, info, t, vx_task_xid(t), t->pid, current->xid);
13766+ return error;
2380c486 13767+ }
4bf69007
AM
13768+/* skip: */
13769 return security_task_kill(t, info, sig, 0);
13770 }
13771
f19bd705 13772@@ -1303,8 +1328,14 @@ int kill_pid_info(int sig, struct siginf
927ca606
AM
13773 for (;;) {
13774 rcu_read_lock();
13775 p = pid_task(pid, PIDTYPE_PID);
13776- if (p)
13777- error = group_send_sig_info(sig, info, p);
13778+ if (p) {
13779+ if (vx_check(vx_task_xid(p), VS_IDENT))
13780+ error = group_send_sig_info(sig, info, p);
13781+ else {
13782+ rcu_read_unlock();
13783+ return -ESRCH;
13784+ }
13785+ }
13786 rcu_read_unlock();
13787 if (likely(!p || error != -ESRCH))
13788 return error;
f19bd705 13789@@ -1349,7 +1380,7 @@ int kill_pid_info_as_cred(int sig, struc
4bf69007
AM
13790
13791 rcu_read_lock();
13792 p = pid_task(pid, PIDTYPE_PID);
13793- if (!p) {
13794+ if (!p || !vx_check(vx_task_xid(p), VS_IDENT)) {
13795 ret = -ESRCH;
13796 goto out_unlock;
13797 }
f19bd705 13798@@ -1401,8 +1432,10 @@ static int kill_something_info(int sig,
4bf69007
AM
13799 struct task_struct * p;
13800
13801 for_each_process(p) {
13802- if (task_pid_vnr(p) > 1 &&
13803- !same_thread_group(p, current)) {
13804+ if (vx_check(vx_task_xid(p), VS_ADMIN|VS_IDENT) &&
13805+ task_pid_vnr(p) > 1 &&
13806+ !same_thread_group(p, current) &&
13807+ !vx_current_initpid(p->pid)) {
13808 int err = group_send_sig_info(sig, info, p);
13809 ++count;
13810 if (err != -EPERM)
f19bd705 13811@@ -2255,6 +2288,11 @@ relock:
4bf69007
AM
13812 !sig_kernel_only(signr))
13813 continue;
13814
13815+ /* virtual init is protected against user signals */
bb20add7 13816+ if ((ksig->info.si_code == SI_USER) &&
4bf69007
AM
13817+ vx_current_initpid(current->pid))
13818+ continue;
d337f35e 13819+
4bf69007
AM
13820 if (sig_kernel_stop(signr)) {
13821 /*
13822 * The default action is to stop all threads in
8de2f54c 13823diff -NurpP --minimal linux-4.4.111/kernel/softirq.c linux-4.4.111-vs2.3.9.5/kernel/softirq.c
f19bd705 13824--- linux-4.4.111/kernel/softirq.c 2015-04-12 22:12:50.000000000 +0000
8de2f54c 13825+++ linux-4.4.111-vs2.3.9.5/kernel/softirq.c 2018-01-09 16:36:34.000000000 +0000
bb20add7 13826@@ -26,6 +26,7 @@
4bf69007
AM
13827 #include <linux/smpboot.h>
13828 #include <linux/tick.h>
265de2f7 13829 #include <linux/irq.h>
4bf69007
AM
13830+#include <linux/vs_context.h>
13831
13832 #define CREATE_TRACE_POINTS
13833 #include <trace/events/irq.h>
8de2f54c 13834diff -NurpP --minimal linux-4.4.111/kernel/sys.c linux-4.4.111-vs2.3.9.5/kernel/sys.c
f19bd705 13835--- linux-4.4.111/kernel/sys.c 2018-01-11 07:57:52.000000000 +0000
8de2f54c 13836+++ linux-4.4.111-vs2.3.9.5/kernel/sys.c 2018-01-09 17:00:36.000000000 +0000
c2e5f7c8 13837@@ -54,6 +54,7 @@
09be7631 13838 #include <linux/cred.h>
4bf69007
AM
13839
13840 #include <linux/kmsg_dump.h>
b00e13aa 13841+#include <linux/vs_pid.h>
4bf69007 13842 /* Move somewhere else to avoid recompiling? */
b00e13aa
AM
13843 #include <generated/utsrelease.h>
13844
927ca606 13845@@ -157,7 +158,10 @@ static int set_one_prio(struct task_stru
4bf69007
AM
13846 goto out;
13847 }
13848 if (niceval < task_nice(p) && !can_nice(p, niceval)) {
13849- error = -EACCES;
13850+ if (vx_flags(VXF_IGNEG_NICE, 0))
13851+ error = 0;
13852+ else
13853+ error = -EACCES;
13854 goto out;
13855 }
13856 no_nice = security_task_setnice(p, niceval);
927ca606 13857@@ -208,6 +212,8 @@ SYSCALL_DEFINE3(setpriority, int, which,
bb20add7
AM
13858 else
13859 pgrp = task_pgrp(current);
13860 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
13861+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
13862+ continue;
13863 error = set_one_prio(p, niceval, error);
13864 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
13865 break;
927ca606 13866@@ -274,6 +280,8 @@ SYSCALL_DEFINE2(getpriority, int, which,
bb20add7
AM
13867 else
13868 pgrp = task_pgrp(current);
13869 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
13870+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
13871+ continue;
13872 niceval = nice_to_rlimit(task_nice(p));
13873 if (niceval > retval)
13874 retval = niceval;
927ca606 13875@@ -290,6 +298,8 @@ SYSCALL_DEFINE2(getpriority, int, which,
bb20add7
AM
13876 goto out_unlock; /* No processes for this user */
13877 }
13878 do_each_thread(g, p) {
13879+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
13880+ continue;
927ca606 13881 if (uid_eq(task_uid(p), uid) && task_pid_vnr(p)) {
bb20add7 13882 niceval = nice_to_rlimit(task_nice(p));
4bf69007 13883 if (niceval > retval)
927ca606 13884@@ -1217,7 +1227,8 @@ SYSCALL_DEFINE2(sethostname, char __user
4bf69007
AM
13885 int errno;
13886 char tmp[__NEW_UTS_LEN];
13887
13888- if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
13889+ if (!vx_ns_capable(current->nsproxy->uts_ns->user_ns,
13890+ CAP_SYS_ADMIN, VXC_SET_UTSNAME))
13891 return -EPERM;
13892
13893 if (len < 0 || len > __NEW_UTS_LEN)
927ca606 13894@@ -1268,7 +1279,8 @@ SYSCALL_DEFINE2(setdomainname, char __us
4bf69007
AM
13895 int errno;
13896 char tmp[__NEW_UTS_LEN];
13897
13898- if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
13899+ if (!vx_ns_capable(current->nsproxy->uts_ns->user_ns,
13900+ CAP_SYS_ADMIN, VXC_SET_UTSNAME))
13901 return -EPERM;
13902 if (len < 0 || len > __NEW_UTS_LEN)
13903 return -EINVAL;
927ca606 13904@@ -1386,7 +1398,7 @@ int do_prlimit(struct task_struct *tsk,
4bf69007
AM
13905 /* Keep the capable check against init_user_ns until
13906 cgroups can contain all limits */
13907 if (new_rlim->rlim_max > rlim->rlim_max &&
13908- !capable(CAP_SYS_RESOURCE))
13909+ !vx_capable(CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
13910 retval = -EPERM;
13911 if (!retval)
13912 retval = security_task_setrlimit(tsk->group_leader,
927ca606 13913@@ -1439,7 +1451,8 @@ static int check_prlimit_permission(stru
4bf69007
AM
13914 gid_eq(cred->gid, tcred->sgid) &&
13915 gid_eq(cred->gid, tcred->gid))
13916 return 0;
13917- if (ns_capable(tcred->user_ns, CAP_SYS_RESOURCE))
13918+ if (vx_ns_capable(tcred->user_ns,
13919+ CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
13920 return 0;
13921
13922 return -EPERM;
8de2f54c 13923diff -NurpP --minimal linux-4.4.111/kernel/sysctl.c linux-4.4.111-vs2.3.9.5/kernel/sysctl.c
f19bd705 13924--- linux-4.4.111/kernel/sysctl.c 2018-01-11 07:57:52.000000000 +0000
8de2f54c 13925+++ linux-4.4.111-vs2.3.9.5/kernel/sysctl.c 2018-01-09 16:36:34.000000000 +0000
927ca606 13926@@ -87,6 +87,7 @@
4bf69007
AM
13927 #if defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_LOCK_STAT)
13928 #include <linux/lockdep.h>
13929 #endif
13930+extern char vshelper_path[];
13931 #ifdef CONFIG_CHR_DEV_SG
13932 #include <scsi/sg.h>
13933 #endif
927ca606 13934@@ -279,6 +280,13 @@ static int max_extfrag_threshold = 1000;
bb20add7
AM
13935
13936 static struct ctl_table kern_table[] = {
13937 {
4bf69007
AM
13938+ .procname = "vshelper",
13939+ .data = &vshelper_path,
13940+ .maxlen = 256,
13941+ .mode = 0644,
bb20add7 13942+ .proc_handler = proc_dostring,
4bf69007 13943+ },
bb20add7
AM
13944+ {
13945 .procname = "sched_child_runs_first",
13946 .data = &sysctl_sched_child_runs_first,
13947 .maxlen = sizeof(unsigned int),
927ca606
AM
13948@@ -1385,7 +1393,6 @@ static struct ctl_table vm_table[] = {
13949 .extra1 = &zero,
13950 .extra2 = &one,
bb20add7
AM
13951 },
13952-
13953 #endif /* CONFIG_COMPACTION */
4bf69007 13954 {
bb20add7 13955 .procname = "min_free_kbytes",
8de2f54c 13956diff -NurpP --minimal linux-4.4.111/kernel/sysctl_binary.c linux-4.4.111-vs2.3.9.5/kernel/sysctl_binary.c
f19bd705 13957--- linux-4.4.111/kernel/sysctl_binary.c 2018-01-11 07:57:52.000000000 +0000
8de2f54c 13958+++ linux-4.4.111-vs2.3.9.5/kernel/sysctl_binary.c 2018-01-09 16:36:34.000000000 +0000
c2e5f7c8 13959@@ -73,6 +73,7 @@ static const struct bin_table bin_kern_t
4bf69007
AM
13960
13961 { CTL_INT, KERN_PANIC, "panic" },
13962 { CTL_INT, KERN_REALROOTDEV, "real-root-dev" },
13963+ { CTL_STR, KERN_VSHELPER, "vshelper" },
13964
13965 { CTL_STR, KERN_SPARC_REBOOT, "reboot-cmd" },
13966 { CTL_INT, KERN_CTLALTDEL, "ctrl-alt-del" },
8de2f54c 13967diff -NurpP --minimal linux-4.4.111/kernel/time/posix-timers.c linux-4.4.111-vs2.3.9.5/kernel/time/posix-timers.c
f19bd705 13968--- linux-4.4.111/kernel/time/posix-timers.c 2018-01-11 07:57:52.000000000 +0000
8de2f54c 13969+++ linux-4.4.111-vs2.3.9.5/kernel/time/posix-timers.c 2018-01-09 16:36:34.000000000 +0000
bb20add7
AM
13970@@ -48,6 +48,7 @@
13971 #include <linux/workqueue.h>
13972 #include <linux/export.h>
13973 #include <linux/hashtable.h>
13974+#include <linux/vs_context.h>
4bf69007 13975
bb20add7 13976 #include "timekeeping.h"
4bf69007 13977
927ca606 13978@@ -407,6 +408,7 @@ int posix_timer_event(struct k_itimer *t
bb20add7
AM
13979 {
13980 struct task_struct *task;
13981 int shared, ret = -1;
13982+
13983 /*
13984 * FIXME: if ->sigq is queued we can race with
13985 * dequeue_signal()->do_schedule_next_timer().
927ca606 13986@@ -423,10 +425,18 @@ int posix_timer_event(struct k_itimer *t
bb20add7
AM
13987 rcu_read_lock();
13988 task = pid_task(timr->it_pid, PIDTYPE_PID);
13989 if (task) {
13990+ struct vx_info_save vxis;
13991+ struct vx_info *vxi;
13992+
13993+ vxi = get_vx_info(task->vx_info);
13994+ enter_vx_info(vxi, &vxis);
13995 shared = !(timr->it_sigev_notify & SIGEV_THREAD_ID);
13996 ret = send_sigqueue(timr->sigq, task, shared);
13997+ leave_vx_info(&vxis);
13998+ put_vx_info(vxi);
13999 }
14000 rcu_read_unlock();
14001+
14002 /* If we failed to send the signal the timer stops. */
14003 return ret > 0;
4bf69007 14004 }
8de2f54c 14005diff -NurpP --minimal linux-4.4.111/kernel/time/time.c linux-4.4.111-vs2.3.9.5/kernel/time/time.c
f19bd705 14006--- linux-4.4.111/kernel/time/time.c 2016-07-05 04:12:39.000000000 +0000
8de2f54c 14007+++ linux-4.4.111-vs2.3.9.5/kernel/time/time.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
14008@@ -37,6 +37,7 @@
14009 #include <linux/fs.h>
14010 #include <linux/math64.h>
14011 #include <linux/ptrace.h>
14012+#include <linux/vs_time.h>
14013
14014 #include <asm/uaccess.h>
14015 #include <asm/unistd.h>
bb20add7 14016@@ -93,7 +94,7 @@ SYSCALL_DEFINE1(stime, time_t __user *,
4bf69007
AM
14017 if (err)
14018 return err;
14019
14020- do_settimeofday(&tv);
14021+ vx_settimeofday(&tv);
14022 return 0;
14023 }
14024
927ca606 14025@@ -186,7 +187,7 @@ int do_sys_settimeofday(const struct tim
4bf69007
AM
14026 }
14027 }
14028 if (tv)
14029- return do_settimeofday(tv);
14030+ return vx_settimeofday(tv);
14031 return 0;
14032 }
14033
8de2f54c 14034diff -NurpP --minimal linux-4.4.111/kernel/time/timekeeping.c linux-4.4.111-vs2.3.9.5/kernel/time/timekeeping.c
f19bd705 14035--- linux-4.4.111/kernel/time/timekeeping.c 2018-01-11 07:57:52.000000000 +0000
8de2f54c 14036+++ linux-4.4.111-vs2.3.9.5/kernel/time/timekeeping.c 2018-01-09 17:02:47.000000000 +0000
bb20add7
AM
14037@@ -23,6 +23,7 @@
14038 #include <linux/stop_machine.h>
14039 #include <linux/pvclock_gtod.h>
14040 #include <linux/compiler.h>
14041+#include <linux/vs_time.h>
14042
14043 #include "tick-internal.h"
14044 #include "ntp_internal.h"
927ca606 14045@@ -921,7 +922,9 @@ void ktime_get_raw_and_real_ts64(struct
bb20add7
AM
14046 } while (read_seqcount_retry(&tk_core.seq, seq));
14047
927ca606 14048 timespec64_add_ns(ts_raw, nsecs_raw);
bb20add7 14049+ vx_adjust_timespec(ts_raw);
927ca606 14050 timespec64_add_ns(ts_real, nsecs_real);
bb20add7
AM
14051+ vx_adjust_timespec(ts_real);
14052 }
927ca606 14053 EXPORT_SYMBOL(ktime_get_raw_and_real_ts64);
bb20add7 14054
8de2f54c 14055diff -NurpP --minimal linux-4.4.111/kernel/time/timer.c linux-4.4.111-vs2.3.9.5/kernel/time/timer.c
f19bd705 14056--- linux-4.4.111/kernel/time/timer.c 2018-01-11 07:57:52.000000000 +0000
8de2f54c 14057+++ linux-4.4.111-vs2.3.9.5/kernel/time/timer.c 2018-01-09 16:36:34.000000000 +0000
09be7631 14058@@ -42,6 +42,10 @@
b00e13aa 14059 #include <linux/sched/sysctl.h>
4bf69007 14060 #include <linux/slab.h>
09be7631 14061 #include <linux/compat.h>
4bf69007
AM
14062+#include <linux/vs_base.h>
14063+#include <linux/vs_cvirt.h>
14064+#include <linux/vs_pid.h>
14065+#include <linux/vserver/sched.h>
14066
14067 #include <asm/uaccess.h>
14068 #include <asm/unistd.h>
8de2f54c 14069diff -NurpP --minimal linux-4.4.111/kernel/user_namespace.c linux-4.4.111-vs2.3.9.5/kernel/user_namespace.c
f19bd705 14070--- linux-4.4.111/kernel/user_namespace.c 2016-07-05 04:12:39.000000000 +0000
8de2f54c 14071+++ linux-4.4.111-vs2.3.9.5/kernel/user_namespace.c 2018-01-09 16:36:34.000000000 +0000
b00e13aa 14072@@ -22,6 +22,7 @@
4bf69007
AM
14073 #include <linux/ctype.h>
14074 #include <linux/projid.h>
b00e13aa 14075 #include <linux/fs_struct.h>
4bf69007
AM
14076+#include <linux/vserver/global.h>
14077
14078 static struct kmem_cache *user_ns_cachep __read_mostly;
bb20add7 14079 static DEFINE_MUTEX(userns_state_mutex);
927ca606 14080@@ -97,6 +98,7 @@ int create_user_ns(struct cred *new)
4bf69007 14081
b00e13aa
AM
14082 atomic_set(&ns->count, 1);
14083 /* Leave the new->user_ns reference with the new user namespace. */
4bf69007
AM
14084+ atomic_inc(&vs_global_user_ns);
14085 ns->parent = parent_ns;
09be7631 14086 ns->level = parent_ns->level + 1;
4bf69007 14087 ns->owner = owner;
927ca606
AM
14088@@ -145,6 +147,7 @@ void free_user_ns(struct user_namespace
14089 key_put(ns->persistent_keyring_register);
14090 #endif
14091 ns_free_inum(&ns->ns);
14092+ atomic_dec(&vs_global_user_ns);
14093 kmem_cache_free(user_ns_cachep, ns);
14094 ns = parent;
14095 } while (atomic_dec_and_test(&parent->count));
14096@@ -358,6 +361,18 @@ gid_t from_kgid_munged(struct user_names
bb20add7
AM
14097 }
14098 EXPORT_SYMBOL(from_kgid_munged);
14099
14100+ktag_t make_ktag(struct user_namespace *from, vtag_t tag)
14101+{
14102+ return KTAGT_INIT(tag);
14103+}
14104+EXPORT_SYMBOL(make_ktag);
14105+
14106+vtag_t from_ktag(struct user_namespace *to, ktag_t tag)
14107+{
14108+ return __ktag_val(tag);
14109+}
14110+EXPORT_SYMBOL(from_ktag);
14111+
14112 /**
14113 * make_kprojid - Map a user-namespace projid pair into a kprojid.
14114 * @ns: User namespace that the projid is in
8de2f54c 14115diff -NurpP --minimal linux-4.4.111/kernel/utsname.c linux-4.4.111-vs2.3.9.5/kernel/utsname.c
f19bd705 14116--- linux-4.4.111/kernel/utsname.c 2015-04-12 22:12:50.000000000 +0000
8de2f54c 14117+++ linux-4.4.111-vs2.3.9.5/kernel/utsname.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
14118@@ -16,14 +16,17 @@
14119 #include <linux/slab.h>
14120 #include <linux/user_namespace.h>
09be7631 14121 #include <linux/proc_ns.h>
4bf69007
AM
14122+#include <linux/vserver/global.h>
14123
14124 static struct uts_namespace *create_uts_ns(void)
14125 {
14126 struct uts_namespace *uts_ns;
14127
14128 uts_ns = kmalloc(sizeof(struct uts_namespace), GFP_KERNEL);
14129- if (uts_ns)
14130+ if (uts_ns) {
c2e5f7c8 14131 kref_init(&uts_ns->kref);
4bf69007
AM
14132+ atomic_inc(&vs_global_uts_ns);
14133+ }
14134 return uts_ns;
14135 }
14136
927ca606 14137@@ -87,6 +90,7 @@ void free_uts_ns(struct kref *kref)
4bf69007
AM
14138 ns = container_of(kref, struct uts_namespace, kref);
14139 put_user_ns(ns->user_ns);
927ca606 14140 ns_free_inum(&ns->ns);
4bf69007
AM
14141+ atomic_dec(&vs_global_uts_ns);
14142 kfree(ns);
14143 }
14144
8de2f54c 14145diff -NurpP --minimal linux-4.4.111/kernel/vserver/Kconfig linux-4.4.111-vs2.3.9.5/kernel/vserver/Kconfig
f19bd705 14146--- linux-4.4.111/kernel/vserver/Kconfig 1970-01-01 00:00:00.000000000 +0000
8de2f54c 14147+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/Kconfig 2018-01-09 16:36:34.000000000 +0000
c2e5f7c8 14148@@ -0,0 +1,230 @@
4bf69007
AM
14149+#
14150+# Linux VServer configuration
14151+#
d337f35e 14152+
4bf69007 14153+menu "Linux VServer"
d337f35e 14154+
4bf69007
AM
14155+config VSERVER_AUTO_LBACK
14156+ bool "Automatically Assign Loopback IP"
14157+ default y
14158+ help
14159+ Automatically assign a guest specific loopback
14160+ IP and add it to the kernel network stack on
14161+ startup.
d337f35e 14162+
4bf69007
AM
14163+config VSERVER_AUTO_SINGLE
14164+ bool "Automatic Single IP Special Casing"
c2e5f7c8 14165+ default n
4bf69007
AM
14166+ help
14167+ This allows network contexts with a single IP to
14168+ automatically remap 0.0.0.0 bindings to that IP,
14169+ avoiding further network checks and improving
14170+ performance.
d337f35e 14171+
4bf69007
AM
14172+ (note: such guests do not allow to change the ip
14173+ on the fly and do not show loopback addresses)
2380c486 14174+
4bf69007
AM
14175+config VSERVER_COWBL
14176+ bool "Enable COW Immutable Link Breaking"
14177+ default y
14178+ help
14179+ This enables the COW (Copy-On-Write) link break code.
14180+ It allows you to treat unified files like normal files
14181+ when writing to them (which will implicitely break the
14182+ link and create a copy of the unified file)
d337f35e 14183+
4bf69007 14184+config VSERVER_VTIME
c2e5f7c8 14185+ bool "Enable Virtualized Guest Time (EXPERIMENTAL)"
4bf69007
AM
14186+ default n
14187+ help
14188+ This enables per guest time offsets to allow for
14189+ adjusting the system clock individually per guest.
14190+ this adds some overhead to the time functions and
14191+ therefore should not be enabled without good reason.
d337f35e 14192+
4bf69007 14193+config VSERVER_DEVICE
c2e5f7c8 14194+ bool "Enable Guest Device Mapping (EXPERIMENTAL)"
4bf69007
AM
14195+ default n
14196+ help
14197+ This enables generic device remapping.
d337f35e 14198+
4bf69007
AM
14199+config VSERVER_PROC_SECURE
14200+ bool "Enable Proc Security"
14201+ depends on PROC_FS
14202+ default y
14203+ help
14204+ This configures ProcFS security to initially hide
14205+ non-process entries for all contexts except the main and
14206+ spectator context (i.e. for all guests), which is a secure
14207+ default.
d337f35e 14208+
4bf69007 14209+ (note: on 1.2x the entries were visible by default)
d337f35e 14210+
4bf69007
AM
14211+choice
14212+ prompt "Persistent Inode Tagging"
14213+ default TAGGING_ID24
14214+ help
14215+ This adds persistent context information to filesystems
14216+ mounted with the tagxid option. Tagging is a requirement
14217+ for per-context disk limits and per-context quota.
d337f35e 14218+
d337f35e 14219+
4bf69007
AM
14220+config TAGGING_NONE
14221+ bool "Disabled"
14222+ help
14223+ do not store per-context information in inodes.
d337f35e 14224+
4bf69007
AM
14225+config TAGGING_UID16
14226+ bool "UID16/GID32"
14227+ help
14228+ reduces UID to 16 bit, but leaves GID at 32 bit.
d337f35e 14229+
4bf69007
AM
14230+config TAGGING_GID16
14231+ bool "UID32/GID16"
14232+ help
14233+ reduces GID to 16 bit, but leaves UID at 32 bit.
d337f35e 14234+
4bf69007
AM
14235+config TAGGING_ID24
14236+ bool "UID24/GID24"
14237+ help
14238+ uses the upper 8bit from UID and GID for XID tagging
14239+ which leaves 24bit for UID/GID each, which should be
14240+ more than sufficient for normal use.
d337f35e 14241+
4bf69007
AM
14242+config TAGGING_INTERN
14243+ bool "UID32/GID32"
14244+ help
14245+ this uses otherwise reserved inode fields in the on
14246+ disk representation, which limits the use to a few
14247+ filesystems (currently ext2 and ext3)
d337f35e 14248+
4bf69007 14249+endchoice
d337f35e 14250+
4bf69007
AM
14251+config TAG_NFSD
14252+ bool "Tag NFSD User Auth and Files"
14253+ default n
14254+ help
14255+ Enable this if you do want the in-kernel NFS
14256+ Server to use the tagging specified above.
14257+ (will require patched clients too)
2380c486 14258+
4bf69007
AM
14259+config VSERVER_PRIVACY
14260+ bool "Honor Privacy Aspects of Guests"
14261+ default n
14262+ help
14263+ When enabled, most context checks will disallow
14264+ access to structures assigned to a specific context,
14265+ like ptys or loop devices.
2380c486 14266+
4bf69007
AM
14267+config VSERVER_CONTEXTS
14268+ int "Maximum number of Contexts (1-65533)" if EMBEDDED
14269+ range 1 65533
14270+ default "768" if 64BIT
14271+ default "256"
14272+ help
14273+ This setting will optimize certain data structures
14274+ and memory allocations according to the expected
14275+ maximum.
2380c486 14276+
4bf69007 14277+ note: this is not a strict upper limit.
2380c486 14278+
4bf69007
AM
14279+config VSERVER_WARN
14280+ bool "VServer Warnings"
14281+ default y
14282+ help
14283+ This enables various runtime warnings, which will
14284+ notify about potential manipulation attempts or
14285+ resource shortage. It is generally considered to
14286+ be a good idea to have that enabled.
2380c486 14287+
4bf69007
AM
14288+config VSERVER_WARN_DEVPTS
14289+ bool "VServer DevPTS Warnings"
14290+ depends on VSERVER_WARN
14291+ default y
14292+ help
14293+ This enables DevPTS related warnings, issued when a
14294+ process inside a context tries to lookup or access
14295+ a dynamic pts from the host or a different context.
d337f35e 14296+
4bf69007
AM
14297+config VSERVER_DEBUG
14298+ bool "VServer Debugging Code"
14299+ default n
14300+ help
14301+ Set this to yes if you want to be able to activate
14302+ debugging output at runtime. It adds a very small
14303+ overhead to all vserver related functions and
14304+ increases the kernel size by about 20k.
d337f35e 14305+
4bf69007
AM
14306+config VSERVER_HISTORY
14307+ bool "VServer History Tracing"
14308+ depends on VSERVER_DEBUG
14309+ default n
14310+ help
14311+ Set this to yes if you want to record the history of
14312+ linux-vserver activities, so they can be replayed in
14313+ the event of a kernel panic or oops.
d337f35e 14314+
4bf69007
AM
14315+config VSERVER_HISTORY_SIZE
14316+ int "Per-CPU History Size (32-65536)"
14317+ depends on VSERVER_HISTORY
14318+ range 32 65536
14319+ default 64
14320+ help
14321+ This allows you to specify the number of entries in
14322+ the per-CPU history buffer.
d337f35e 14323+
4bf69007
AM
14324+config VSERVER_EXTRA_MNT_CHECK
14325+ bool "Extra Checks for Reachability"
14326+ default n
14327+ help
14328+ Set this to yes if you want to do extra checks for
14329+ vfsmount reachability in the proc filesystem code.
14330+ This shouldn't be required on any setup utilizing
14331+ mnt namespaces.
d337f35e 14332+
4bf69007
AM
14333+choice
14334+ prompt "Quotes used in debug and warn messages"
14335+ default QUOTES_ISO8859
d337f35e 14336+
4bf69007
AM
14337+config QUOTES_ISO8859
14338+ bool "Extended ASCII (ISO 8859) angle quotes"
14339+ help
14340+ This uses the extended ASCII characters \xbb
14341+ and \xab for quoting file and process names.
d337f35e 14342+
4bf69007
AM
14343+config QUOTES_UTF8
14344+ bool "UTF-8 angle quotes"
14345+ help
14346+ This uses the the UTF-8 sequences for angle
14347+ quotes to quote file and process names.
d337f35e 14348+
4bf69007
AM
14349+config QUOTES_ASCII
14350+ bool "ASCII single quotes"
14351+ help
14352+ This uses the ASCII single quote character
14353+ (\x27) to quote file and process names.
d337f35e 14354+
4bf69007 14355+endchoice
d337f35e 14356+
4bf69007 14357+endmenu
d337f35e 14358+
d337f35e 14359+
4bf69007
AM
14360+config VSERVER
14361+ bool
14362+ default y
14363+ select NAMESPACES
14364+ select UTS_NS
14365+ select IPC_NS
14366+# select USER_NS
14367+ select SYSVIPC
d337f35e 14368+
4bf69007
AM
14369+config VSERVER_SECURITY
14370+ bool
14371+ depends on SECURITY
14372+ default y
14373+ select SECURITY_CAPABILITIES
d337f35e 14374+
4bf69007
AM
14375+config VSERVER_DISABLED
14376+ bool
14377+ default n
d337f35e 14378+
8de2f54c 14379diff -NurpP --minimal linux-4.4.111/kernel/vserver/Makefile linux-4.4.111-vs2.3.9.5/kernel/vserver/Makefile
f19bd705 14380--- linux-4.4.111/kernel/vserver/Makefile 1970-01-01 00:00:00.000000000 +0000
8de2f54c 14381+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/Makefile 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
14382@@ -0,0 +1,18 @@
14383+#
14384+# Makefile for the Linux vserver routines.
14385+#
d337f35e 14386+
d337f35e 14387+
4bf69007 14388+obj-y += vserver.o
2380c486 14389+
4bf69007
AM
14390+vserver-y := switch.o context.o space.o sched.o network.o inode.o \
14391+ limit.o cvirt.o cacct.o signal.o helper.o init.o \
14392+ dlimit.o tag.o
d337f35e 14393+
4bf69007
AM
14394+vserver-$(CONFIG_INET) += inet.o
14395+vserver-$(CONFIG_PROC_FS) += proc.o
14396+vserver-$(CONFIG_VSERVER_DEBUG) += sysctl.o debug.o
14397+vserver-$(CONFIG_VSERVER_HISTORY) += history.o
14398+vserver-$(CONFIG_VSERVER_MONITOR) += monitor.o
14399+vserver-$(CONFIG_VSERVER_DEVICE) += device.o
d337f35e 14400+
8de2f54c 14401diff -NurpP --minimal linux-4.4.111/kernel/vserver/cacct.c linux-4.4.111-vs2.3.9.5/kernel/vserver/cacct.c
f19bd705 14402--- linux-4.4.111/kernel/vserver/cacct.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 14403+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/cacct.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
14404@@ -0,0 +1,42 @@
14405+/*
14406+ * linux/kernel/vserver/cacct.c
14407+ *
14408+ * Virtual Server: Context Accounting
14409+ *
927ca606 14410+ * Copyright (C) 2006-2007 Herbert P?tzl
4bf69007
AM
14411+ *
14412+ * V0.01 added accounting stats
14413+ *
14414+ */
d337f35e 14415+
4bf69007
AM
14416+#include <linux/types.h>
14417+#include <linux/vs_context.h>
14418+#include <linux/vserver/cacct_cmd.h>
14419+#include <linux/vserver/cacct_int.h>
d337f35e 14420+
4bf69007
AM
14421+#include <asm/errno.h>
14422+#include <asm/uaccess.h>
14423+
14424+
14425+int vc_sock_stat(struct vx_info *vxi, void __user *data)
d337f35e 14426+{
4bf69007
AM
14427+ struct vcmd_sock_stat_v0 vc_data;
14428+ int j, field;
d337f35e 14429+
2380c486
JR
14430+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
14431+ return -EFAULT;
14432+
4bf69007
AM
14433+ field = vc_data.field;
14434+ if ((field < 0) || (field >= VXA_SOCK_SIZE))
14435+ return -EINVAL;
7e46296a 14436+
4bf69007
AM
14437+ for (j = 0; j < 3; j++) {
14438+ vc_data.count[j] = vx_sock_count(&vxi->cacct, field, j);
14439+ vc_data.total[j] = vx_sock_total(&vxi->cacct, field, j);
14440+ }
7e46296a
AM
14441+
14442+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
14443+ return -EFAULT;
14444+ return 0;
14445+}
14446+
8de2f54c 14447diff -NurpP --minimal linux-4.4.111/kernel/vserver/cacct_init.h linux-4.4.111-vs2.3.9.5/kernel/vserver/cacct_init.h
f19bd705 14448--- linux-4.4.111/kernel/vserver/cacct_init.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 14449+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/cacct_init.h 2018-01-09 16:36:34.000000000 +0000
4bf69007 14450@@ -0,0 +1,25 @@
7e46296a
AM
14451+
14452+
4bf69007 14453+static inline void vx_info_init_cacct(struct _vx_cacct *cacct)
265d6dcc 14454+{
4bf69007 14455+ int i, j;
265d6dcc 14456+
265d6dcc 14457+
4bf69007
AM
14458+ for (i = 0; i < VXA_SOCK_SIZE; i++) {
14459+ for (j = 0; j < 3; j++) {
14460+ atomic_long_set(&cacct->sock[i][j].count, 0);
14461+ atomic_long_set(&cacct->sock[i][j].total, 0);
14462+ }
14463+ }
14464+ for (i = 0; i < 8; i++)
14465+ atomic_set(&cacct->slab[i], 0);
14466+ for (i = 0; i < 5; i++)
14467+ for (j = 0; j < 4; j++)
14468+ atomic_set(&cacct->page[i][j], 0);
265d6dcc
JR
14469+}
14470+
4bf69007 14471+static inline void vx_info_exit_cacct(struct _vx_cacct *cacct)
265d6dcc 14472+{
4bf69007 14473+ return;
265d6dcc
JR
14474+}
14475+
8de2f54c 14476diff -NurpP --minimal linux-4.4.111/kernel/vserver/cacct_proc.h linux-4.4.111-vs2.3.9.5/kernel/vserver/cacct_proc.h
f19bd705 14477--- linux-4.4.111/kernel/vserver/cacct_proc.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 14478+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/cacct_proc.h 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
14479@@ -0,0 +1,53 @@
14480+#ifndef _VX_CACCT_PROC_H
14481+#define _VX_CACCT_PROC_H
265d6dcc 14482+
4bf69007 14483+#include <linux/vserver/cacct_int.h>
d337f35e 14484+
d337f35e 14485+
4bf69007
AM
14486+#define VX_SOCKA_TOP \
14487+ "Type\t recv #/bytes\t\t send #/bytes\t\t fail #/bytes\n"
d337f35e 14488+
4bf69007 14489+static inline int vx_info_proc_cacct(struct _vx_cacct *cacct, char *buffer)
d337f35e 14490+{
4bf69007
AM
14491+ int i, j, length = 0;
14492+ static char *type[VXA_SOCK_SIZE] = {
14493+ "UNSPEC", "UNIX", "INET", "INET6", "PACKET", "OTHER"
14494+ };
d337f35e 14495+
4bf69007
AM
14496+ length += sprintf(buffer + length, VX_SOCKA_TOP);
14497+ for (i = 0; i < VXA_SOCK_SIZE; i++) {
14498+ length += sprintf(buffer + length, "%s:", type[i]);
14499+ for (j = 0; j < 3; j++) {
14500+ length += sprintf(buffer + length,
14501+ "\t%10lu/%-10lu",
14502+ vx_sock_count(cacct, i, j),
14503+ vx_sock_total(cacct, i, j));
14504+ }
14505+ buffer[length++] = '\n';
14506+ }
d337f35e 14507+
4bf69007
AM
14508+ length += sprintf(buffer + length, "\n");
14509+ length += sprintf(buffer + length,
14510+ "slab:\t %8u %8u %8u %8u\n",
14511+ atomic_read(&cacct->slab[1]),
14512+ atomic_read(&cacct->slab[4]),
14513+ atomic_read(&cacct->slab[0]),
14514+ atomic_read(&cacct->slab[2]));
d337f35e 14515+
4bf69007
AM
14516+ length += sprintf(buffer + length, "\n");
14517+ for (i = 0; i < 5; i++) {
14518+ length += sprintf(buffer + length,
14519+ "page[%d]: %8u %8u %8u %8u\t %8u %8u %8u %8u\n", i,
14520+ atomic_read(&cacct->page[i][0]),
14521+ atomic_read(&cacct->page[i][1]),
14522+ atomic_read(&cacct->page[i][2]),
14523+ atomic_read(&cacct->page[i][3]),
14524+ atomic_read(&cacct->page[i][4]),
14525+ atomic_read(&cacct->page[i][5]),
14526+ atomic_read(&cacct->page[i][6]),
14527+ atomic_read(&cacct->page[i][7]));
14528+ }
14529+ return length;
14530+}
d337f35e 14531+
4bf69007 14532+#endif /* _VX_CACCT_PROC_H */
8de2f54c 14533diff -NurpP --minimal linux-4.4.111/kernel/vserver/context.c linux-4.4.111-vs2.3.9.5/kernel/vserver/context.c
f19bd705 14534--- linux-4.4.111/kernel/vserver/context.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 14535+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/context.c 2018-01-09 16:36:34.000000000 +0000
4bf69007 14536@@ -0,0 +1,1119 @@
2380c486 14537+/*
4bf69007 14538+ * linux/kernel/vserver/context.c
2380c486 14539+ *
4bf69007 14540+ * Virtual Server: Context Support
2380c486 14541+ *
927ca606 14542+ * Copyright (C) 2003-2011 Herbert P?tzl
2380c486 14543+ *
4bf69007
AM
14544+ * V0.01 context helper
14545+ * V0.02 vx_ctx_kill syscall command
14546+ * V0.03 replaced context_info calls
14547+ * V0.04 redesign of struct (de)alloc
14548+ * V0.05 rlimit basic implementation
14549+ * V0.06 task_xid and info commands
14550+ * V0.07 context flags and caps
14551+ * V0.08 switch to RCU based hash
14552+ * V0.09 revert to non RCU for now
14553+ * V0.10 and back to working RCU hash
14554+ * V0.11 and back to locking again
14555+ * V0.12 referenced context store
14556+ * V0.13 separate per cpu data
14557+ * V0.14 changed vcmds to vxi arg
14558+ * V0.15 added context stat
14559+ * V0.16 have __create claim() the vxi
14560+ * V0.17 removed older and legacy stuff
14561+ * V0.18 added user credentials
14562+ * V0.19 added warn mask
2380c486
JR
14563+ *
14564+ */
d337f35e 14565+
4bf69007 14566+#include <linux/slab.h>
2380c486 14567+#include <linux/types.h>
4bf69007
AM
14568+#include <linux/security.h>
14569+#include <linux/pid_namespace.h>
14570+#include <linux/capability.h>
1e8b8f9b 14571+
4bf69007
AM
14572+#include <linux/vserver/context.h>
14573+#include <linux/vserver/network.h>
14574+#include <linux/vserver/debug.h>
14575+#include <linux/vserver/limit.h>
14576+#include <linux/vserver/limit_int.h>
14577+#include <linux/vserver/space.h>
14578+#include <linux/init_task.h>
14579+#include <linux/fs_struct.h>
14580+#include <linux/cred.h>
1e8b8f9b 14581+
4bf69007
AM
14582+#include <linux/vs_context.h>
14583+#include <linux/vs_limit.h>
14584+#include <linux/vs_pid.h>
14585+#include <linux/vserver/context_cmd.h>
d337f35e 14586+
4bf69007
AM
14587+#include "cvirt_init.h"
14588+#include "cacct_init.h"
14589+#include "limit_init.h"
14590+#include "sched_init.h"
d337f35e 14591+
d337f35e 14592+
4bf69007
AM
14593+atomic_t vx_global_ctotal = ATOMIC_INIT(0);
14594+atomic_t vx_global_cactive = ATOMIC_INIT(0);
d337f35e 14595+
d337f35e 14596+
4bf69007 14597+/* now inactive context structures */
d337f35e 14598+
4bf69007 14599+static struct hlist_head vx_info_inactive = HLIST_HEAD_INIT;
2380c486 14600+
4bf69007 14601+static DEFINE_SPINLOCK(vx_info_inactive_lock);
d337f35e 14602+
2380c486 14603+
4bf69007 14604+/* __alloc_vx_info()
d337f35e 14605+
4bf69007
AM
14606+ * allocate an initialized vx_info struct
14607+ * doesn't make it visible (hash) */
d337f35e 14608+
61333608 14609+static struct vx_info *__alloc_vx_info(vxid_t xid)
4bf69007
AM
14610+{
14611+ struct vx_info *new = NULL;
14612+ int cpu, index;
d337f35e 14613+
4bf69007 14614+ vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d)*", xid);
d337f35e 14615+
4bf69007
AM
14616+ /* would this benefit from a slab cache? */
14617+ new = kmalloc(sizeof(struct vx_info), GFP_KERNEL);
14618+ if (!new)
14619+ return 0;
2380c486 14620+
4bf69007
AM
14621+ memset(new, 0, sizeof(struct vx_info));
14622+#ifdef CONFIG_SMP
14623+ new->ptr_pc = alloc_percpu(struct _vx_info_pc);
14624+ if (!new->ptr_pc)
14625+ goto error;
14626+#endif
14627+ new->vx_id = xid;
14628+ INIT_HLIST_NODE(&new->vx_hlist);
14629+ atomic_set(&new->vx_usecnt, 0);
14630+ atomic_set(&new->vx_tasks, 0);
14631+ new->vx_parent = NULL;
14632+ new->vx_state = 0;
14633+ init_waitqueue_head(&new->vx_wait);
2380c486 14634+
4bf69007
AM
14635+ /* prepare reaper */
14636+ get_task_struct(init_pid_ns.child_reaper);
14637+ new->vx_reaper = init_pid_ns.child_reaper;
14638+ new->vx_badness_bias = 0;
d337f35e 14639+
4bf69007
AM
14640+ /* rest of init goes here */
14641+ vx_info_init_limit(&new->limit);
14642+ vx_info_init_sched(&new->sched);
14643+ vx_info_init_cvirt(&new->cvirt);
14644+ vx_info_init_cacct(&new->cacct);
d337f35e 14645+
4bf69007
AM
14646+ /* per cpu data structures */
14647+ for_each_possible_cpu(cpu) {
14648+ vx_info_init_sched_pc(
14649+ &vx_per_cpu(new, sched_pc, cpu), cpu);
14650+ vx_info_init_cvirt_pc(
14651+ &vx_per_cpu(new, cvirt_pc, cpu), cpu);
14652+ }
d337f35e 14653+
4bf69007
AM
14654+ new->vx_flags = VXF_INIT_SET;
14655+ new->vx_bcaps = CAP_FULL_SET; // maybe ~CAP_SETPCAP
14656+ new->vx_ccaps = 0;
14657+ new->vx_umask = 0;
14658+ new->vx_wmask = 0;
d337f35e 14659+
4bf69007
AM
14660+ new->reboot_cmd = 0;
14661+ new->exit_code = 0;
d337f35e 14662+
4bf69007
AM
14663+ // preconfig spaces
14664+ for (index = 0; index < VX_SPACES; index++) {
14665+ struct _vx_space *space = &new->space[index];
d337f35e 14666+
4bf69007
AM
14667+ // filesystem
14668+ spin_lock(&init_fs.lock);
14669+ init_fs.users++;
14670+ spin_unlock(&init_fs.lock);
14671+ space->vx_fs = &init_fs;
2380c486 14672+
4bf69007
AM
14673+ /* FIXME: do we want defaults? */
14674+ // space->vx_real_cred = 0;
14675+ // space->vx_cred = 0;
2380c486 14676+ }
4bf69007
AM
14677+
14678+
14679+ vxdprintk(VXD_CBIT(xid, 0),
14680+ "alloc_vx_info(%d) = %p", xid, new);
14681+ vxh_alloc_vx_info(new);
14682+ atomic_inc(&vx_global_ctotal);
14683+ return new;
14684+#ifdef CONFIG_SMP
14685+error:
14686+ kfree(new);
14687+ return 0;
14688+#endif
d337f35e
JR
14689+}
14690+
4bf69007 14691+/* __dealloc_vx_info()
d337f35e 14692+
4bf69007 14693+ * final disposal of vx_info */
d337f35e 14694+
4bf69007 14695+static void __dealloc_vx_info(struct vx_info *vxi)
d337f35e 14696+{
4bf69007
AM
14697+#ifdef CONFIG_VSERVER_WARN
14698+ struct vx_info_save vxis;
14699+ int cpu;
14700+#endif
14701+ vxdprintk(VXD_CBIT(xid, 0),
14702+ "dealloc_vx_info(%p)", vxi);
14703+ vxh_dealloc_vx_info(vxi);
d337f35e 14704+
4bf69007
AM
14705+#ifdef CONFIG_VSERVER_WARN
14706+ enter_vx_info(vxi, &vxis);
14707+ vx_info_exit_limit(&vxi->limit);
14708+ vx_info_exit_sched(&vxi->sched);
14709+ vx_info_exit_cvirt(&vxi->cvirt);
14710+ vx_info_exit_cacct(&vxi->cacct);
d337f35e 14711+
4bf69007
AM
14712+ for_each_possible_cpu(cpu) {
14713+ vx_info_exit_sched_pc(
14714+ &vx_per_cpu(vxi, sched_pc, cpu), cpu);
14715+ vx_info_exit_cvirt_pc(
14716+ &vx_per_cpu(vxi, cvirt_pc, cpu), cpu);
14717+ }
14718+ leave_vx_info(&vxis);
14719+#endif
d337f35e 14720+
4bf69007
AM
14721+ vxi->vx_id = -1;
14722+ vxi->vx_state |= VXS_RELEASED;
d337f35e 14723+
4bf69007
AM
14724+#ifdef CONFIG_SMP
14725+ free_percpu(vxi->ptr_pc);
14726+#endif
14727+ kfree(vxi);
14728+ atomic_dec(&vx_global_ctotal);
d337f35e
JR
14729+}
14730+
4bf69007 14731+static void __shutdown_vx_info(struct vx_info *vxi)
d337f35e 14732+{
4bf69007
AM
14733+ struct nsproxy *nsproxy;
14734+ struct fs_struct *fs;
14735+ struct cred *cred;
14736+ int index, kill;
d337f35e 14737+
4bf69007 14738+ might_sleep();
d337f35e 14739+
4bf69007
AM
14740+ vxi->vx_state |= VXS_SHUTDOWN;
14741+ vs_state_change(vxi, VSC_SHUTDOWN);
d337f35e 14742+
4bf69007
AM
14743+ for (index = 0; index < VX_SPACES; index++) {
14744+ struct _vx_space *space = &vxi->space[index];
d337f35e 14745+
4bf69007
AM
14746+ nsproxy = xchg(&space->vx_nsproxy, NULL);
14747+ if (nsproxy)
14748+ put_nsproxy(nsproxy);
2380c486 14749+
4bf69007
AM
14750+ fs = xchg(&space->vx_fs, NULL);
14751+ spin_lock(&fs->lock);
14752+ kill = !--fs->users;
14753+ spin_unlock(&fs->lock);
14754+ if (kill)
14755+ free_fs_struct(fs);
d337f35e 14756+
4bf69007
AM
14757+ cred = (struct cred *)xchg(&space->vx_cred, NULL);
14758+ if (cred)
14759+ abort_creds(cred);
14760+ }
d337f35e
JR
14761+}
14762+
4bf69007 14763+/* exported stuff */
d337f35e 14764+
4bf69007 14765+void free_vx_info(struct vx_info *vxi)
d337f35e 14766+{
4bf69007
AM
14767+ unsigned long flags;
14768+ unsigned index;
d337f35e 14769+
4bf69007
AM
14770+ /* check for reference counts first */
14771+ BUG_ON(atomic_read(&vxi->vx_usecnt));
14772+ BUG_ON(atomic_read(&vxi->vx_tasks));
2380c486 14773+
4bf69007
AM
14774+ /* context must not be hashed */
14775+ BUG_ON(vx_info_state(vxi, VXS_HASHED));
d337f35e 14776+
4bf69007
AM
14777+ /* context shutdown is mandatory */
14778+ BUG_ON(!vx_info_state(vxi, VXS_SHUTDOWN));
d337f35e 14779+
4bf69007
AM
14780+ /* spaces check */
14781+ for (index = 0; index < VX_SPACES; index++) {
14782+ struct _vx_space *space = &vxi->space[index];
d337f35e 14783+
4bf69007
AM
14784+ BUG_ON(space->vx_nsproxy);
14785+ BUG_ON(space->vx_fs);
14786+ // BUG_ON(space->vx_real_cred);
14787+ // BUG_ON(space->vx_cred);
14788+ }
d337f35e 14789+
4bf69007
AM
14790+ spin_lock_irqsave(&vx_info_inactive_lock, flags);
14791+ hlist_del(&vxi->vx_hlist);
14792+ spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
d337f35e 14793+
4bf69007
AM
14794+ __dealloc_vx_info(vxi);
14795+}
eab5a9a6 14796+
d337f35e 14797+
4bf69007 14798+/* hash table for vx_info hash */
93de0823 14799+
4bf69007 14800+#define VX_HASH_SIZE 13
d337f35e 14801+
4bf69007
AM
14802+static struct hlist_head vx_info_hash[VX_HASH_SIZE] =
14803+ { [0 ... VX_HASH_SIZE-1] = HLIST_HEAD_INIT };
d337f35e 14804+
4bf69007 14805+static DEFINE_SPINLOCK(vx_info_hash_lock);
d337f35e 14806+
93de0823 14807+
61333608 14808+static inline unsigned int __hashval(vxid_t xid)
4bf69007
AM
14809+{
14810+ return (xid % VX_HASH_SIZE);
d337f35e
JR
14811+}
14812+
14813+
d337f35e 14814+
4bf69007 14815+/* __hash_vx_info()
d337f35e 14816+
4bf69007
AM
14817+ * add the vxi to the global hash table
14818+ * requires the hash_lock to be held */
d337f35e 14819+
4bf69007 14820+static inline void __hash_vx_info(struct vx_info *vxi)
d337f35e 14821+{
4bf69007 14822+ struct hlist_head *head;
d337f35e 14823+
4bf69007
AM
14824+ vxd_assert_lock(&vx_info_hash_lock);
14825+ vxdprintk(VXD_CBIT(xid, 4),
14826+ "__hash_vx_info: %p[#%d]", vxi, vxi->vx_id);
14827+ vxh_hash_vx_info(vxi);
d337f35e 14828+
4bf69007
AM
14829+ /* context must not be hashed */
14830+ BUG_ON(vx_info_state(vxi, VXS_HASHED));
d337f35e 14831+
4bf69007
AM
14832+ vxi->vx_state |= VXS_HASHED;
14833+ head = &vx_info_hash[__hashval(vxi->vx_id)];
14834+ hlist_add_head(&vxi->vx_hlist, head);
14835+ atomic_inc(&vx_global_cactive);
2380c486 14836+}
d337f35e 14837+
4bf69007 14838+/* __unhash_vx_info()
d337f35e 14839+
4bf69007
AM
14840+ * remove the vxi from the global hash table
14841+ * requires the hash_lock to be held */
d337f35e 14842+
4bf69007 14843+static inline void __unhash_vx_info(struct vx_info *vxi)
d337f35e 14844+{
4bf69007
AM
14845+ unsigned long flags;
14846+
14847+ vxd_assert_lock(&vx_info_hash_lock);
14848+ vxdprintk(VXD_CBIT(xid, 4),
14849+ "__unhash_vx_info: %p[#%d.%d.%d]", vxi, vxi->vx_id,
14850+ atomic_read(&vxi->vx_usecnt), atomic_read(&vxi->vx_tasks));
14851+ vxh_unhash_vx_info(vxi);
14852+
14853+ /* context must be hashed */
14854+ BUG_ON(!vx_info_state(vxi, VXS_HASHED));
14855+ /* but without tasks */
14856+ BUG_ON(atomic_read(&vxi->vx_tasks));
14857+
14858+ vxi->vx_state &= ~VXS_HASHED;
14859+ hlist_del_init(&vxi->vx_hlist);
14860+ spin_lock_irqsave(&vx_info_inactive_lock, flags);
14861+ hlist_add_head(&vxi->vx_hlist, &vx_info_inactive);
14862+ spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
14863+ atomic_dec(&vx_global_cactive);
2380c486 14864+}
d337f35e 14865+
d337f35e 14866+
4bf69007 14867+/* __lookup_vx_info()
d337f35e 14868+
4bf69007
AM
14869+ * requires the hash_lock to be held
14870+ * doesn't increment the vx_refcnt */
2380c486 14871+
61333608 14872+static inline struct vx_info *__lookup_vx_info(vxid_t xid)
d337f35e 14873+{
4bf69007
AM
14874+ struct hlist_head *head = &vx_info_hash[__hashval(xid)];
14875+ struct hlist_node *pos;
14876+ struct vx_info *vxi;
d337f35e 14877+
4bf69007
AM
14878+ vxd_assert_lock(&vx_info_hash_lock);
14879+ hlist_for_each(pos, head) {
14880+ vxi = hlist_entry(pos, struct vx_info, vx_hlist);
d337f35e 14881+
4bf69007
AM
14882+ if (vxi->vx_id == xid)
14883+ goto found;
14884+ }
14885+ vxi = NULL;
14886+found:
14887+ vxdprintk(VXD_CBIT(xid, 0),
14888+ "__lookup_vx_info(#%u): %p[#%u]",
14889+ xid, vxi, vxi ? vxi->vx_id : 0);
14890+ vxh_lookup_vx_info(vxi, xid);
14891+ return vxi;
14892+}
d337f35e 14893+
d337f35e 14894+
4bf69007 14895+/* __create_vx_info()
d337f35e 14896+
4bf69007
AM
14897+ * create the requested context
14898+ * get(), claim() and hash it */
2380c486 14899+
4bf69007
AM
14900+static struct vx_info *__create_vx_info(int id)
14901+{
14902+ struct vx_info *new, *vxi = NULL;
2380c486 14903+
4bf69007 14904+ vxdprintk(VXD_CBIT(xid, 1), "create_vx_info(%d)*", id);
d337f35e 14905+
4bf69007
AM
14906+ if (!(new = __alloc_vx_info(id)))
14907+ return ERR_PTR(-ENOMEM);
d337f35e 14908+
4bf69007
AM
14909+ /* required to make dynamic xids unique */
14910+ spin_lock(&vx_info_hash_lock);
d337f35e 14911+
4bf69007
AM
14912+ /* static context requested */
14913+ if ((vxi = __lookup_vx_info(id))) {
14914+ vxdprintk(VXD_CBIT(xid, 0),
14915+ "create_vx_info(%d) = %p (already there)", id, vxi);
14916+ if (vx_info_flags(vxi, VXF_STATE_SETUP, 0))
14917+ vxi = ERR_PTR(-EBUSY);
14918+ else
14919+ vxi = ERR_PTR(-EEXIST);
14920+ goto out_unlock;
14921+ }
14922+ /* new context */
14923+ vxdprintk(VXD_CBIT(xid, 0),
14924+ "create_vx_info(%d) = %p (new)", id, new);
14925+ claim_vx_info(new, NULL);
14926+ __hash_vx_info(get_vx_info(new));
14927+ vxi = new, new = NULL;
d337f35e 14928+
4bf69007
AM
14929+out_unlock:
14930+ spin_unlock(&vx_info_hash_lock);
14931+ vxh_create_vx_info(IS_ERR(vxi) ? NULL : vxi, id);
14932+ if (new)
14933+ __dealloc_vx_info(new);
14934+ return vxi;
14935+}
d337f35e 14936+
d337f35e 14937+
4bf69007 14938+/* exported stuff */
d337f35e 14939+
d337f35e 14940+
4bf69007 14941+void unhash_vx_info(struct vx_info *vxi)
d337f35e 14942+{
4bf69007
AM
14943+ spin_lock(&vx_info_hash_lock);
14944+ __unhash_vx_info(vxi);
14945+ spin_unlock(&vx_info_hash_lock);
14946+ __shutdown_vx_info(vxi);
14947+ __wakeup_vx_info(vxi);
2380c486 14948+}
d337f35e 14949+
2380c486 14950+
4bf69007 14951+/* lookup_vx_info()
2380c486 14952+
4bf69007
AM
14953+ * search for a vx_info and get() it
14954+ * negative id means current */
2380c486 14955+
4bf69007 14956+struct vx_info *lookup_vx_info(int id)
2380c486 14957+{
4bf69007
AM
14958+ struct vx_info *vxi = NULL;
14959+
14960+ if (id < 0) {
14961+ vxi = get_vx_info(current_vx_info());
14962+ } else if (id > 1) {
14963+ spin_lock(&vx_info_hash_lock);
14964+ vxi = get_vx_info(__lookup_vx_info(id));
14965+ spin_unlock(&vx_info_hash_lock);
2380c486 14966+ }
4bf69007 14967+ return vxi;
d337f35e
JR
14968+}
14969+
4bf69007 14970+/* xid_is_hashed()
d337f35e 14971+
4bf69007 14972+ * verify that xid is still hashed */
d337f35e 14973+
61333608 14974+int xid_is_hashed(vxid_t xid)
4bf69007
AM
14975+{
14976+ int hashed;
d337f35e 14977+
4bf69007
AM
14978+ spin_lock(&vx_info_hash_lock);
14979+ hashed = (__lookup_vx_info(xid) != NULL);
14980+ spin_unlock(&vx_info_hash_lock);
14981+ return hashed;
14982+}
d337f35e 14983+
4bf69007 14984+#ifdef CONFIG_PROC_FS
d337f35e 14985+
4bf69007 14986+/* get_xid_list()
d337f35e 14987+
4bf69007
AM
14988+ * get a subset of hashed xids for proc
14989+ * assumes size is at least one */
d337f35e 14990+
4bf69007
AM
14991+int get_xid_list(int index, unsigned int *xids, int size)
14992+{
14993+ int hindex, nr_xids = 0;
d337f35e 14994+
4bf69007
AM
14995+ /* only show current and children */
14996+ if (!vx_check(0, VS_ADMIN | VS_WATCH)) {
14997+ if (index > 0)
14998+ return 0;
14999+ xids[nr_xids] = vx_current_xid();
15000+ return 1;
15001+ }
d337f35e 15002+
4bf69007
AM
15003+ for (hindex = 0; hindex < VX_HASH_SIZE; hindex++) {
15004+ struct hlist_head *head = &vx_info_hash[hindex];
15005+ struct hlist_node *pos;
d337f35e 15006+
4bf69007
AM
15007+ spin_lock(&vx_info_hash_lock);
15008+ hlist_for_each(pos, head) {
15009+ struct vx_info *vxi;
d337f35e 15010+
4bf69007
AM
15011+ if (--index > 0)
15012+ continue;
d337f35e 15013+
4bf69007
AM
15014+ vxi = hlist_entry(pos, struct vx_info, vx_hlist);
15015+ xids[nr_xids] = vxi->vx_id;
15016+ if (++nr_xids >= size) {
15017+ spin_unlock(&vx_info_hash_lock);
15018+ goto out;
15019+ }
15020+ }
15021+ /* keep the lock time short */
15022+ spin_unlock(&vx_info_hash_lock);
15023+ }
15024+out:
15025+ return nr_xids;
15026+}
15027+#endif
d337f35e 15028+
4bf69007 15029+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 15030+
4bf69007 15031+void dump_vx_info_inactive(int level)
d337f35e 15032+{
4bf69007 15033+ struct hlist_node *entry, *next;
d337f35e 15034+
4bf69007
AM
15035+ hlist_for_each_safe(entry, next, &vx_info_inactive) {
15036+ struct vx_info *vxi =
15037+ list_entry(entry, struct vx_info, vx_hlist);
d337f35e 15038+
4bf69007
AM
15039+ dump_vx_info(vxi, level);
15040+ }
d337f35e
JR
15041+}
15042+
4bf69007 15043+#endif
d337f35e 15044+
4bf69007
AM
15045+#if 0
15046+int vx_migrate_user(struct task_struct *p, struct vx_info *vxi)
d337f35e 15047+{
4bf69007 15048+ struct user_struct *new_user, *old_user;
d337f35e 15049+
4bf69007
AM
15050+ if (!p || !vxi)
15051+ BUG();
d337f35e 15052+
4bf69007
AM
15053+ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
15054+ return -EACCES;
d337f35e 15055+
4bf69007
AM
15056+ new_user = alloc_uid(vxi->vx_id, p->uid);
15057+ if (!new_user)
15058+ return -ENOMEM;
d337f35e 15059+
4bf69007
AM
15060+ old_user = p->user;
15061+ if (new_user != old_user) {
15062+ atomic_inc(&new_user->processes);
15063+ atomic_dec(&old_user->processes);
15064+ p->user = new_user;
d337f35e 15065+ }
4bf69007
AM
15066+ free_uid(old_user);
15067+ return 0;
d337f35e 15068+}
4bf69007 15069+#endif
d337f35e 15070+
4bf69007
AM
15071+#if 0
15072+void vx_mask_cap_bset(struct vx_info *vxi, struct task_struct *p)
d337f35e 15073+{
4bf69007
AM
15074+ // p->cap_effective &= vxi->vx_cap_bset;
15075+ p->cap_effective =
15076+ cap_intersect(p->cap_effective, vxi->cap_bset);
15077+ // p->cap_inheritable &= vxi->vx_cap_bset;
15078+ p->cap_inheritable =
15079+ cap_intersect(p->cap_inheritable, vxi->cap_bset);
15080+ // p->cap_permitted &= vxi->vx_cap_bset;
15081+ p->cap_permitted =
15082+ cap_intersect(p->cap_permitted, vxi->cap_bset);
15083+}
15084+#endif
d337f35e
JR
15085+
15086+
4bf69007
AM
15087+#include <linux/file.h>
15088+#include <linux/fdtable.h>
d337f35e 15089+
4bf69007
AM
15090+static int vx_openfd_task(struct task_struct *tsk)
15091+{
15092+ struct files_struct *files = tsk->files;
15093+ struct fdtable *fdt;
15094+ const unsigned long *bptr;
15095+ int count, total;
d337f35e 15096+
4bf69007
AM
15097+ /* no rcu_read_lock() because of spin_lock() */
15098+ spin_lock(&files->file_lock);
15099+ fdt = files_fdtable(files);
15100+ bptr = fdt->open_fds;
15101+ count = fdt->max_fds / (sizeof(unsigned long) * 8);
15102+ for (total = 0; count > 0; count--) {
15103+ if (*bptr)
15104+ total += hweight_long(*bptr);
15105+ bptr++;
15106+ }
15107+ spin_unlock(&files->file_lock);
15108+ return total;
d337f35e
JR
15109+}
15110+
d337f35e 15111+
4bf69007
AM
15112+/* for *space compatibility */
15113+
15114+asmlinkage long sys_unshare(unsigned long);
15115+
15116+/*
15117+ * migrate task to new context
15118+ * gets vxi, puts old_vxi on change
15119+ * optionally unshares namespaces (hack)
2380c486 15120+ */
4bf69007
AM
15121+
15122+int vx_migrate_task(struct task_struct *p, struct vx_info *vxi, int unshare)
2380c486 15123+{
4bf69007
AM
15124+ struct vx_info *old_vxi;
15125+ int ret = 0;
d337f35e 15126+
4bf69007
AM
15127+ if (!p || !vxi)
15128+ BUG();
d337f35e 15129+
4bf69007
AM
15130+ vxdprintk(VXD_CBIT(xid, 5),
15131+ "vx_migrate_task(%p,%p[#%d.%d])", p, vxi,
15132+ vxi->vx_id, atomic_read(&vxi->vx_usecnt));
d337f35e 15133+
4bf69007
AM
15134+ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0) &&
15135+ !vx_info_flags(vxi, VXF_STATE_SETUP, 0))
15136+ return -EACCES;
2380c486 15137+
4bf69007
AM
15138+ if (vx_info_state(vxi, VXS_SHUTDOWN))
15139+ return -EFAULT;
d337f35e 15140+
4bf69007
AM
15141+ old_vxi = task_get_vx_info(p);
15142+ if (old_vxi == vxi)
15143+ goto out;
d337f35e 15144+
4bf69007
AM
15145+// if (!(ret = vx_migrate_user(p, vxi))) {
15146+ {
15147+ int openfd;
d337f35e 15148+
4bf69007
AM
15149+ task_lock(p);
15150+ openfd = vx_openfd_task(p);
15151+
15152+ if (old_vxi) {
15153+ atomic_dec(&old_vxi->cvirt.nr_threads);
15154+ atomic_dec(&old_vxi->cvirt.nr_running);
15155+ __rlim_dec(&old_vxi->limit, RLIMIT_NPROC);
15156+ /* FIXME: what about the struct files here? */
15157+ __rlim_sub(&old_vxi->limit, VLIMIT_OPENFD, openfd);
15158+ /* account for the executable */
15159+ __rlim_dec(&old_vxi->limit, VLIMIT_DENTRY);
2380c486 15160+ }
4bf69007
AM
15161+ atomic_inc(&vxi->cvirt.nr_threads);
15162+ atomic_inc(&vxi->cvirt.nr_running);
15163+ __rlim_inc(&vxi->limit, RLIMIT_NPROC);
15164+ /* FIXME: what about the struct files here? */
15165+ __rlim_add(&vxi->limit, VLIMIT_OPENFD, openfd);
15166+ /* account for the executable */
15167+ __rlim_inc(&vxi->limit, VLIMIT_DENTRY);
2380c486 15168+
4bf69007
AM
15169+ if (old_vxi) {
15170+ release_vx_info(old_vxi, p);
15171+ clr_vx_info(&p->vx_info);
15172+ }
15173+ claim_vx_info(vxi, p);
15174+ set_vx_info(&p->vx_info, vxi);
15175+ p->xid = vxi->vx_id;
d337f35e 15176+
4bf69007
AM
15177+ vxdprintk(VXD_CBIT(xid, 5),
15178+ "moved task %p into vxi:%p[#%d]",
15179+ p, vxi, vxi->vx_id);
d337f35e 15180+
4bf69007
AM
15181+ // vx_mask_cap_bset(vxi, p);
15182+ task_unlock(p);
d337f35e 15183+
4bf69007
AM
15184+ /* hack for *spaces to provide compatibility */
15185+ if (unshare) {
15186+ struct nsproxy *old_nsp, *new_nsp;
d337f35e 15187+
4bf69007
AM
15188+ ret = unshare_nsproxy_namespaces(
15189+ CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER,
b00e13aa 15190+ &new_nsp, NULL, NULL);
4bf69007
AM
15191+ if (ret)
15192+ goto out;
d337f35e 15193+
4bf69007
AM
15194+ old_nsp = xchg(&p->nsproxy, new_nsp);
15195+ vx_set_space(vxi,
15196+ CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER, 0);
15197+ put_nsproxy(old_nsp);
15198+ }
15199+ }
15200+out:
15201+ put_vx_info(old_vxi);
2380c486
JR
15202+ return ret;
15203+}
d337f35e 15204+
4bf69007 15205+int vx_set_reaper(struct vx_info *vxi, struct task_struct *p)
d337f35e 15206+{
4bf69007
AM
15207+ struct task_struct *old_reaper;
15208+ struct vx_info *reaper_vxi;
d337f35e 15209+
4bf69007
AM
15210+ if (!vxi)
15211+ return -EINVAL;
d337f35e 15212+
4bf69007
AM
15213+ vxdprintk(VXD_CBIT(xid, 6),
15214+ "vx_set_reaper(%p[#%d],%p[#%d,%d])",
15215+ vxi, vxi->vx_id, p, p->xid, p->pid);
d337f35e 15216+
4bf69007
AM
15217+ old_reaper = vxi->vx_reaper;
15218+ if (old_reaper == p)
15219+ return 0;
d337f35e 15220+
4bf69007
AM
15221+ reaper_vxi = task_get_vx_info(p);
15222+ if (reaper_vxi && reaper_vxi != vxi) {
15223+ vxwprintk(1,
15224+ "Unsuitable reaper [" VS_Q("%s") ",%u:#%u] "
15225+ "for [xid #%u]",
15226+ p->comm, p->pid, p->xid, vx_current_xid());
2380c486
JR
15227+ goto out;
15228+ }
4bf69007
AM
15229+
15230+ /* set new child reaper */
15231+ get_task_struct(p);
15232+ vxi->vx_reaper = p;
15233+ put_task_struct(old_reaper);
2380c486 15234+out:
4bf69007
AM
15235+ put_vx_info(reaper_vxi);
15236+ return 0;
2380c486 15237+}
d337f35e 15238+
4bf69007 15239+int vx_set_init(struct vx_info *vxi, struct task_struct *p)
d337f35e 15240+{
4bf69007
AM
15241+ if (!vxi)
15242+ return -EINVAL;
d337f35e 15243+
4bf69007
AM
15244+ vxdprintk(VXD_CBIT(xid, 6),
15245+ "vx_set_init(%p[#%d],%p[#%d,%d,%d])",
15246+ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
d337f35e 15247+
4bf69007
AM
15248+ vxi->vx_flags &= ~VXF_STATE_INIT;
15249+ // vxi->vx_initpid = p->tgid;
15250+ vxi->vx_initpid = p->pid;
2380c486 15251+ return 0;
d337f35e
JR
15252+}
15253+
4bf69007 15254+void vx_exit_init(struct vx_info *vxi, struct task_struct *p, int code)
d337f35e 15255+{
4bf69007
AM
15256+ vxdprintk(VXD_CBIT(xid, 6),
15257+ "vx_exit_init(%p[#%d],%p[#%d,%d,%d])",
15258+ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
2380c486 15259+
4bf69007
AM
15260+ vxi->exit_code = code;
15261+ vxi->vx_initpid = 0;
d337f35e
JR
15262+}
15263+
2380c486 15264+
4bf69007 15265+void vx_set_persistent(struct vx_info *vxi)
d337f35e 15266+{
4bf69007
AM
15267+ vxdprintk(VXD_CBIT(xid, 6),
15268+ "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id);
2380c486 15269+
4bf69007
AM
15270+ get_vx_info(vxi);
15271+ claim_vx_info(vxi, NULL);
d337f35e
JR
15272+}
15273+
4bf69007 15274+void vx_clear_persistent(struct vx_info *vxi)
2380c486 15275+{
4bf69007
AM
15276+ vxdprintk(VXD_CBIT(xid, 6),
15277+ "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id);
d337f35e 15278+
4bf69007
AM
15279+ release_vx_info(vxi, NULL);
15280+ put_vx_info(vxi);
2380c486 15281+}
d337f35e 15282+
4bf69007 15283+void vx_update_persistent(struct vx_info *vxi)
d337f35e 15284+{
4bf69007
AM
15285+ if (vx_info_flags(vxi, VXF_PERSISTENT, 0))
15286+ vx_set_persistent(vxi);
2380c486 15287+ else
4bf69007 15288+ vx_clear_persistent(vxi);
2380c486 15289+}
d337f35e 15290+
d337f35e 15291+
4bf69007
AM
15292+/* task must be current or locked */
15293+
15294+void exit_vx_info(struct task_struct *p, int code)
2380c486 15295+{
4bf69007 15296+ struct vx_info *vxi = p->vx_info;
d337f35e 15297+
4bf69007
AM
15298+ if (vxi) {
15299+ atomic_dec(&vxi->cvirt.nr_threads);
15300+ vx_nproc_dec(p);
d337f35e 15301+
4bf69007
AM
15302+ vxi->exit_code = code;
15303+ release_vx_info(vxi, p);
15304+ }
2380c486 15305+}
d337f35e 15306+
4bf69007 15307+void exit_vx_info_early(struct task_struct *p, int code)
2380c486 15308+{
4bf69007 15309+ struct vx_info *vxi = p->vx_info;
d337f35e 15310+
4bf69007
AM
15311+ if (vxi) {
15312+ if (vxi->vx_initpid == p->pid)
15313+ vx_exit_init(vxi, p, code);
15314+ if (vxi->vx_reaper == p)
15315+ vx_set_reaper(vxi, init_pid_ns.child_reaper);
15316+ }
d337f35e
JR
15317+}
15318+
15319+
4bf69007 15320+/* vserver syscall commands below here */
d337f35e 15321+
4bf69007 15322+/* taks xid and vx_info functions */
d337f35e 15323+
4bf69007 15324+#include <asm/uaccess.h>
d337f35e 15325+
d337f35e 15326+
4bf69007 15327+int vc_task_xid(uint32_t id)
d337f35e 15328+{
61333608 15329+ vxid_t xid;
d337f35e 15330+
4bf69007
AM
15331+ if (id) {
15332+ struct task_struct *tsk;
d337f35e 15333+
4bf69007
AM
15334+ rcu_read_lock();
15335+ tsk = find_task_by_real_pid(id);
15336+ xid = (tsk) ? tsk->xid : -ESRCH;
15337+ rcu_read_unlock();
15338+ } else
15339+ xid = vx_current_xid();
15340+ return xid;
d337f35e
JR
15341+}
15342+
d337f35e 15343+
4bf69007
AM
15344+int vc_vx_info(struct vx_info *vxi, void __user *data)
15345+{
15346+ struct vcmd_vx_info_v0 vc_data;
d337f35e 15347+
4bf69007
AM
15348+ vc_data.xid = vxi->vx_id;
15349+ vc_data.initpid = vxi->vx_initpid;
d337f35e 15350+
4bf69007
AM
15351+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15352+ return -EFAULT;
15353+ return 0;
15354+}
d337f35e 15355+
d337f35e 15356+
4bf69007 15357+int vc_ctx_stat(struct vx_info *vxi, void __user *data)
d337f35e 15358+{
4bf69007 15359+ struct vcmd_ctx_stat_v0 vc_data;
d337f35e 15360+
4bf69007
AM
15361+ vc_data.usecnt = atomic_read(&vxi->vx_usecnt);
15362+ vc_data.tasks = atomic_read(&vxi->vx_tasks);
d337f35e 15363+
4bf69007
AM
15364+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15365+ return -EFAULT;
15366+ return 0;
d337f35e
JR
15367+}
15368+
d337f35e 15369+
4bf69007 15370+/* context functions */
d337f35e 15371+
4bf69007 15372+int vc_ctx_create(uint32_t xid, void __user *data)
d337f35e 15373+{
4bf69007
AM
15374+ struct vcmd_ctx_create vc_data = { .flagword = VXF_INIT_SET };
15375+ struct vx_info *new_vxi;
15376+ int ret;
d337f35e 15377+
4bf69007
AM
15378+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
15379+ return -EFAULT;
d337f35e 15380+
4bf69007
AM
15381+ if ((xid > MAX_S_CONTEXT) || (xid < 2))
15382+ return -EINVAL;
d337f35e 15383+
4bf69007
AM
15384+ new_vxi = __create_vx_info(xid);
15385+ if (IS_ERR(new_vxi))
15386+ return PTR_ERR(new_vxi);
d337f35e 15387+
4bf69007
AM
15388+ /* initial flags */
15389+ new_vxi->vx_flags = vc_data.flagword;
d337f35e 15390+
4bf69007
AM
15391+ ret = -ENOEXEC;
15392+ if (vs_state_change(new_vxi, VSC_STARTUP))
15393+ goto out;
d337f35e 15394+
4bf69007
AM
15395+ ret = vx_migrate_task(current, new_vxi, (!data));
15396+ if (ret)
15397+ goto out;
d337f35e 15398+
4bf69007
AM
15399+ /* return context id on success */
15400+ ret = new_vxi->vx_id;
d337f35e 15401+
4bf69007
AM
15402+ /* get a reference for persistent contexts */
15403+ if ((vc_data.flagword & VXF_PERSISTENT))
15404+ vx_set_persistent(new_vxi);
15405+out:
15406+ release_vx_info(new_vxi, NULL);
15407+ put_vx_info(new_vxi);
15408+ return ret;
15409+}
d337f35e
JR
15410+
15411+
4bf69007 15412+int vc_ctx_migrate(struct vx_info *vxi, void __user *data)
d337f35e 15413+{
4bf69007
AM
15414+ struct vcmd_ctx_migrate vc_data = { .flagword = 0 };
15415+ int ret;
d337f35e 15416+
4bf69007
AM
15417+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
15418+ return -EFAULT;
d337f35e 15419+
4bf69007
AM
15420+ ret = vx_migrate_task(current, vxi, 0);
15421+ if (ret)
15422+ return ret;
15423+ if (vc_data.flagword & VXM_SET_INIT)
15424+ ret = vx_set_init(vxi, current);
15425+ if (ret)
15426+ return ret;
15427+ if (vc_data.flagword & VXM_SET_REAPER)
15428+ ret = vx_set_reaper(vxi, current);
15429+ return ret;
15430+}
d337f35e 15431+
d337f35e 15432+
4bf69007 15433+int vc_get_cflags(struct vx_info *vxi, void __user *data)
d337f35e 15434+{
4bf69007 15435+ struct vcmd_ctx_flags_v0 vc_data;
d337f35e 15436+
4bf69007 15437+ vc_data.flagword = vxi->vx_flags;
d337f35e 15438+
4bf69007
AM
15439+ /* special STATE flag handling */
15440+ vc_data.mask = vs_mask_flags(~0ULL, vxi->vx_flags, VXF_ONE_TIME);
d337f35e 15441+
4bf69007
AM
15442+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15443+ return -EFAULT;
15444+ return 0;
d337f35e
JR
15445+}
15446+
4bf69007
AM
15447+int vc_set_cflags(struct vx_info *vxi, void __user *data)
15448+{
15449+ struct vcmd_ctx_flags_v0 vc_data;
15450+ uint64_t mask, trigger;
d337f35e 15451+
4bf69007
AM
15452+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15453+ return -EFAULT;
d337f35e 15454+
4bf69007
AM
15455+ /* special STATE flag handling */
15456+ mask = vs_mask_mask(vc_data.mask, vxi->vx_flags, VXF_ONE_TIME);
15457+ trigger = (mask & vxi->vx_flags) ^ (mask & vc_data.flagword);
d337f35e 15458+
4bf69007
AM
15459+ if (vxi == current_vx_info()) {
15460+ /* if (trigger & VXF_STATE_SETUP)
15461+ vx_mask_cap_bset(vxi, current); */
15462+ if (trigger & VXF_STATE_INIT) {
15463+ int ret;
d337f35e 15464+
4bf69007
AM
15465+ ret = vx_set_init(vxi, current);
15466+ if (ret)
15467+ return ret;
15468+ ret = vx_set_reaper(vxi, current);
15469+ if (ret)
15470+ return ret;
d337f35e
JR
15471+ }
15472+ }
4bf69007
AM
15473+
15474+ vxi->vx_flags = vs_mask_flags(vxi->vx_flags,
15475+ vc_data.flagword, mask);
15476+ if (trigger & VXF_PERSISTENT)
15477+ vx_update_persistent(vxi);
15478+
15479+ return 0;
d337f35e
JR
15480+}
15481+
15482+
4bf69007 15483+static inline uint64_t caps_from_cap_t(kernel_cap_t c)
d337f35e 15484+{
4bf69007 15485+ uint64_t v = c.cap[0] | ((uint64_t)c.cap[1] << 32);
d337f35e 15486+
4bf69007
AM
15487+ // printk("caps_from_cap_t(%08x:%08x) = %016llx\n", c.cap[1], c.cap[0], v);
15488+ return v;
d337f35e
JR
15489+}
15490+
4bf69007 15491+static inline kernel_cap_t cap_t_from_caps(uint64_t v)
d337f35e 15492+{
4bf69007 15493+ kernel_cap_t c = __cap_empty_set;
d337f35e 15494+
4bf69007
AM
15495+ c.cap[0] = v & 0xFFFFFFFF;
15496+ c.cap[1] = (v >> 32) & 0xFFFFFFFF;
d337f35e 15497+
4bf69007
AM
15498+ // printk("cap_t_from_caps(%016llx) = %08x:%08x\n", v, c.cap[1], c.cap[0]);
15499+ return c;
d337f35e
JR
15500+}
15501+
15502+
4bf69007 15503+static int do_get_caps(struct vx_info *vxi, uint64_t *bcaps, uint64_t *ccaps)
d337f35e 15504+{
4bf69007
AM
15505+ if (bcaps)
15506+ *bcaps = caps_from_cap_t(vxi->vx_bcaps);
15507+ if (ccaps)
15508+ *ccaps = vxi->vx_ccaps;
d337f35e 15509+
4bf69007
AM
15510+ return 0;
15511+}
d337f35e 15512+
4bf69007
AM
15513+int vc_get_ccaps(struct vx_info *vxi, void __user *data)
15514+{
15515+ struct vcmd_ctx_caps_v1 vc_data;
15516+ int ret;
d337f35e 15517+
4bf69007
AM
15518+ ret = do_get_caps(vxi, NULL, &vc_data.ccaps);
15519+ if (ret)
15520+ return ret;
15521+ vc_data.cmask = ~0ULL;
d337f35e 15522+
4bf69007
AM
15523+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15524+ return -EFAULT;
15525+ return 0;
d337f35e
JR
15526+}
15527+
4bf69007
AM
15528+static int do_set_caps(struct vx_info *vxi,
15529+ uint64_t bcaps, uint64_t bmask, uint64_t ccaps, uint64_t cmask)
d337f35e 15530+{
4bf69007 15531+ uint64_t bcold = caps_from_cap_t(vxi->vx_bcaps);
d337f35e 15532+
4bf69007
AM
15533+#if 0
15534+ printk("do_set_caps(%16llx, %16llx, %16llx, %16llx)\n",
15535+ bcaps, bmask, ccaps, cmask);
15536+#endif
15537+ vxi->vx_bcaps = cap_t_from_caps(
15538+ vs_mask_flags(bcold, bcaps, bmask));
15539+ vxi->vx_ccaps = vs_mask_flags(vxi->vx_ccaps, ccaps, cmask);
d337f35e 15540+
4bf69007 15541+ return 0;
d337f35e
JR
15542+}
15543+
4bf69007 15544+int vc_set_ccaps(struct vx_info *vxi, void __user *data)
d337f35e 15545+{
4bf69007 15546+ struct vcmd_ctx_caps_v1 vc_data;
d337f35e 15547+
2380c486 15548+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15549+ return -EFAULT;
15550+
4bf69007 15551+ return do_set_caps(vxi, 0, 0, vc_data.ccaps, vc_data.cmask);
d337f35e
JR
15552+}
15553+
4bf69007 15554+int vc_get_bcaps(struct vx_info *vxi, void __user *data)
d337f35e 15555+{
4bf69007
AM
15556+ struct vcmd_bcaps vc_data;
15557+ int ret;
d337f35e 15558+
4bf69007
AM
15559+ ret = do_get_caps(vxi, &vc_data.bcaps, NULL);
15560+ if (ret)
15561+ return ret;
15562+ vc_data.bmask = ~0ULL;
d337f35e 15563+
4bf69007
AM
15564+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15565+ return -EFAULT;
15566+ return 0;
d337f35e
JR
15567+}
15568+
4bf69007 15569+int vc_set_bcaps(struct vx_info *vxi, void __user *data)
d337f35e 15570+{
4bf69007 15571+ struct vcmd_bcaps vc_data;
d337f35e 15572+
2380c486 15573+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15574+ return -EFAULT;
15575+
4bf69007 15576+ return do_set_caps(vxi, vc_data.bcaps, vc_data.bmask, 0, 0);
d337f35e
JR
15577+}
15578+
d337f35e 15579+
4bf69007 15580+int vc_get_umask(struct vx_info *vxi, void __user *data)
d337f35e 15581+{
4bf69007 15582+ struct vcmd_umask vc_data;
7e46296a 15583+
4bf69007
AM
15584+ vc_data.umask = vxi->vx_umask;
15585+ vc_data.mask = ~0ULL;
d337f35e 15586+
4bf69007
AM
15587+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15588+ return -EFAULT;
15589+ return 0;
15590+}
d337f35e 15591+
4bf69007
AM
15592+int vc_set_umask(struct vx_info *vxi, void __user *data)
15593+{
15594+ struct vcmd_umask vc_data;
d337f35e 15595+
4bf69007
AM
15596+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15597+ return -EFAULT;
7e46296a 15598+
4bf69007
AM
15599+ vxi->vx_umask = vs_mask_flags(vxi->vx_umask,
15600+ vc_data.umask, vc_data.mask);
15601+ return 0;
15602+}
7e46296a 15603+
d337f35e 15604+
4bf69007
AM
15605+int vc_get_wmask(struct vx_info *vxi, void __user *data)
15606+{
15607+ struct vcmd_wmask vc_data;
d337f35e 15608+
4bf69007
AM
15609+ vc_data.wmask = vxi->vx_wmask;
15610+ vc_data.mask = ~0ULL;
d337f35e 15611+
4bf69007
AM
15612+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15613+ return -EFAULT;
15614+ return 0;
d337f35e
JR
15615+}
15616+
4bf69007 15617+int vc_set_wmask(struct vx_info *vxi, void __user *data)
d337f35e 15618+{
4bf69007 15619+ struct vcmd_wmask vc_data;
d337f35e 15620+
2380c486 15621+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15622+ return -EFAULT;
15623+
4bf69007
AM
15624+ vxi->vx_wmask = vs_mask_flags(vxi->vx_wmask,
15625+ vc_data.wmask, vc_data.mask);
15626+ return 0;
d337f35e
JR
15627+}
15628+
d337f35e 15629+
4bf69007 15630+int vc_get_badness(struct vx_info *vxi, void __user *data)
d337f35e 15631+{
4bf69007
AM
15632+ struct vcmd_badness_v0 vc_data;
15633+
15634+ vc_data.bias = vxi->vx_badness_bias;
15635+
15636+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15637+ return -EFAULT;
15638+ return 0;
15639+}
15640+
15641+int vc_set_badness(struct vx_info *vxi, void __user *data)
15642+{
15643+ struct vcmd_badness_v0 vc_data;
d337f35e 15644+
2380c486 15645+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15646+ return -EFAULT;
15647+
4bf69007
AM
15648+ vxi->vx_badness_bias = vc_data.bias;
15649+ return 0;
d337f35e
JR
15650+}
15651+
4bf69007 15652+#include <linux/module.h>
d337f35e 15653+
4bf69007 15654+EXPORT_SYMBOL_GPL(free_vx_info);
d337f35e 15655+
8de2f54c 15656diff -NurpP --minimal linux-4.4.111/kernel/vserver/cvirt.c linux-4.4.111-vs2.3.9.5/kernel/vserver/cvirt.c
f19bd705 15657--- linux-4.4.111/kernel/vserver/cvirt.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 15658+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/cvirt.c 2018-01-09 22:27:39.000000000 +0000
4bf69007
AM
15659@@ -0,0 +1,313 @@
15660+/*
15661+ * linux/kernel/vserver/cvirt.c
15662+ *
15663+ * Virtual Server: Context Virtualization
15664+ *
927ca606 15665+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
15666+ *
15667+ * V0.01 broken out from limit.c
15668+ * V0.02 added utsname stuff
15669+ * V0.03 changed vcmds to vxi arg
15670+ *
15671+ */
d337f35e 15672+
4bf69007
AM
15673+#include <linux/types.h>
15674+#include <linux/utsname.h>
15675+#include <linux/vs_cvirt.h>
15676+#include <linux/vserver/switch.h>
15677+#include <linux/vserver/cvirt_cmd.h>
d337f35e 15678+
4bf69007 15679+#include <asm/uaccess.h>
d337f35e 15680+
d337f35e 15681+
4bf69007
AM
15682+void vx_vsi_boottime(struct timespec *boottime)
15683+{
15684+ struct vx_info *vxi = current_vx_info();
d337f35e 15685+
4bf69007
AM
15686+ set_normalized_timespec(boottime,
15687+ boottime->tv_sec + vxi->cvirt.bias_uptime.tv_sec,
15688+ boottime->tv_nsec + vxi->cvirt.bias_uptime.tv_nsec);
15689+ return;
d337f35e
JR
15690+}
15691+
4bf69007 15692+void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle)
d337f35e 15693+{
4bf69007 15694+ struct vx_info *vxi = current_vx_info();
d337f35e 15695+
4bf69007
AM
15696+ set_normalized_timespec(uptime,
15697+ uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec,
15698+ uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec);
15699+ if (!idle)
15700+ return;
15701+ set_normalized_timespec(idle,
15702+ idle->tv_sec - vxi->cvirt.bias_idle.tv_sec,
15703+ idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec);
15704+ return;
d337f35e
JR
15705+}
15706+
4bf69007 15707+uint64_t vx_idle_jiffies(void)
d337f35e 15708+{
4bf69007 15709+ return init_task.utime + init_task.stime;
d337f35e
JR
15710+}
15711+
d337f35e
JR
15712+
15713+
4bf69007
AM
15714+static inline uint32_t __update_loadavg(uint32_t load,
15715+ int wsize, int delta, int n)
d337f35e 15716+{
4bf69007 15717+ unsigned long long calc, prev;
d337f35e 15718+
4bf69007
AM
15719+ /* just set it to n */
15720+ if (unlikely(delta >= wsize))
15721+ return (n << FSHIFT);
d337f35e 15722+
4bf69007
AM
15723+ calc = delta * n;
15724+ calc <<= FSHIFT;
15725+ prev = (wsize - delta);
15726+ prev *= load;
15727+ calc += prev;
15728+ do_div(calc, wsize);
15729+ return calc;
15730+}
d337f35e 15731+
d337f35e 15732+
4bf69007
AM
15733+void vx_update_load(struct vx_info *vxi)
15734+{
15735+ uint32_t now, last, delta;
15736+ unsigned int nr_running, nr_uninterruptible;
15737+ unsigned int total;
15738+ unsigned long flags;
d337f35e 15739+
4bf69007 15740+ spin_lock_irqsave(&vxi->cvirt.load_lock, flags);
d337f35e 15741+
4bf69007
AM
15742+ now = jiffies;
15743+ last = vxi->cvirt.load_last;
15744+ delta = now - last;
d337f35e 15745+
4bf69007
AM
15746+ if (delta < 5*HZ)
15747+ goto out;
d337f35e 15748+
4bf69007
AM
15749+ nr_running = atomic_read(&vxi->cvirt.nr_running);
15750+ nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible);
15751+ total = nr_running + nr_uninterruptible;
d337f35e 15752+
4bf69007
AM
15753+ vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0],
15754+ 60*HZ, delta, total);
15755+ vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1],
15756+ 5*60*HZ, delta, total);
15757+ vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2],
15758+ 15*60*HZ, delta, total);
d337f35e 15759+
4bf69007
AM
15760+ vxi->cvirt.load_last = now;
15761+out:
15762+ atomic_inc(&vxi->cvirt.load_updates);
15763+ spin_unlock_irqrestore(&vxi->cvirt.load_lock, flags);
d337f35e
JR
15764+}
15765+
d337f35e 15766+
d337f35e 15767+/*
4bf69007 15768+ * Commands to do_syslog:
d337f35e 15769+ *
4bf69007
AM
15770+ * 0 -- Close the log. Currently a NOP.
15771+ * 1 -- Open the log. Currently a NOP.
15772+ * 2 -- Read from the log.
15773+ * 3 -- Read all messages remaining in the ring buffer.
15774+ * 4 -- Read and clear all messages remaining in the ring buffer
15775+ * 5 -- Clear ring buffer.
15776+ * 6 -- Disable printk's to console
15777+ * 7 -- Enable printk's to console
15778+ * 8 -- Set level of messages printed to console
15779+ * 9 -- Return number of unread characters in the log buffer
15780+ * 10 -- Return size of the log buffer
d337f35e 15781+ */
4bf69007
AM
15782+int vx_do_syslog(int type, char __user *buf, int len)
15783+{
15784+ int error = 0;
15785+ int do_clear = 0;
15786+ struct vx_info *vxi = current_vx_info();
15787+ struct _vx_syslog *log;
d337f35e 15788+
4bf69007
AM
15789+ if (!vxi)
15790+ return -EINVAL;
15791+ log = &vxi->cvirt.syslog;
15792+
15793+ switch (type) {
15794+ case 0: /* Close log */
15795+ case 1: /* Open log */
15796+ break;
15797+ case 2: /* Read from log */
15798+ error = wait_event_interruptible(log->log_wait,
15799+ (log->log_start - log->log_end));
15800+ if (error)
15801+ break;
15802+ spin_lock_irq(&log->logbuf_lock);
15803+ spin_unlock_irq(&log->logbuf_lock);
15804+ break;
15805+ case 4: /* Read/clear last kernel messages */
15806+ do_clear = 1;
15807+ /* fall through */
15808+ case 3: /* Read last kernel messages */
15809+ return 0;
d337f35e 15810+
4bf69007
AM
15811+ case 5: /* Clear ring buffer */
15812+ return 0;
d337f35e 15813+
4bf69007
AM
15814+ case 6: /* Disable logging to console */
15815+ case 7: /* Enable logging to console */
15816+ case 8: /* Set level of messages printed to console */
15817+ break;
d337f35e 15818+
4bf69007
AM
15819+ case 9: /* Number of chars in the log buffer */
15820+ return 0;
15821+ case 10: /* Size of the log buffer */
15822+ return 0;
15823+ default:
15824+ error = -EINVAL;
15825+ break;
15826+ }
15827+ return error;
1e8b8f9b 15828+}
d337f35e 15829+
4bf69007
AM
15830+
15831+/* virtual host info names */
15832+
15833+static char *vx_vhi_name(struct vx_info *vxi, int id)
d337f35e 15834+{
4bf69007
AM
15835+ struct nsproxy *nsproxy;
15836+ struct uts_namespace *uts;
d337f35e 15837+
4bf69007
AM
15838+ if (id == VHIN_CONTEXT)
15839+ return vxi->vx_name;
15840+
15841+ nsproxy = vxi->space[0].vx_nsproxy;
15842+ if (!nsproxy)
15843+ return NULL;
15844+
15845+ uts = nsproxy->uts_ns;
15846+ if (!uts)
15847+ return NULL;
15848+
15849+ switch (id) {
15850+ case VHIN_SYSNAME:
15851+ return uts->name.sysname;
15852+ case VHIN_NODENAME:
15853+ return uts->name.nodename;
15854+ case VHIN_RELEASE:
15855+ return uts->name.release;
15856+ case VHIN_VERSION:
15857+ return uts->name.version;
15858+ case VHIN_MACHINE:
15859+ return uts->name.machine;
15860+ case VHIN_DOMAINNAME:
15861+ return uts->name.domainname;
15862+ default:
15863+ return NULL;
d337f35e 15864+ }
4bf69007 15865+ return NULL;
d337f35e
JR
15866+}
15867+
4bf69007 15868+int vc_set_vhi_name(struct vx_info *vxi, void __user *data)
d337f35e 15869+{
4bf69007
AM
15870+ struct vcmd_vhi_name_v0 vc_data;
15871+ char *name;
d337f35e 15872+
4bf69007
AM
15873+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15874+ return -EFAULT;
d337f35e 15875+
4bf69007
AM
15876+ name = vx_vhi_name(vxi, vc_data.field);
15877+ if (!name)
15878+ return -EINVAL;
d337f35e 15879+
4bf69007
AM
15880+ memcpy(name, vc_data.name, 65);
15881+ return 0;
15882+}
d337f35e 15883+
4bf69007
AM
15884+int vc_get_vhi_name(struct vx_info *vxi, void __user *data)
15885+{
15886+ struct vcmd_vhi_name_v0 vc_data;
15887+ char *name;
d337f35e 15888+
4bf69007
AM
15889+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15890+ return -EFAULT;
d337f35e 15891+
4bf69007
AM
15892+ name = vx_vhi_name(vxi, vc_data.field);
15893+ if (!name)
15894+ return -EINVAL;
d337f35e 15895+
4bf69007
AM
15896+ memcpy(vc_data.name, name, 65);
15897+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15898+ return -EFAULT;
15899+ return 0;
15900+}
d337f35e 15901+
d337f35e 15902+
4bf69007
AM
15903+int vc_virt_stat(struct vx_info *vxi, void __user *data)
15904+{
15905+ struct vcmd_virt_stat_v0 vc_data;
15906+ struct _vx_cvirt *cvirt = &vxi->cvirt;
15907+ struct timespec uptime;
99a884b4 15908+
927ca606 15909+ ktime_get_ts(&uptime);
4bf69007
AM
15910+ set_normalized_timespec(&uptime,
15911+ uptime.tv_sec - cvirt->bias_uptime.tv_sec,
15912+ uptime.tv_nsec - cvirt->bias_uptime.tv_nsec);
d337f35e 15913+
4bf69007
AM
15914+ vc_data.offset = timespec_to_ns(&cvirt->bias_ts);
15915+ vc_data.uptime = timespec_to_ns(&uptime);
15916+ vc_data.nr_threads = atomic_read(&cvirt->nr_threads);
15917+ vc_data.nr_running = atomic_read(&cvirt->nr_running);
15918+ vc_data.nr_uninterruptible = atomic_read(&cvirt->nr_uninterruptible);
15919+ vc_data.nr_onhold = atomic_read(&cvirt->nr_onhold);
15920+ vc_data.nr_forks = atomic_read(&cvirt->total_forks);
15921+ vc_data.load[0] = cvirt->load[0];
15922+ vc_data.load[1] = cvirt->load[1];
15923+ vc_data.load[2] = cvirt->load[2];
15924+
15925+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15926+ return -EFAULT;
15927+ return 0;
d337f35e
JR
15928+}
15929+
15930+
4bf69007
AM
15931+#ifdef CONFIG_VSERVER_VTIME
15932+
15933+/* virtualized time base */
15934+
15935+void vx_adjust_timespec(struct timespec *ts)
d337f35e 15936+{
4bf69007 15937+ struct vx_info *vxi;
d337f35e 15938+
4bf69007
AM
15939+ if (!vx_flags(VXF_VIRT_TIME, 0))
15940+ return;
d337f35e 15941+
4bf69007
AM
15942+ vxi = current_vx_info();
15943+ ts->tv_sec += vxi->cvirt.bias_ts.tv_sec;
15944+ ts->tv_nsec += vxi->cvirt.bias_ts.tv_nsec;
d337f35e 15945+
4bf69007
AM
15946+ if (ts->tv_nsec >= NSEC_PER_SEC) {
15947+ ts->tv_sec++;
15948+ ts->tv_nsec -= NSEC_PER_SEC;
15949+ } else if (ts->tv_nsec < 0) {
15950+ ts->tv_sec--;
15951+ ts->tv_nsec += NSEC_PER_SEC;
d337f35e 15952+ }
d337f35e
JR
15953+}
15954+
4bf69007 15955+int vx_settimeofday(const struct timespec *ts)
99a884b4 15956+{
4bf69007
AM
15957+ struct timespec ats, delta;
15958+ struct vx_info *vxi;
99a884b4 15959+
4bf69007
AM
15960+ if (!vx_flags(VXF_VIRT_TIME, 0))
15961+ return do_settimeofday(ts);
99a884b4 15962+
4bf69007
AM
15963+ getnstimeofday(&ats);
15964+ delta = timespec_sub(*ts, ats);
99a884b4 15965+
4bf69007
AM
15966+ vxi = current_vx_info();
15967+ vxi->cvirt.bias_ts = timespec_add(vxi->cvirt.bias_ts, delta);
99a884b4
AM
15968+ return 0;
15969+}
d337f35e 15970+
4bf69007 15971+#endif
d337f35e 15972+
8de2f54c 15973diff -NurpP --minimal linux-4.4.111/kernel/vserver/cvirt_init.h linux-4.4.111-vs2.3.9.5/kernel/vserver/cvirt_init.h
f19bd705 15974--- linux-4.4.111/kernel/vserver/cvirt_init.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 15975+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/cvirt_init.h 2018-01-09 22:16:00.000000000 +0000
4bf69007 15976@@ -0,0 +1,70 @@
d337f35e 15977+
d337f35e 15978+
4bf69007 15979+extern uint64_t vx_idle_jiffies(void);
d337f35e 15980+
4bf69007
AM
15981+static inline void vx_info_init_cvirt(struct _vx_cvirt *cvirt)
15982+{
15983+ uint64_t idle_jiffies = vx_idle_jiffies();
15984+ uint64_t nsuptime;
d337f35e 15985+
927ca606 15986+ ktime_get_ts(&cvirt->bias_uptime);
4bf69007
AM
15987+ nsuptime = (unsigned long long)cvirt->bias_uptime.tv_sec
15988+ * NSEC_PER_SEC + cvirt->bias_uptime.tv_nsec;
15989+ cvirt->bias_clock = nsec_to_clock_t(nsuptime);
15990+ cvirt->bias_ts.tv_sec = 0;
15991+ cvirt->bias_ts.tv_nsec = 0;
d337f35e 15992+
4bf69007
AM
15993+ jiffies_to_timespec(idle_jiffies, &cvirt->bias_idle);
15994+ atomic_set(&cvirt->nr_threads, 0);
15995+ atomic_set(&cvirt->nr_running, 0);
15996+ atomic_set(&cvirt->nr_uninterruptible, 0);
15997+ atomic_set(&cvirt->nr_onhold, 0);
d337f35e 15998+
4bf69007
AM
15999+ spin_lock_init(&cvirt->load_lock);
16000+ cvirt->load_last = jiffies;
16001+ atomic_set(&cvirt->load_updates, 0);
16002+ cvirt->load[0] = 0;
16003+ cvirt->load[1] = 0;
16004+ cvirt->load[2] = 0;
16005+ atomic_set(&cvirt->total_forks, 0);
d337f35e 16006+
4bf69007
AM
16007+ spin_lock_init(&cvirt->syslog.logbuf_lock);
16008+ init_waitqueue_head(&cvirt->syslog.log_wait);
16009+ cvirt->syslog.log_start = 0;
16010+ cvirt->syslog.log_end = 0;
16011+ cvirt->syslog.con_start = 0;
16012+ cvirt->syslog.logged_chars = 0;
16013+}
16014+
16015+static inline
16016+void vx_info_init_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
d337f35e 16017+{
4bf69007
AM
16018+ // cvirt_pc->cpustat = { 0 };
16019+}
d337f35e 16020+
4bf69007
AM
16021+static inline void vx_info_exit_cvirt(struct _vx_cvirt *cvirt)
16022+{
16023+#ifdef CONFIG_VSERVER_WARN
16024+ int value;
16025+#endif
16026+ vxwprintk_xid((value = atomic_read(&cvirt->nr_threads)),
16027+ "!!! cvirt: %p[nr_threads] = %d on exit.",
16028+ cvirt, value);
16029+ vxwprintk_xid((value = atomic_read(&cvirt->nr_running)),
16030+ "!!! cvirt: %p[nr_running] = %d on exit.",
16031+ cvirt, value);
16032+ vxwprintk_xid((value = atomic_read(&cvirt->nr_uninterruptible)),
16033+ "!!! cvirt: %p[nr_uninterruptible] = %d on exit.",
16034+ cvirt, value);
16035+ vxwprintk_xid((value = atomic_read(&cvirt->nr_onhold)),
16036+ "!!! cvirt: %p[nr_onhold] = %d on exit.",
16037+ cvirt, value);
16038+ return;
16039+}
d337f35e 16040+
4bf69007
AM
16041+static inline
16042+void vx_info_exit_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
16043+{
16044+ return;
16045+}
d337f35e 16046+
8de2f54c 16047diff -NurpP --minimal linux-4.4.111/kernel/vserver/cvirt_proc.h linux-4.4.111-vs2.3.9.5/kernel/vserver/cvirt_proc.h
f19bd705 16048--- linux-4.4.111/kernel/vserver/cvirt_proc.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 16049+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/cvirt_proc.h 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
16050@@ -0,0 +1,123 @@
16051+#ifndef _VX_CVIRT_PROC_H
16052+#define _VX_CVIRT_PROC_H
d337f35e 16053+
4bf69007
AM
16054+#include <linux/nsproxy.h>
16055+#include <linux/mnt_namespace.h>
16056+#include <linux/ipc_namespace.h>
16057+#include <linux/utsname.h>
16058+#include <linux/ipc.h>
d337f35e 16059+
4bf69007 16060+extern int vx_info_mnt_namespace(struct mnt_namespace *, char *);
d337f35e 16061+
4bf69007
AM
16062+static inline
16063+int vx_info_proc_nsproxy(struct nsproxy *nsproxy, char *buffer)
16064+{
16065+ struct mnt_namespace *ns;
16066+ struct uts_namespace *uts;
16067+ struct ipc_namespace *ipc;
16068+ int length = 0;
d337f35e 16069+
4bf69007
AM
16070+ if (!nsproxy)
16071+ goto out;
d337f35e 16072+
4bf69007
AM
16073+ length += sprintf(buffer + length,
16074+ "NSProxy:\t%p [%p,%p,%p]\n",
16075+ nsproxy, nsproxy->mnt_ns,
16076+ nsproxy->uts_ns, nsproxy->ipc_ns);
d337f35e 16077+
4bf69007
AM
16078+ ns = nsproxy->mnt_ns;
16079+ if (!ns)
16080+ goto skip_ns;
d337f35e 16081+
4bf69007 16082+ length += vx_info_mnt_namespace(ns, buffer + length);
d337f35e 16083+
4bf69007 16084+skip_ns:
d337f35e 16085+
4bf69007
AM
16086+ uts = nsproxy->uts_ns;
16087+ if (!uts)
16088+ goto skip_uts;
d337f35e 16089+
4bf69007
AM
16090+ length += sprintf(buffer + length,
16091+ "SysName:\t%.*s\n"
16092+ "NodeName:\t%.*s\n"
16093+ "Release:\t%.*s\n"
16094+ "Version:\t%.*s\n"
16095+ "Machine:\t%.*s\n"
16096+ "DomainName:\t%.*s\n",
16097+ __NEW_UTS_LEN, uts->name.sysname,
16098+ __NEW_UTS_LEN, uts->name.nodename,
16099+ __NEW_UTS_LEN, uts->name.release,
16100+ __NEW_UTS_LEN, uts->name.version,
16101+ __NEW_UTS_LEN, uts->name.machine,
16102+ __NEW_UTS_LEN, uts->name.domainname);
16103+skip_uts:
d337f35e 16104+
4bf69007
AM
16105+ ipc = nsproxy->ipc_ns;
16106+ if (!ipc)
16107+ goto skip_ipc;
d337f35e 16108+
4bf69007
AM
16109+ length += sprintf(buffer + length,
16110+ "SEMS:\t\t%d %d %d %d %d\n"
16111+ "MSG:\t\t%d %d %d\n"
b00e13aa 16112+ "SHM:\t\t%lu %lu %d %ld\n",
4bf69007
AM
16113+ ipc->sem_ctls[0], ipc->sem_ctls[1],
16114+ ipc->sem_ctls[2], ipc->sem_ctls[3],
16115+ ipc->used_sems,
16116+ ipc->msg_ctlmax, ipc->msg_ctlmnb, ipc->msg_ctlmni,
16117+ (unsigned long)ipc->shm_ctlmax,
16118+ (unsigned long)ipc->shm_ctlall,
16119+ ipc->shm_ctlmni, ipc->shm_tot);
16120+skip_ipc:
16121+out:
16122+ return length;
16123+}
d337f35e
JR
16124+
16125+
4bf69007 16126+#include <linux/sched.h>
d337f35e 16127+
4bf69007
AM
16128+#define LOAD_INT(x) ((x) >> FSHIFT)
16129+#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1 - 1)) * 100)
d337f35e 16130+
4bf69007
AM
16131+static inline
16132+int vx_info_proc_cvirt(struct _vx_cvirt *cvirt, char *buffer)
d337f35e 16133+{
4bf69007
AM
16134+ int length = 0;
16135+ int a, b, c;
d337f35e 16136+
4bf69007
AM
16137+ length += sprintf(buffer + length,
16138+ "BiasUptime:\t%lu.%02lu\n",
16139+ (unsigned long)cvirt->bias_uptime.tv_sec,
16140+ (cvirt->bias_uptime.tv_nsec / (NSEC_PER_SEC / 100)));
d337f35e 16141+
4bf69007
AM
16142+ a = cvirt->load[0] + (FIXED_1 / 200);
16143+ b = cvirt->load[1] + (FIXED_1 / 200);
16144+ c = cvirt->load[2] + (FIXED_1 / 200);
16145+ length += sprintf(buffer + length,
16146+ "nr_threads:\t%d\n"
16147+ "nr_running:\t%d\n"
16148+ "nr_unintr:\t%d\n"
16149+ "nr_onhold:\t%d\n"
16150+ "load_updates:\t%d\n"
16151+ "loadavg:\t%d.%02d %d.%02d %d.%02d\n"
16152+ "total_forks:\t%d\n",
16153+ atomic_read(&cvirt->nr_threads),
16154+ atomic_read(&cvirt->nr_running),
16155+ atomic_read(&cvirt->nr_uninterruptible),
16156+ atomic_read(&cvirt->nr_onhold),
16157+ atomic_read(&cvirt->load_updates),
16158+ LOAD_INT(a), LOAD_FRAC(a),
16159+ LOAD_INT(b), LOAD_FRAC(b),
16160+ LOAD_INT(c), LOAD_FRAC(c),
16161+ atomic_read(&cvirt->total_forks));
16162+ return length;
d337f35e
JR
16163+}
16164+
4bf69007
AM
16165+static inline
16166+int vx_info_proc_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc,
16167+ char *buffer, int cpu)
16168+{
16169+ int length = 0;
16170+ return length;
16171+}
d337f35e 16172+
4bf69007 16173+#endif /* _VX_CVIRT_PROC_H */
8de2f54c 16174diff -NurpP --minimal linux-4.4.111/kernel/vserver/debug.c linux-4.4.111-vs2.3.9.5/kernel/vserver/debug.c
f19bd705 16175--- linux-4.4.111/kernel/vserver/debug.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 16176+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/debug.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
16177@@ -0,0 +1,32 @@
16178+/*
16179+ * kernel/vserver/debug.c
16180+ *
927ca606 16181+ * Copyright (C) 2005-2007 Herbert P?tzl
4bf69007
AM
16182+ *
16183+ * V0.01 vx_info dump support
16184+ *
16185+ */
d337f35e 16186+
4bf69007 16187+#include <linux/module.h>
d337f35e 16188+
4bf69007 16189+#include <linux/vserver/context.h>
d337f35e 16190+
d337f35e 16191+
4bf69007 16192+void dump_vx_info(struct vx_info *vxi, int level)
d337f35e 16193+{
4bf69007
AM
16194+ printk("vx_info %p[#%d, %d.%d, %4x]\n", vxi, vxi->vx_id,
16195+ atomic_read(&vxi->vx_usecnt),
16196+ atomic_read(&vxi->vx_tasks),
16197+ vxi->vx_state);
16198+ if (level > 0) {
16199+ __dump_vx_limit(&vxi->limit);
16200+ __dump_vx_sched(&vxi->sched);
16201+ __dump_vx_cvirt(&vxi->cvirt);
16202+ __dump_vx_cacct(&vxi->cacct);
16203+ }
16204+ printk("---\n");
16205+}
d337f35e 16206+
d337f35e 16207+
4bf69007 16208+EXPORT_SYMBOL_GPL(dump_vx_info);
d337f35e 16209+
8de2f54c 16210diff -NurpP --minimal linux-4.4.111/kernel/vserver/device.c linux-4.4.111-vs2.3.9.5/kernel/vserver/device.c
f19bd705 16211--- linux-4.4.111/kernel/vserver/device.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 16212+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/device.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
16213@@ -0,0 +1,443 @@
16214+/*
16215+ * linux/kernel/vserver/device.c
16216+ *
16217+ * Linux-VServer: Device Support
16218+ *
927ca606 16219+ * Copyright (C) 2006 Herbert P?tzl
4bf69007
AM
16220+ * Copyright (C) 2007 Daniel Hokka Zakrisson
16221+ *
16222+ * V0.01 device mapping basics
16223+ * V0.02 added defaults
16224+ *
16225+ */
d337f35e 16226+
4bf69007
AM
16227+#include <linux/slab.h>
16228+#include <linux/rcupdate.h>
16229+#include <linux/fs.h>
16230+#include <linux/namei.h>
16231+#include <linux/hash.h>
d337f35e 16232+
4bf69007
AM
16233+#include <asm/errno.h>
16234+#include <asm/uaccess.h>
16235+#include <linux/vserver/base.h>
16236+#include <linux/vserver/debug.h>
16237+#include <linux/vserver/context.h>
16238+#include <linux/vserver/device.h>
16239+#include <linux/vserver/device_cmd.h>
d337f35e 16240+
d337f35e 16241+
4bf69007 16242+#define DMAP_HASH_BITS 4
d337f35e 16243+
d337f35e 16244+
4bf69007
AM
16245+struct vs_mapping {
16246+ union {
16247+ struct hlist_node hlist;
16248+ struct list_head list;
16249+ } u;
16250+#define dm_hlist u.hlist
16251+#define dm_list u.list
61333608 16252+ vxid_t xid;
4bf69007
AM
16253+ dev_t device;
16254+ struct vx_dmap_target target;
16255+};
d337f35e 16256+
d337f35e 16257+
4bf69007 16258+static struct hlist_head dmap_main_hash[1 << DMAP_HASH_BITS];
d337f35e 16259+
4bf69007 16260+static DEFINE_SPINLOCK(dmap_main_hash_lock);
d337f35e 16261+
4bf69007
AM
16262+static struct vx_dmap_target dmap_defaults[2] = {
16263+ { .flags = DATTR_OPEN },
16264+ { .flags = DATTR_OPEN },
16265+};
d337f35e
JR
16266+
16267+
4bf69007 16268+struct kmem_cache *dmap_cachep __read_mostly;
d337f35e 16269+
4bf69007
AM
16270+int __init dmap_cache_init(void)
16271+{
16272+ dmap_cachep = kmem_cache_create("dmap_cache",
16273+ sizeof(struct vs_mapping), 0,
16274+ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
d337f35e
JR
16275+ return 0;
16276+}
16277+
4bf69007 16278+__initcall(dmap_cache_init);
d337f35e 16279+
4bf69007
AM
16280+
16281+static inline unsigned int __hashval(dev_t dev, int bits)
d337f35e 16282+{
4bf69007
AM
16283+ return hash_long((unsigned long)dev, bits);
16284+}
d337f35e 16285+
d337f35e 16286+
4bf69007
AM
16287+/* __hash_mapping()
16288+ * add the mapping to the hash table
16289+ */
16290+static inline void __hash_mapping(struct vx_info *vxi, struct vs_mapping *vdm)
16291+{
16292+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16293+ struct hlist_head *head, *hash = dmap_main_hash;
16294+ int device = vdm->device;
d337f35e 16295+
4bf69007
AM
16296+ spin_lock(hash_lock);
16297+ vxdprintk(VXD_CBIT(misc, 8), "__hash_mapping: %p[#%d] %08x:%08x",
16298+ vxi, vxi ? vxi->vx_id : 0, device, vdm->target.target);
d337f35e 16299+
4bf69007
AM
16300+ head = &hash[__hashval(device, DMAP_HASH_BITS)];
16301+ hlist_add_head(&vdm->dm_hlist, head);
16302+ spin_unlock(hash_lock);
16303+}
16304+
16305+
16306+static inline int __mode_to_default(umode_t mode)
16307+{
16308+ switch (mode) {
16309+ case S_IFBLK:
16310+ return 0;
16311+ case S_IFCHR:
16312+ return 1;
16313+ default:
16314+ BUG();
d337f35e 16315+ }
d337f35e
JR
16316+}
16317+
4bf69007
AM
16318+
16319+/* __set_default()
16320+ * set a default
16321+ */
16322+static inline void __set_default(struct vx_info *vxi, umode_t mode,
16323+ struct vx_dmap_target *vdmt)
d337f35e 16324+{
4bf69007
AM
16325+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16326+ spin_lock(hash_lock);
d337f35e 16327+
4bf69007
AM
16328+ if (vxi)
16329+ vxi->dmap.targets[__mode_to_default(mode)] = *vdmt;
16330+ else
16331+ dmap_defaults[__mode_to_default(mode)] = *vdmt;
d337f35e 16332+
d337f35e 16333+
4bf69007 16334+ spin_unlock(hash_lock);
d337f35e 16335+
4bf69007
AM
16336+ vxdprintk(VXD_CBIT(misc, 8), "__set_default: %p[#%u] %08x %04x",
16337+ vxi, vxi ? vxi->vx_id : 0, vdmt->target, vdmt->flags);
d337f35e
JR
16338+}
16339+
d337f35e 16340+
4bf69007
AM
16341+/* __remove_default()
16342+ * remove a default
16343+ */
16344+static inline int __remove_default(struct vx_info *vxi, umode_t mode)
d337f35e 16345+{
4bf69007
AM
16346+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16347+ spin_lock(hash_lock);
d337f35e 16348+
4bf69007
AM
16349+ if (vxi)
16350+ vxi->dmap.targets[__mode_to_default(mode)].flags = 0;
16351+ else /* remove == reset */
16352+ dmap_defaults[__mode_to_default(mode)].flags = DATTR_OPEN | mode;
d337f35e 16353+
4bf69007
AM
16354+ spin_unlock(hash_lock);
16355+ return 0;
d337f35e
JR
16356+}
16357+
d337f35e 16358+
4bf69007
AM
16359+/* __find_mapping()
16360+ * find a mapping in the hash table
16361+ *
16362+ * caller must hold hash_lock
16363+ */
61333608 16364+static inline int __find_mapping(vxid_t xid, dev_t device, umode_t mode,
4bf69007
AM
16365+ struct vs_mapping **local, struct vs_mapping **global)
16366+{
16367+ struct hlist_head *hash = dmap_main_hash;
16368+ struct hlist_head *head = &hash[__hashval(device, DMAP_HASH_BITS)];
16369+ struct hlist_node *pos;
16370+ struct vs_mapping *vdm;
d337f35e 16371+
4bf69007
AM
16372+ *local = NULL;
16373+ if (global)
16374+ *global = NULL;
d337f35e 16375+
4bf69007
AM
16376+ hlist_for_each(pos, head) {
16377+ vdm = hlist_entry(pos, struct vs_mapping, dm_hlist);
d337f35e 16378+
4bf69007
AM
16379+ if ((vdm->device == device) &&
16380+ !((vdm->target.flags ^ mode) & S_IFMT)) {
16381+ if (vdm->xid == xid) {
16382+ *local = vdm;
16383+ return 1;
16384+ } else if (global && vdm->xid == 0)
16385+ *global = vdm;
2380c486
JR
16386+ }
16387+ }
16388+
4bf69007
AM
16389+ if (global && *global)
16390+ return 0;
16391+ else
16392+ return -ENOENT;
2380c486
JR
16393+}
16394+
16395+
4bf69007
AM
16396+/* __lookup_mapping()
16397+ * find a mapping and store the result in target and flags
16398+ */
16399+static inline int __lookup_mapping(struct vx_info *vxi,
16400+ dev_t device, dev_t *target, int *flags, umode_t mode)
2380c486 16401+{
4bf69007
AM
16402+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16403+ struct vs_mapping *vdm, *global;
16404+ struct vx_dmap_target *vdmt;
2380c486 16405+ int ret = 0;
61333608 16406+ vxid_t xid = vxi->vx_id;
4bf69007 16407+ int index;
2380c486 16408+
4bf69007
AM
16409+ spin_lock(hash_lock);
16410+ if (__find_mapping(xid, device, mode, &vdm, &global) > 0) {
2380c486 16411+ ret = 1;
4bf69007
AM
16412+ vdmt = &vdm->target;
16413+ goto found;
16414+ }
2380c486 16415+
4bf69007
AM
16416+ index = __mode_to_default(mode);
16417+ if (vxi && vxi->dmap.targets[index].flags) {
16418+ ret = 2;
16419+ vdmt = &vxi->dmap.targets[index];
16420+ } else if (global) {
16421+ ret = 3;
16422+ vdmt = &global->target;
16423+ goto found;
16424+ } else {
16425+ ret = 4;
16426+ vdmt = &dmap_defaults[index];
d337f35e 16427+ }
2380c486 16428+
4bf69007
AM
16429+found:
16430+ if (target && (vdmt->flags & DATTR_REMAP))
16431+ *target = vdmt->target;
16432+ else if (target)
16433+ *target = device;
16434+ if (flags)
16435+ *flags = vdmt->flags;
16436+
16437+ spin_unlock(hash_lock);
2380c486
JR
16438+
16439+ return ret;
d337f35e
JR
16440+}
16441+
16442+
4bf69007
AM
16443+/* __remove_mapping()
16444+ * remove a mapping from the hash table
16445+ */
16446+static inline int __remove_mapping(struct vx_info *vxi, dev_t device,
16447+ umode_t mode)
d337f35e 16448+{
4bf69007
AM
16449+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16450+ struct vs_mapping *vdm = NULL;
d337f35e
JR
16451+ int ret = 0;
16452+
4bf69007
AM
16453+ spin_lock(hash_lock);
16454+
16455+ ret = __find_mapping((vxi ? vxi->vx_id : 0), device, mode, &vdm,
16456+ NULL);
16457+ vxdprintk(VXD_CBIT(misc, 8), "__remove_mapping: %p[#%d] %08x %04x",
16458+ vxi, vxi ? vxi->vx_id : 0, device, mode);
16459+ if (ret < 0)
2380c486 16460+ goto out;
4bf69007 16461+ hlist_del(&vdm->dm_hlist);
2380c486 16462+
2380c486 16463+out:
4bf69007
AM
16464+ spin_unlock(hash_lock);
16465+ if (vdm)
16466+ kmem_cache_free(dmap_cachep, vdm);
2380c486
JR
16467+ return ret;
16468+}
16469+
16470+
2380c486 16471+
4bf69007
AM
16472+int vs_map_device(struct vx_info *vxi,
16473+ dev_t device, dev_t *target, umode_t mode)
2380c486 16474+{
4bf69007 16475+ int ret, flags = DATTR_MASK;
2380c486 16476+
4bf69007
AM
16477+ if (!vxi) {
16478+ if (target)
16479+ *target = device;
2380c486 16480+ goto out;
2380c486 16481+ }
4bf69007
AM
16482+ ret = __lookup_mapping(vxi, device, target, &flags, mode);
16483+ vxdprintk(VXD_CBIT(misc, 8), "vs_map_device: %08x target: %08x flags: %04x mode: %04x mapped=%d",
16484+ device, target ? *target : 0, flags, mode, ret);
2380c486 16485+out:
4bf69007 16486+ return (flags & DATTR_MASK);
2380c486
JR
16487+}
16488+
2380c486 16489+
4bf69007
AM
16490+
16491+static int do_set_mapping(struct vx_info *vxi,
16492+ dev_t device, dev_t target, int flags, umode_t mode)
2380c486 16493+{
4bf69007
AM
16494+ if (device) {
16495+ struct vs_mapping *new;
2380c486 16496+
4bf69007
AM
16497+ new = kmem_cache_alloc(dmap_cachep, GFP_KERNEL);
16498+ if (!new)
16499+ return -ENOMEM;
16500+
16501+ INIT_HLIST_NODE(&new->dm_hlist);
16502+ new->device = device;
16503+ new->target.target = target;
16504+ new->target.flags = flags | mode;
16505+ new->xid = (vxi ? vxi->vx_id : 0);
16506+
16507+ vxdprintk(VXD_CBIT(misc, 8), "do_set_mapping: %08x target: %08x flags: %04x", device, target, flags);
16508+ __hash_mapping(vxi, new);
16509+ } else {
16510+ struct vx_dmap_target new = {
16511+ .target = target,
16512+ .flags = flags | mode,
16513+ };
16514+ __set_default(vxi, mode, &new);
16515+ }
16516+ return 0;
2380c486
JR
16517+}
16518+
4bf69007
AM
16519+
16520+static int do_unset_mapping(struct vx_info *vxi,
16521+ dev_t device, dev_t target, int flags, umode_t mode)
2380c486 16522+{
4bf69007 16523+ int ret = -EINVAL;
763640ca 16524+
4bf69007
AM
16525+ if (device) {
16526+ ret = __remove_mapping(vxi, device, mode);
16527+ if (ret < 0)
16528+ goto out;
16529+ } else {
16530+ ret = __remove_default(vxi, mode);
16531+ if (ret < 0)
16532+ goto out;
16533+ }
2380c486 16534+
4bf69007
AM
16535+out:
16536+ return ret;
16537+}
2380c486 16538+
2380c486 16539+
4bf69007
AM
16540+static inline int __user_device(const char __user *name, dev_t *dev,
16541+ umode_t *mode)
16542+{
927ca606 16543+ struct path path;
4bf69007 16544+ int ret;
2380c486 16545+
4bf69007
AM
16546+ if (!name) {
16547+ *dev = 0;
16548+ return 0;
16549+ }
927ca606 16550+ ret = user_lpath(name, &path);
4bf69007
AM
16551+ if (ret)
16552+ return ret;
927ca606
AM
16553+ if (path.dentry->d_inode) {
16554+ *dev = path.dentry->d_inode->i_rdev;
16555+ *mode = path.dentry->d_inode->i_mode;
4bf69007 16556+ }
927ca606 16557+ path_put(&path);
4bf69007
AM
16558+ return 0;
16559+}
2380c486 16560+
4bf69007
AM
16561+static inline int __mapping_mode(dev_t device, dev_t target,
16562+ umode_t device_mode, umode_t target_mode, umode_t *mode)
16563+{
16564+ if (device)
16565+ *mode = device_mode & S_IFMT;
16566+ else if (target)
16567+ *mode = target_mode & S_IFMT;
16568+ else
16569+ return -EINVAL;
2380c486 16570+
4bf69007
AM
16571+ /* if both given, device and target mode have to match */
16572+ if (device && target &&
16573+ ((device_mode ^ target_mode) & S_IFMT))
16574+ return -EINVAL;
16575+ return 0;
16576+}
d337f35e 16577+
d337f35e 16578+
4bf69007
AM
16579+static inline int do_mapping(struct vx_info *vxi, const char __user *device_path,
16580+ const char __user *target_path, int flags, int set)
16581+{
16582+ dev_t device = ~0, target = ~0;
16583+ umode_t device_mode = 0, target_mode = 0, mode;
16584+ int ret;
2380c486 16585+
4bf69007
AM
16586+ ret = __user_device(device_path, &device, &device_mode);
16587+ if (ret)
16588+ return ret;
16589+ ret = __user_device(target_path, &target, &target_mode);
16590+ if (ret)
16591+ return ret;
2380c486 16592+
4bf69007
AM
16593+ ret = __mapping_mode(device, target,
16594+ device_mode, target_mode, &mode);
16595+ if (ret)
16596+ return ret;
2380c486 16597+
4bf69007
AM
16598+ if (set)
16599+ return do_set_mapping(vxi, device, target,
16600+ flags, mode);
16601+ else
16602+ return do_unset_mapping(vxi, device, target,
16603+ flags, mode);
d337f35e
JR
16604+}
16605+
d337f35e 16606+
4bf69007
AM
16607+int vc_set_mapping(struct vx_info *vxi, void __user *data)
16608+{
16609+ struct vcmd_set_mapping_v0 vc_data;
d337f35e 16610+
4bf69007
AM
16611+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16612+ return -EFAULT;
d337f35e 16613+
4bf69007
AM
16614+ return do_mapping(vxi, vc_data.device, vc_data.target,
16615+ vc_data.flags, 1);
16616+}
d337f35e 16617+
4bf69007 16618+int vc_unset_mapping(struct vx_info *vxi, void __user *data)
d337f35e 16619+{
4bf69007 16620+ struct vcmd_set_mapping_v0 vc_data;
d337f35e 16621+
4bf69007
AM
16622+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16623+ return -EFAULT;
16624+
16625+ return do_mapping(vxi, vc_data.device, vc_data.target,
16626+ vc_data.flags, 0);
d337f35e
JR
16627+}
16628+
16629+
4bf69007
AM
16630+#ifdef CONFIG_COMPAT
16631+
16632+int vc_set_mapping_x32(struct vx_info *vxi, void __user *data)
d337f35e 16633+{
4bf69007 16634+ struct vcmd_set_mapping_v0_x32 vc_data;
d337f35e 16635+
4bf69007
AM
16636+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16637+ return -EFAULT;
16638+
16639+ return do_mapping(vxi, compat_ptr(vc_data.device_ptr),
16640+ compat_ptr(vc_data.target_ptr), vc_data.flags, 1);
d337f35e
JR
16641+}
16642+
4bf69007
AM
16643+int vc_unset_mapping_x32(struct vx_info *vxi, void __user *data)
16644+{
16645+ struct vcmd_set_mapping_v0_x32 vc_data;
16646+
16647+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16648+ return -EFAULT;
d337f35e 16649+
4bf69007
AM
16650+ return do_mapping(vxi, compat_ptr(vc_data.device_ptr),
16651+ compat_ptr(vc_data.target_ptr), vc_data.flags, 0);
16652+}
d337f35e 16653+
4bf69007 16654+#endif /* CONFIG_COMPAT */
d337f35e 16655+
4bf69007 16656+
8de2f54c 16657diff -NurpP --minimal linux-4.4.111/kernel/vserver/dlimit.c linux-4.4.111-vs2.3.9.5/kernel/vserver/dlimit.c
f19bd705 16658--- linux-4.4.111/kernel/vserver/dlimit.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 16659+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/dlimit.c 2018-01-09 16:36:34.000000000 +0000
b00e13aa 16660@@ -0,0 +1,528 @@
d337f35e 16661+/*
4bf69007 16662+ * linux/kernel/vserver/dlimit.c
d337f35e 16663+ *
4bf69007 16664+ * Virtual Server: Context Disk Limits
d337f35e 16665+ *
927ca606 16666+ * Copyright (C) 2004-2009 Herbert P?tzl
d337f35e 16667+ *
4bf69007
AM
16668+ * V0.01 initial version
16669+ * V0.02 compat32 splitup
16670+ * V0.03 extended interface
d337f35e
JR
16671+ *
16672+ */
16673+
4bf69007
AM
16674+#include <linux/statfs.h>
16675+#include <linux/sched.h>
2380c486 16676+#include <linux/namei.h>
d337f35e 16677+#include <linux/vs_tag.h>
4bf69007
AM
16678+#include <linux/vs_dlimit.h>
16679+#include <linux/vserver/dlimit_cmd.h>
16680+#include <linux/slab.h>
16681+// #include <linux/gfp.h>
d337f35e 16682+
d337f35e
JR
16683+#include <asm/uaccess.h>
16684+
4bf69007 16685+/* __alloc_dl_info()
d337f35e 16686+
4bf69007
AM
16687+ * allocate an initialized dl_info struct
16688+ * doesn't make it visible (hash) */
d337f35e 16689+
61333608 16690+static struct dl_info *__alloc_dl_info(struct super_block *sb, vtag_t tag)
4bf69007
AM
16691+{
16692+ struct dl_info *new = NULL;
d337f35e 16693+
4bf69007
AM
16694+ vxdprintk(VXD_CBIT(dlim, 5),
16695+ "alloc_dl_info(%p,%d)*", sb, tag);
d337f35e 16696+
4bf69007
AM
16697+ /* would this benefit from a slab cache? */
16698+ new = kmalloc(sizeof(struct dl_info), GFP_KERNEL);
16699+ if (!new)
16700+ return 0;
d337f35e 16701+
4bf69007
AM
16702+ memset(new, 0, sizeof(struct dl_info));
16703+ new->dl_tag = tag;
16704+ new->dl_sb = sb;
16705+ // INIT_RCU_HEAD(&new->dl_rcu);
16706+ INIT_HLIST_NODE(&new->dl_hlist);
16707+ spin_lock_init(&new->dl_lock);
16708+ atomic_set(&new->dl_refcnt, 0);
16709+ atomic_set(&new->dl_usecnt, 0);
d337f35e 16710+
4bf69007 16711+ /* rest of init goes here */
d337f35e 16712+
4bf69007
AM
16713+ vxdprintk(VXD_CBIT(dlim, 4),
16714+ "alloc_dl_info(%p,%d) = %p", sb, tag, new);
16715+ return new;
16716+}
d4263eb0 16717+
4bf69007 16718+/* __dealloc_dl_info()
d337f35e 16719+
4bf69007 16720+ * final disposal of dl_info */
d337f35e 16721+
4bf69007 16722+static void __dealloc_dl_info(struct dl_info *dli)
adc1caaa 16723+{
4bf69007
AM
16724+ vxdprintk(VXD_CBIT(dlim, 4),
16725+ "dealloc_dl_info(%p)", dli);
2380c486 16726+
4bf69007
AM
16727+ dli->dl_hlist.next = LIST_POISON1;
16728+ dli->dl_tag = -1;
16729+ dli->dl_sb = 0;
2380c486 16730+
4bf69007
AM
16731+ BUG_ON(atomic_read(&dli->dl_usecnt));
16732+ BUG_ON(atomic_read(&dli->dl_refcnt));
2380c486 16733+
4bf69007 16734+ kfree(dli);
adc1caaa 16735+}
2380c486 16736+
2380c486 16737+
4bf69007 16738+/* hash table for dl_info hash */
2380c486 16739+
4bf69007 16740+#define DL_HASH_SIZE 13
2380c486 16741+
4bf69007 16742+struct hlist_head dl_info_hash[DL_HASH_SIZE];
2380c486 16743+
4bf69007 16744+static DEFINE_SPINLOCK(dl_info_hash_lock);
2380c486 16745+
d33d7b00 16746+
61333608 16747+static inline unsigned int __hashval(struct super_block *sb, vtag_t tag)
adc1caaa 16748+{
4bf69007
AM
16749+ return ((tag ^ (unsigned long)sb) % DL_HASH_SIZE);
16750+}
2380c486 16751+
2380c486 16752+
2380c486 16753+
4bf69007 16754+/* __hash_dl_info()
2380c486 16755+
4bf69007
AM
16756+ * add the dli to the global hash table
16757+ * requires the hash_lock to be held */
2380c486 16758+
4bf69007
AM
16759+static inline void __hash_dl_info(struct dl_info *dli)
16760+{
16761+ struct hlist_head *head;
d337f35e 16762+
4bf69007
AM
16763+ vxdprintk(VXD_CBIT(dlim, 6),
16764+ "__hash_dl_info: %p[#%d]", dli, dli->dl_tag);
16765+ get_dl_info(dli);
16766+ head = &dl_info_hash[__hashval(dli->dl_sb, dli->dl_tag)];
16767+ hlist_add_head_rcu(&dli->dl_hlist, head);
16768+}
d337f35e 16769+
4bf69007 16770+/* __unhash_dl_info()
3bac966d 16771+
4bf69007
AM
16772+ * remove the dli from the global hash table
16773+ * requires the hash_lock to be held */
3bac966d 16774+
4bf69007
AM
16775+static inline void __unhash_dl_info(struct dl_info *dli)
16776+{
16777+ vxdprintk(VXD_CBIT(dlim, 6),
16778+ "__unhash_dl_info: %p[#%d]", dli, dli->dl_tag);
16779+ hlist_del_rcu(&dli->dl_hlist);
16780+ put_dl_info(dli);
16781+}
3bac966d 16782+
3bac966d 16783+
4bf69007 16784+/* __lookup_dl_info()
3bac966d 16785+
4bf69007
AM
16786+ * requires the rcu_read_lock()
16787+ * doesn't increment the dl_refcnt */
3bac966d 16788+
61333608 16789+static inline struct dl_info *__lookup_dl_info(struct super_block *sb, vtag_t tag)
4bf69007
AM
16790+{
16791+ struct hlist_head *head = &dl_info_hash[__hashval(sb, tag)];
4bf69007 16792+ struct dl_info *dli;
3bac966d 16793+
b00e13aa
AM
16794+ hlist_for_each_entry_rcu(dli, head, dl_hlist) {
16795+ if (dli->dl_tag == tag && dli->dl_sb == sb)
4bf69007 16796+ return dli;
d33d7b00 16797+ }
4bf69007
AM
16798+ return NULL;
16799+}
3bac966d 16800+
3bac966d 16801+
61333608 16802+struct dl_info *locate_dl_info(struct super_block *sb, vtag_t tag)
4bf69007
AM
16803+{
16804+ struct dl_info *dli;
16805+
16806+ rcu_read_lock();
16807+ dli = get_dl_info(__lookup_dl_info(sb, tag));
16808+ vxdprintk(VXD_CBIT(dlim, 7),
16809+ "locate_dl_info(%p,#%d) = %p", sb, tag, dli);
16810+ rcu_read_unlock();
16811+ return dli;
d33d7b00 16812+}
3bac966d 16813+
4bf69007 16814+void rcu_free_dl_info(struct rcu_head *head)
d33d7b00 16815+{
4bf69007
AM
16816+ struct dl_info *dli = container_of(head, struct dl_info, dl_rcu);
16817+ int usecnt, refcnt;
3bac966d 16818+
4bf69007 16819+ BUG_ON(!dli || !head);
3bac966d 16820+
4bf69007
AM
16821+ usecnt = atomic_read(&dli->dl_usecnt);
16822+ BUG_ON(usecnt < 0);
3bac966d 16823+
4bf69007
AM
16824+ refcnt = atomic_read(&dli->dl_refcnt);
16825+ BUG_ON(refcnt < 0);
16826+
16827+ vxdprintk(VXD_CBIT(dlim, 3),
16828+ "rcu_free_dl_info(%p)", dli);
16829+ if (!usecnt)
16830+ __dealloc_dl_info(dli);
16831+ else
16832+ printk("!!! rcu didn't free\n");
d33d7b00 16833+}
3bac966d 16834+
3bac966d 16835+
4bf69007
AM
16836+
16837+
16838+static int do_addrem_dlimit(uint32_t id, const char __user *name,
16839+ uint32_t flags, int add)
d33d7b00
AM
16840+{
16841+ struct path path;
d33d7b00 16842+ int ret;
3bac966d 16843+
4bf69007 16844+ ret = user_lpath(name, &path);
d33d7b00 16845+ if (!ret) {
4bf69007
AM
16846+ struct super_block *sb;
16847+ struct dl_info *dli;
16848+
16849+ ret = -EINVAL;
16850+ if (!path.dentry->d_inode)
16851+ goto out_release;
16852+ if (!(sb = path.dentry->d_inode->i_sb))
16853+ goto out_release;
16854+
16855+ if (add) {
16856+ dli = __alloc_dl_info(sb, id);
16857+ spin_lock(&dl_info_hash_lock);
16858+
16859+ ret = -EEXIST;
16860+ if (__lookup_dl_info(sb, id))
16861+ goto out_unlock;
16862+ __hash_dl_info(dli);
16863+ dli = NULL;
16864+ } else {
16865+ spin_lock(&dl_info_hash_lock);
16866+ dli = __lookup_dl_info(sb, id);
16867+
16868+ ret = -ESRCH;
16869+ if (!dli)
16870+ goto out_unlock;
16871+ __unhash_dl_info(dli);
16872+ }
16873+ ret = 0;
16874+ out_unlock:
16875+ spin_unlock(&dl_info_hash_lock);
16876+ if (add && dli)
16877+ __dealloc_dl_info(dli);
16878+ out_release:
d33d7b00
AM
16879+ path_put(&path);
16880+ }
d33d7b00
AM
16881+ return ret;
16882+}
3bac966d 16883+
4bf69007 16884+int vc_add_dlimit(uint32_t id, void __user *data)
d33d7b00 16885+{
4bf69007 16886+ struct vcmd_ctx_dlimit_base_v0 vc_data;
3bac966d 16887+
d33d7b00
AM
16888+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16889+ return -EFAULT;
3bac966d 16890+
4bf69007
AM
16891+ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 1);
16892+}
3bac966d 16893+
4bf69007
AM
16894+int vc_rem_dlimit(uint32_t id, void __user *data)
16895+{
16896+ struct vcmd_ctx_dlimit_base_v0 vc_data;
3bac966d 16897+
4bf69007 16898+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d33d7b00 16899+ return -EFAULT;
4bf69007
AM
16900+
16901+ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 0);
d33d7b00 16902+}
3bac966d 16903+
4bf69007 16904+#ifdef CONFIG_COMPAT
3bac966d 16905+
4bf69007
AM
16906+int vc_add_dlimit_x32(uint32_t id, void __user *data)
16907+{
16908+ struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
3bac966d 16909+
4bf69007
AM
16910+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16911+ return -EFAULT;
d337f35e 16912+
4bf69007
AM
16913+ return do_addrem_dlimit(id,
16914+ compat_ptr(vc_data.name_ptr), vc_data.flags, 1);
16915+}
d337f35e 16916+
4bf69007 16917+int vc_rem_dlimit_x32(uint32_t id, void __user *data)
d33d7b00 16918+{
4bf69007 16919+ struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
d337f35e 16920+
4bf69007
AM
16921+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16922+ return -EFAULT;
16923+
16924+ return do_addrem_dlimit(id,
16925+ compat_ptr(vc_data.name_ptr), vc_data.flags, 0);
d33d7b00 16926+}
d337f35e 16927+
4bf69007
AM
16928+#endif /* CONFIG_COMPAT */
16929+
16930+
16931+static inline
16932+int do_set_dlimit(uint32_t id, const char __user *name,
16933+ uint32_t space_used, uint32_t space_total,
16934+ uint32_t inodes_used, uint32_t inodes_total,
16935+ uint32_t reserved, uint32_t flags)
d33d7b00 16936+{
4bf69007
AM
16937+ struct path path;
16938+ int ret;
ba86f833 16939+
4bf69007
AM
16940+ ret = user_lpath(name, &path);
16941+ if (!ret) {
16942+ struct super_block *sb;
16943+ struct dl_info *dli;
d337f35e 16944+
4bf69007
AM
16945+ ret = -EINVAL;
16946+ if (!path.dentry->d_inode)
16947+ goto out_release;
16948+ if (!(sb = path.dentry->d_inode->i_sb))
16949+ goto out_release;
d337f35e 16950+
4bf69007
AM
16951+ /* sanity checks */
16952+ if ((reserved != CDLIM_KEEP &&
16953+ reserved > 100) ||
16954+ (inodes_used != CDLIM_KEEP &&
16955+ inodes_used > inodes_total) ||
16956+ (space_used != CDLIM_KEEP &&
16957+ space_used > space_total))
16958+ goto out_release;
d337f35e 16959+
4bf69007
AM
16960+ ret = -ESRCH;
16961+ dli = locate_dl_info(sb, id);
16962+ if (!dli)
16963+ goto out_release;
ba86f833 16964+
4bf69007 16965+ spin_lock(&dli->dl_lock);
d337f35e 16966+
4bf69007
AM
16967+ if (inodes_used != CDLIM_KEEP)
16968+ dli->dl_inodes_used = inodes_used;
16969+ if (inodes_total != CDLIM_KEEP)
16970+ dli->dl_inodes_total = inodes_total;
16971+ if (space_used != CDLIM_KEEP)
16972+ dli->dl_space_used = dlimit_space_32to64(
16973+ space_used, flags, DLIMS_USED);
d337f35e 16974+
4bf69007
AM
16975+ if (space_total == CDLIM_INFINITY)
16976+ dli->dl_space_total = DLIM_INFINITY;
16977+ else if (space_total != CDLIM_KEEP)
16978+ dli->dl_space_total = dlimit_space_32to64(
16979+ space_total, flags, DLIMS_TOTAL);
78865d5b 16980+
4bf69007
AM
16981+ if (reserved != CDLIM_KEEP)
16982+ dli->dl_nrlmult = (1 << 10) * (100 - reserved) / 100;
78865d5b 16983+
4bf69007 16984+ spin_unlock(&dli->dl_lock);
d337f35e 16985+
4bf69007
AM
16986+ put_dl_info(dli);
16987+ ret = 0;
d337f35e 16988+
4bf69007
AM
16989+ out_release:
16990+ path_put(&path);
16991+ }
16992+ return ret;
16993+}
d337f35e 16994+
4bf69007
AM
16995+int vc_set_dlimit(uint32_t id, void __user *data)
16996+{
16997+ struct vcmd_ctx_dlimit_v0 vc_data;
d337f35e 16998+
4bf69007
AM
16999+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17000+ return -EFAULT;
d337f35e 17001+
4bf69007
AM
17002+ return do_set_dlimit(id, vc_data.name,
17003+ vc_data.space_used, vc_data.space_total,
17004+ vc_data.inodes_used, vc_data.inodes_total,
17005+ vc_data.reserved, vc_data.flags);
17006+}
d337f35e 17007+
4bf69007 17008+#ifdef CONFIG_COMPAT
d337f35e 17009+
4bf69007
AM
17010+int vc_set_dlimit_x32(uint32_t id, void __user *data)
17011+{
17012+ struct vcmd_ctx_dlimit_v0_x32 vc_data;
d337f35e 17013+
4bf69007
AM
17014+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17015+ return -EFAULT;
d337f35e 17016+
4bf69007
AM
17017+ return do_set_dlimit(id, compat_ptr(vc_data.name_ptr),
17018+ vc_data.space_used, vc_data.space_total,
17019+ vc_data.inodes_used, vc_data.inodes_total,
17020+ vc_data.reserved, vc_data.flags);
17021+}
d337f35e 17022+
4bf69007 17023+#endif /* CONFIG_COMPAT */
d337f35e 17024+
d337f35e 17025+
4bf69007
AM
17026+static inline
17027+int do_get_dlimit(uint32_t id, const char __user *name,
17028+ uint32_t *space_used, uint32_t *space_total,
17029+ uint32_t *inodes_used, uint32_t *inodes_total,
17030+ uint32_t *reserved, uint32_t *flags)
17031+{
17032+ struct path path;
17033+ int ret;
d337f35e 17034+
4bf69007
AM
17035+ ret = user_lpath(name, &path);
17036+ if (!ret) {
17037+ struct super_block *sb;
17038+ struct dl_info *dli;
d337f35e 17039+
4bf69007
AM
17040+ ret = -EINVAL;
17041+ if (!path.dentry->d_inode)
17042+ goto out_release;
17043+ if (!(sb = path.dentry->d_inode->i_sb))
17044+ goto out_release;
d337f35e 17045+
4bf69007
AM
17046+ ret = -ESRCH;
17047+ dli = locate_dl_info(sb, id);
17048+ if (!dli)
17049+ goto out_release;
d337f35e 17050+
4bf69007
AM
17051+ spin_lock(&dli->dl_lock);
17052+ *inodes_used = dli->dl_inodes_used;
17053+ *inodes_total = dli->dl_inodes_total;
d337f35e 17054+
4bf69007
AM
17055+ *space_used = dlimit_space_64to32(
17056+ dli->dl_space_used, flags, DLIMS_USED);
d337f35e 17057+
4bf69007
AM
17058+ if (dli->dl_space_total == DLIM_INFINITY)
17059+ *space_total = CDLIM_INFINITY;
17060+ else
17061+ *space_total = dlimit_space_64to32(
17062+ dli->dl_space_total, flags, DLIMS_TOTAL);
d337f35e 17063+
4bf69007
AM
17064+ *reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10);
17065+ spin_unlock(&dli->dl_lock);
d337f35e 17066+
4bf69007
AM
17067+ put_dl_info(dli);
17068+ ret = -EFAULT;
d337f35e 17069+
4bf69007
AM
17070+ ret = 0;
17071+ out_release:
17072+ path_put(&path);
17073+ }
17074+ return ret;
d337f35e
JR
17075+}
17076+
4bf69007
AM
17077+
17078+int vc_get_dlimit(uint32_t id, void __user *data)
d337f35e 17079+{
4bf69007 17080+ struct vcmd_ctx_dlimit_v0 vc_data;
d337f35e
JR
17081+ int ret;
17082+
2380c486 17083+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
17084+ return -EFAULT;
17085+
4bf69007
AM
17086+ ret = do_get_dlimit(id, vc_data.name,
17087+ &vc_data.space_used, &vc_data.space_total,
17088+ &vc_data.inodes_used, &vc_data.inodes_total,
17089+ &vc_data.reserved, &vc_data.flags);
d337f35e
JR
17090+ if (ret)
17091+ return ret;
17092+
2380c486 17093+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
d337f35e
JR
17094+ return -EFAULT;
17095+ return 0;
17096+}
17097+
4bf69007 17098+#ifdef CONFIG_COMPAT
d337f35e 17099+
4bf69007 17100+int vc_get_dlimit_x32(uint32_t id, void __user *data)
d337f35e 17101+{
4bf69007 17102+ struct vcmd_ctx_dlimit_v0_x32 vc_data;
d337f35e
JR
17103+ int ret;
17104+
2380c486 17105+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
17106+ return -EFAULT;
17107+
4bf69007
AM
17108+ ret = do_get_dlimit(id, compat_ptr(vc_data.name_ptr),
17109+ &vc_data.space_used, &vc_data.space_total,
17110+ &vc_data.inodes_used, &vc_data.inodes_total,
17111+ &vc_data.reserved, &vc_data.flags);
d337f35e
JR
17112+ if (ret)
17113+ return ret;
17114+
2380c486 17115+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
d337f35e
JR
17116+ return -EFAULT;
17117+ return 0;
17118+}
17119+
4bf69007 17120+#endif /* CONFIG_COMPAT */
ec22aa5c
AM
17121+
17122+
4bf69007 17123+void vx_vsi_statfs(struct super_block *sb, struct kstatfs *buf)
ec22aa5c 17124+{
4bf69007
AM
17125+ struct dl_info *dli;
17126+ __u64 blimit, bfree, bavail;
17127+ __u32 ifree;
ec22aa5c 17128+
4bf69007
AM
17129+ dli = locate_dl_info(sb, dx_current_tag());
17130+ if (!dli)
17131+ return;
ec22aa5c 17132+
4bf69007
AM
17133+ spin_lock(&dli->dl_lock);
17134+ if (dli->dl_inodes_total == (unsigned long)DLIM_INFINITY)
17135+ goto no_ilim;
ec22aa5c 17136+
4bf69007
AM
17137+ /* reduce max inodes available to limit */
17138+ if (buf->f_files > dli->dl_inodes_total)
17139+ buf->f_files = dli->dl_inodes_total;
ec22aa5c 17140+
4bf69007
AM
17141+ ifree = dli->dl_inodes_total - dli->dl_inodes_used;
17142+ /* reduce free inodes to min */
17143+ if (ifree < buf->f_ffree)
17144+ buf->f_ffree = ifree;
b2252bc2 17145+
4bf69007
AM
17146+no_ilim:
17147+ if (dli->dl_space_total == DLIM_INFINITY)
17148+ goto no_blim;
d337f35e 17149+
4bf69007 17150+ blimit = dli->dl_space_total >> sb->s_blocksize_bits;
d337f35e 17151+
4bf69007
AM
17152+ if (dli->dl_space_total < dli->dl_space_used)
17153+ bfree = 0;
17154+ else
17155+ bfree = (dli->dl_space_total - dli->dl_space_used)
17156+ >> sb->s_blocksize_bits;
d337f35e 17157+
4bf69007
AM
17158+ bavail = ((dli->dl_space_total >> 10) * dli->dl_nrlmult);
17159+ if (bavail < dli->dl_space_used)
17160+ bavail = 0;
17161+ else
17162+ bavail = (bavail - dli->dl_space_used)
17163+ >> sb->s_blocksize_bits;
d337f35e 17164+
4bf69007
AM
17165+ /* reduce max space available to limit */
17166+ if (buf->f_blocks > blimit)
17167+ buf->f_blocks = blimit;
d337f35e 17168+
4bf69007
AM
17169+ /* reduce free space to min */
17170+ if (bfree < buf->f_bfree)
17171+ buf->f_bfree = bfree;
d337f35e 17172+
4bf69007
AM
17173+ /* reduce avail space to min */
17174+ if (bavail < buf->f_bavail)
17175+ buf->f_bavail = bavail;
d337f35e 17176+
4bf69007
AM
17177+no_blim:
17178+ spin_unlock(&dli->dl_lock);
17179+ put_dl_info(dli);
d337f35e 17180+
4bf69007 17181+ return;
d337f35e
JR
17182+}
17183+
4bf69007 17184+#include <linux/module.h>
d337f35e 17185+
4bf69007
AM
17186+EXPORT_SYMBOL_GPL(locate_dl_info);
17187+EXPORT_SYMBOL_GPL(rcu_free_dl_info);
e3afe727 17188+
8de2f54c 17189diff -NurpP --minimal linux-4.4.111/kernel/vserver/helper.c linux-4.4.111-vs2.3.9.5/kernel/vserver/helper.c
f19bd705 17190--- linux-4.4.111/kernel/vserver/helper.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 17191+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/helper.c 2018-01-09 16:36:34.000000000 +0000
09be7631 17192@@ -0,0 +1,242 @@
4bf69007
AM
17193+/*
17194+ * linux/kernel/vserver/helper.c
17195+ *
17196+ * Virtual Context Support
17197+ *
927ca606 17198+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
17199+ *
17200+ * V0.01 basic helper
17201+ *
17202+ */
e3afe727 17203+
4bf69007
AM
17204+#include <linux/kmod.h>
17205+#include <linux/reboot.h>
17206+#include <linux/vs_context.h>
17207+#include <linux/vs_network.h>
17208+#include <linux/vserver/signal.h>
e3afe727 17209+
4bf69007
AM
17210+
17211+char vshelper_path[255] = "/sbin/vshelper";
17212+
17213+static int vshelper_init(struct subprocess_info *info, struct cred *new_cred)
17214+{
09be7631 17215+ current->flags &= ~PF_NO_SETAFFINITY;
4bf69007 17216+ return 0;
d337f35e
JR
17217+}
17218+
09be7631
JR
17219+static int vs_call_usermodehelper(char *path, char **argv, char **envp, int wait)
17220+{
17221+ struct subprocess_info *info;
17222+ gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
17223+
17224+ info = call_usermodehelper_setup(path, argv, envp, gfp_mask,
17225+ vshelper_init, NULL, NULL);
17226+ if (info == NULL)
17227+ return -ENOMEM;
17228+
17229+ return call_usermodehelper_exec(info, wait);
17230+}
17231+
4bf69007 17232+static int do_vshelper(char *name, char *argv[], char *envp[], int sync)
d337f35e 17233+{
4bf69007 17234+ int ret;
e3afe727 17235+
09be7631
JR
17236+ if ((ret = vs_call_usermodehelper(name, argv, envp,
17237+ sync ? UMH_WAIT_PROC : UMH_WAIT_EXEC))) {
4bf69007
AM
17238+ printk(KERN_WARNING "%s: (%s %s) returned %s with %d\n",
17239+ name, argv[1], argv[2],
17240+ sync ? "sync" : "async", ret);
17241+ }
17242+ vxdprintk(VXD_CBIT(switch, 4),
17243+ "%s: (%s %s) returned %s with %d",
17244+ name, argv[1], argv[2], sync ? "sync" : "async", ret);
17245+ return ret;
17246+}
e3afe727 17247+
4bf69007
AM
17248+/*
17249+ * vshelper path is set via /proc/sys
17250+ * invoked by vserver sys_reboot(), with
17251+ * the following arguments
17252+ *
17253+ * argv [0] = vshelper_path;
17254+ * argv [1] = action: "restart", "halt", "poweroff", ...
17255+ * argv [2] = context identifier
17256+ *
17257+ * envp [*] = type-specific parameters
17258+ */
e3afe727 17259+
4bf69007
AM
17260+long vs_reboot_helper(struct vx_info *vxi, int cmd, void __user *arg)
17261+{
17262+ char id_buf[8], cmd_buf[16];
17263+ char uid_buf[16], pid_buf[16];
17264+ int ret;
e3afe727 17265+
4bf69007
AM
17266+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
17267+ char *envp[] = {"HOME=/", "TERM=linux",
17268+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
17269+ uid_buf, pid_buf, cmd_buf, 0};
e3afe727 17270+
4bf69007
AM
17271+ if (vx_info_state(vxi, VXS_HELPER))
17272+ return -EAGAIN;
17273+ vxi->vx_state |= VXS_HELPER;
7b17263b 17274+
4bf69007 17275+ snprintf(id_buf, sizeof(id_buf), "%d", vxi->vx_id);
d337f35e 17276+
4bf69007 17277+ snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
8ce283e1
AM
17278+ snprintf(uid_buf, sizeof(uid_buf), "VS_UID=%d",
17279+ from_kuid(&init_user_ns, current_uid()));
4bf69007 17280+ snprintf(pid_buf, sizeof(pid_buf), "VS_PID=%d", current->pid);
e3afe727 17281+
4bf69007
AM
17282+ switch (cmd) {
17283+ case LINUX_REBOOT_CMD_RESTART:
17284+ argv[1] = "restart";
17285+ break;
07a627a5 17286+
4bf69007
AM
17287+ case LINUX_REBOOT_CMD_HALT:
17288+ argv[1] = "halt";
17289+ break;
e3afe727 17290+
4bf69007
AM
17291+ case LINUX_REBOOT_CMD_POWER_OFF:
17292+ argv[1] = "poweroff";
17293+ break;
d337f35e 17294+
4bf69007
AM
17295+ case LINUX_REBOOT_CMD_SW_SUSPEND:
17296+ argv[1] = "swsusp";
17297+ break;
d337f35e 17298+
4bf69007
AM
17299+ case LINUX_REBOOT_CMD_OOM:
17300+ argv[1] = "oom";
17301+ break;
d337f35e 17302+
4bf69007
AM
17303+ default:
17304+ vxi->vx_state &= ~VXS_HELPER;
17305+ return 0;
d337f35e 17306+ }
4bf69007
AM
17307+
17308+ ret = do_vshelper(vshelper_path, argv, envp, 0);
17309+ vxi->vx_state &= ~VXS_HELPER;
17310+ __wakeup_vx_info(vxi);
17311+ return (ret) ? -EPERM : 0;
d337f35e
JR
17312+}
17313+
4bf69007
AM
17314+
17315+long vs_reboot(unsigned int cmd, void __user *arg)
d337f35e 17316+{
4bf69007
AM
17317+ struct vx_info *vxi = current_vx_info();
17318+ long ret = 0;
d337f35e 17319+
4bf69007
AM
17320+ vxdprintk(VXD_CBIT(misc, 5),
17321+ "vs_reboot(%p[#%d],%u)",
17322+ vxi, vxi ? vxi->vx_id : 0, cmd);
17323+
17324+ ret = vs_reboot_helper(vxi, cmd, arg);
17325+ if (ret)
17326+ return ret;
17327+
17328+ vxi->reboot_cmd = cmd;
17329+ if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
17330+ switch (cmd) {
17331+ case LINUX_REBOOT_CMD_RESTART:
17332+ case LINUX_REBOOT_CMD_HALT:
17333+ case LINUX_REBOOT_CMD_POWER_OFF:
17334+ vx_info_kill(vxi, 0, SIGKILL);
17335+ vx_info_kill(vxi, 1, SIGKILL);
17336+ default:
17337+ break;
17338+ }
d337f35e 17339+ }
4bf69007 17340+ return 0;
d337f35e
JR
17341+}
17342+
4bf69007
AM
17343+long vs_oom_action(unsigned int cmd)
17344+{
17345+ struct vx_info *vxi = current_vx_info();
17346+ long ret = 0;
d337f35e 17347+
4bf69007
AM
17348+ vxdprintk(VXD_CBIT(misc, 5),
17349+ "vs_oom_action(%p[#%d],%u)",
17350+ vxi, vxi ? vxi->vx_id : 0, cmd);
d337f35e 17351+
4bf69007
AM
17352+ ret = vs_reboot_helper(vxi, cmd, NULL);
17353+ if (ret)
17354+ return ret;
d337f35e 17355+
4bf69007
AM
17356+ vxi->reboot_cmd = cmd;
17357+ if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
17358+ vx_info_kill(vxi, 0, SIGKILL);
17359+ vx_info_kill(vxi, 1, SIGKILL);
17360+ }
17361+ return 0;
17362+}
d337f35e 17363+
4bf69007
AM
17364+/*
17365+ * argv [0] = vshelper_path;
17366+ * argv [1] = action: "startup", "shutdown"
17367+ * argv [2] = context identifier
17368+ *
17369+ * envp [*] = type-specific parameters
17370+ */
d337f35e 17371+
4bf69007 17372+long vs_state_change(struct vx_info *vxi, unsigned int cmd)
d337f35e 17373+{
4bf69007
AM
17374+ char id_buf[8], cmd_buf[16];
17375+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
17376+ char *envp[] = {"HOME=/", "TERM=linux",
17377+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
17378+
17379+ if (!vx_info_flags(vxi, VXF_SC_HELPER, 0))
17380+ return 0;
17381+
17382+ snprintf(id_buf, sizeof(id_buf), "%d", vxi->vx_id);
17383+ snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
17384+
17385+ switch (cmd) {
17386+ case VSC_STARTUP:
17387+ argv[1] = "startup";
17388+ break;
17389+ case VSC_SHUTDOWN:
17390+ argv[1] = "shutdown";
17391+ break;
17392+ default:
17393+ return 0;
17394+ }
17395+
17396+ return do_vshelper(vshelper_path, argv, envp, 1);
d337f35e
JR
17397+}
17398+
d337f35e 17399+
4bf69007
AM
17400+/*
17401+ * argv [0] = vshelper_path;
17402+ * argv [1] = action: "netup", "netdown"
17403+ * argv [2] = context identifier
17404+ *
17405+ * envp [*] = type-specific parameters
17406+ */
17407+
17408+long vs_net_change(struct nx_info *nxi, unsigned int cmd)
17409+{
17410+ char id_buf[8], cmd_buf[16];
17411+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
17412+ char *envp[] = {"HOME=/", "TERM=linux",
17413+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
17414+
17415+ if (!nx_info_flags(nxi, NXF_SC_HELPER, 0))
17416+ return 0;
17417+
17418+ snprintf(id_buf, sizeof(id_buf), "%d", nxi->nx_id);
17419+ snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
17420+
17421+ switch (cmd) {
17422+ case VSC_NETUP:
17423+ argv[1] = "netup";
17424+ break;
17425+ case VSC_NETDOWN:
17426+ argv[1] = "netdown";
17427+ break;
17428+ default:
17429+ return 0;
17430+ }
17431+
17432+ return do_vshelper(vshelper_path, argv, envp, 1);
17433+}
d337f35e 17434+
8de2f54c 17435diff -NurpP --minimal linux-4.4.111/kernel/vserver/history.c linux-4.4.111-vs2.3.9.5/kernel/vserver/history.c
f19bd705 17436--- linux-4.4.111/kernel/vserver/history.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 17437+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/history.c 2018-01-09 16:36:34.000000000 +0000
4bf69007 17438@@ -0,0 +1,258 @@
d337f35e 17439+/*
4bf69007 17440+ * kernel/vserver/history.c
d337f35e 17441+ *
4bf69007 17442+ * Virtual Context History Backtrace
d337f35e 17443+ *
927ca606 17444+ * Copyright (C) 2004-2007 Herbert P?tzl
d337f35e 17445+ *
4bf69007
AM
17446+ * V0.01 basic structure
17447+ * V0.02 hash/unhash and trace
17448+ * V0.03 preemption fixes
d337f35e
JR
17449+ *
17450+ */
17451+
4bf69007
AM
17452+#include <linux/module.h>
17453+#include <asm/uaccess.h>
d337f35e 17454+
4bf69007
AM
17455+#include <linux/vserver/context.h>
17456+#include <linux/vserver/debug.h>
17457+#include <linux/vserver/debug_cmd.h>
17458+#include <linux/vserver/history.h>
d337f35e
JR
17459+
17460+
4bf69007
AM
17461+#ifdef CONFIG_VSERVER_HISTORY
17462+#define VXH_SIZE CONFIG_VSERVER_HISTORY_SIZE
17463+#else
17464+#define VXH_SIZE 64
17465+#endif
d337f35e 17466+
4bf69007
AM
17467+struct _vx_history {
17468+ unsigned int counter;
2380c486 17469+
4bf69007
AM
17470+ struct _vx_hist_entry entry[VXH_SIZE + 1];
17471+};
2380c486 17472+
2380c486 17473+
4bf69007 17474+DEFINE_PER_CPU(struct _vx_history, vx_history_buffer);
2380c486 17475+
4bf69007 17476+unsigned volatile int vxh_active = 1;
2380c486 17477+
4bf69007 17478+static atomic_t sequence = ATOMIC_INIT(0);
2380c486 17479+
2380c486 17480+
4bf69007 17481+/* vxh_advance()
2380c486 17482+
4bf69007
AM
17483+ * requires disabled preemption */
17484+
17485+struct _vx_hist_entry *vxh_advance(void *loc)
2380c486 17486+{
4bf69007
AM
17487+ unsigned int cpu = smp_processor_id();
17488+ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
17489+ struct _vx_hist_entry *entry;
17490+ unsigned int index;
17491+
17492+ index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE;
17493+ entry = &hist->entry[index];
17494+
17495+ entry->seq = atomic_inc_return(&sequence);
17496+ entry->loc = loc;
17497+ return entry;
2380c486
JR
17498+}
17499+
4bf69007 17500+EXPORT_SYMBOL_GPL(vxh_advance);
2380c486 17501+
2380c486 17502+
4bf69007 17503+#define VXH_LOC_FMTS "(#%04x,*%d):%p"
2380c486 17504+
4bf69007 17505+#define VXH_LOC_ARGS(e) (e)->seq, cpu, (e)->loc
2380c486 17506+
2380c486 17507+
4bf69007 17508+#define VXH_VXI_FMTS "%p[#%d,%d.%d]"
2380c486 17509+
4bf69007
AM
17510+#define VXH_VXI_ARGS(e) (e)->vxi.ptr, \
17511+ (e)->vxi.ptr ? (e)->vxi.xid : 0, \
17512+ (e)->vxi.ptr ? (e)->vxi.usecnt : 0, \
17513+ (e)->vxi.ptr ? (e)->vxi.tasks : 0
17514+
17515+void vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu)
2380c486 17516+{
4bf69007
AM
17517+ switch (e->type) {
17518+ case VXH_THROW_OOPS:
17519+ printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e));
17520+ break;
2380c486 17521+
4bf69007
AM
17522+ case VXH_GET_VX_INFO:
17523+ case VXH_PUT_VX_INFO:
17524+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
17525+ VXH_LOC_ARGS(e),
17526+ (e->type == VXH_GET_VX_INFO) ? "get" : "put",
17527+ VXH_VXI_ARGS(e));
17528+ break;
2380c486 17529+
4bf69007
AM
17530+ case VXH_INIT_VX_INFO:
17531+ case VXH_SET_VX_INFO:
17532+ case VXH_CLR_VX_INFO:
17533+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
17534+ VXH_LOC_ARGS(e),
17535+ (e->type == VXH_INIT_VX_INFO) ? "init" :
17536+ ((e->type == VXH_SET_VX_INFO) ? "set" : "clr"),
17537+ VXH_VXI_ARGS(e), e->sc.data);
17538+ break;
2380c486 17539+
4bf69007
AM
17540+ case VXH_CLAIM_VX_INFO:
17541+ case VXH_RELEASE_VX_INFO:
17542+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
17543+ VXH_LOC_ARGS(e),
17544+ (e->type == VXH_CLAIM_VX_INFO) ? "claim" : "release",
17545+ VXH_VXI_ARGS(e), e->sc.data);
17546+ break;
2380c486 17547+
4bf69007
AM
17548+ case VXH_ALLOC_VX_INFO:
17549+ case VXH_DEALLOC_VX_INFO:
17550+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
17551+ VXH_LOC_ARGS(e),
17552+ (e->type == VXH_ALLOC_VX_INFO) ? "alloc" : "dealloc",
17553+ VXH_VXI_ARGS(e));
17554+ break;
2380c486 17555+
4bf69007
AM
17556+ case VXH_HASH_VX_INFO:
17557+ case VXH_UNHASH_VX_INFO:
17558+ printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n",
17559+ VXH_LOC_ARGS(e),
17560+ (e->type == VXH_HASH_VX_INFO) ? "hash" : "unhash",
17561+ VXH_VXI_ARGS(e));
17562+ break;
2380c486 17563+
4bf69007
AM
17564+ case VXH_LOC_VX_INFO:
17565+ case VXH_LOOKUP_VX_INFO:
17566+ case VXH_CREATE_VX_INFO:
17567+ printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n",
17568+ VXH_LOC_ARGS(e),
17569+ (e->type == VXH_CREATE_VX_INFO) ? "create" :
17570+ ((e->type == VXH_LOC_VX_INFO) ? "loc" : "lookup"),
17571+ e->ll.arg, VXH_VXI_ARGS(e));
17572+ break;
2380c486
JR
17573+ }
17574+}
17575+
4bf69007
AM
17576+static void __vxh_dump_history(void)
17577+{
17578+ unsigned int i, cpu;
d337f35e 17579+
4bf69007
AM
17580+ printk("History:\tSEQ: %8x\tNR_CPUS: %d\n",
17581+ atomic_read(&sequence), NR_CPUS);
d337f35e 17582+
4bf69007
AM
17583+ for (i = 0; i < VXH_SIZE; i++) {
17584+ for_each_online_cpu(cpu) {
17585+ struct _vx_history *hist =
17586+ &per_cpu(vx_history_buffer, cpu);
17587+ unsigned int index = (hist->counter - i) % VXH_SIZE;
17588+ struct _vx_hist_entry *entry = &hist->entry[index];
d337f35e 17589+
4bf69007
AM
17590+ vxh_dump_entry(entry, cpu);
17591+ }
17592+ }
17593+}
d337f35e 17594+
4bf69007
AM
17595+void vxh_dump_history(void)
17596+{
17597+ vxh_active = 0;
17598+#ifdef CONFIG_SMP
17599+ local_irq_enable();
17600+ smp_send_stop();
17601+ local_irq_disable();
17602+#endif
17603+ __vxh_dump_history();
17604+}
d337f35e 17605+
d337f35e 17606+
4bf69007 17607+/* vserver syscall commands below here */
d337f35e 17608+
d337f35e 17609+
4bf69007
AM
17610+int vc_dump_history(uint32_t id)
17611+{
17612+ vxh_active = 0;
17613+ __vxh_dump_history();
17614+ vxh_active = 1;
2380c486 17615+
4bf69007 17616+ return 0;
d337f35e
JR
17617+}
17618+
d337f35e 17619+
4bf69007
AM
17620+int do_read_history(struct __user _vx_hist_entry *data,
17621+ int cpu, uint32_t *index, uint32_t *count)
d337f35e 17622+{
4bf69007
AM
17623+ int pos, ret = 0;
17624+ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
17625+ int end = hist->counter;
17626+ int start = end - VXH_SIZE + 2;
17627+ int idx = *index;
d337f35e 17628+
4bf69007
AM
17629+ /* special case: get current pos */
17630+ if (!*count) {
17631+ *index = end;
17632+ return 0;
17633+ }
d337f35e 17634+
4bf69007
AM
17635+ /* have we lost some data? */
17636+ if (idx < start)
17637+ idx = start;
d337f35e 17638+
4bf69007
AM
17639+ for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) {
17640+ struct _vx_hist_entry *entry =
17641+ &hist->entry[idx % VXH_SIZE];
2380c486 17642+
4bf69007
AM
17643+ /* send entry to userspace */
17644+ ret = copy_to_user(&data[pos], entry, sizeof(*entry));
17645+ if (ret)
17646+ break;
17647+ }
17648+ /* save new index and count */
17649+ *index = idx;
17650+ *count = pos;
17651+ return ret ? ret : (*index < end);
d337f35e
JR
17652+}
17653+
4bf69007 17654+int vc_read_history(uint32_t id, void __user *data)
d337f35e 17655+{
4bf69007
AM
17656+ struct vcmd_read_history_v0 vc_data;
17657+ int ret;
d337f35e 17658+
4bf69007
AM
17659+ if (id >= NR_CPUS)
17660+ return -EINVAL;
d337f35e 17661+
4bf69007
AM
17662+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17663+ return -EFAULT;
d337f35e 17664+
4bf69007
AM
17665+ ret = do_read_history((struct __user _vx_hist_entry *)vc_data.data,
17666+ id, &vc_data.index, &vc_data.count);
d337f35e 17667+
4bf69007
AM
17668+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
17669+ return -EFAULT;
17670+ return ret;
d337f35e
JR
17671+}
17672+
4bf69007 17673+#ifdef CONFIG_COMPAT
d337f35e 17674+
4bf69007 17675+int vc_read_history_x32(uint32_t id, void __user *data)
d337f35e 17676+{
4bf69007
AM
17677+ struct vcmd_read_history_v0_x32 vc_data;
17678+ int ret;
d337f35e 17679+
4bf69007
AM
17680+ if (id >= NR_CPUS)
17681+ return -EINVAL;
d337f35e 17682+
4bf69007
AM
17683+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17684+ return -EFAULT;
2380c486 17685+
4bf69007
AM
17686+ ret = do_read_history((struct __user _vx_hist_entry *)
17687+ compat_ptr(vc_data.data_ptr),
17688+ id, &vc_data.index, &vc_data.count);
d337f35e 17689+
4bf69007
AM
17690+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
17691+ return -EFAULT;
17692+ return ret;
17693+}
d337f35e 17694+
4bf69007 17695+#endif /* CONFIG_COMPAT */
d337f35e 17696+
8de2f54c 17697diff -NurpP --minimal linux-4.4.111/kernel/vserver/inet.c linux-4.4.111-vs2.3.9.5/kernel/vserver/inet.c
f19bd705 17698--- linux-4.4.111/kernel/vserver/inet.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 17699+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/inet.c 2018-01-09 16:36:34.000000000 +0000
7a9e40b8 17700@@ -0,0 +1,236 @@
d337f35e 17701+
4bf69007
AM
17702+#include <linux/in.h>
17703+#include <linux/inetdevice.h>
17704+#include <linux/export.h>
17705+#include <linux/vs_inet.h>
17706+#include <linux/vs_inet6.h>
17707+#include <linux/vserver/debug.h>
17708+#include <net/route.h>
17709+#include <net/addrconf.h>
d337f35e
JR
17710+
17711+
4bf69007 17712+int nx_v4_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2)
d337f35e 17713+{
4bf69007
AM
17714+ int ret = 0;
17715+
17716+ if (!nxi1 || !nxi2 || nxi1 == nxi2)
17717+ ret = 1;
17718+ else {
17719+ struct nx_addr_v4 *ptr;
7a9e40b8 17720+ unsigned long irqflags;
d337f35e 17721+
7a9e40b8 17722+ spin_lock_irqsave(&nxi1->addr_lock, irqflags);
4bf69007
AM
17723+ for (ptr = &nxi1->v4; ptr; ptr = ptr->next) {
17724+ if (v4_nx_addr_in_nx_info(nxi2, ptr, -1)) {
17725+ ret = 1;
17726+ break;
17727+ }
17728+ }
7a9e40b8 17729+ spin_unlock_irqrestore(&nxi1->addr_lock, irqflags);
4bf69007 17730+ }
d337f35e 17731+
4bf69007
AM
17732+ vxdprintk(VXD_CBIT(net, 2),
17733+ "nx_v4_addr_conflict(%p,%p): %d",
17734+ nxi1, nxi2, ret);
d337f35e 17735+
4bf69007
AM
17736+ return ret;
17737+}
d337f35e 17738+
d337f35e 17739+
4bf69007
AM
17740+#ifdef CONFIG_IPV6
17741+
17742+int nx_v6_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2)
d337f35e 17743+{
4bf69007 17744+ int ret = 0;
d337f35e 17745+
4bf69007
AM
17746+ if (!nxi1 || !nxi2 || nxi1 == nxi2)
17747+ ret = 1;
17748+ else {
17749+ struct nx_addr_v6 *ptr;
7a9e40b8 17750+ unsigned long irqflags;
d337f35e 17751+
7a9e40b8 17752+ spin_lock_irqsave(&nxi1->addr_lock, irqflags);
4bf69007
AM
17753+ for (ptr = &nxi1->v6; ptr; ptr = ptr->next) {
17754+ if (v6_nx_addr_in_nx_info(nxi2, ptr, -1)) {
17755+ ret = 1;
17756+ break;
17757+ }
17758+ }
7a9e40b8 17759+ spin_unlock_irqrestore(&nxi1->addr_lock, irqflags);
4bf69007 17760+ }
d337f35e 17761+
4bf69007
AM
17762+ vxdprintk(VXD_CBIT(net, 2),
17763+ "nx_v6_addr_conflict(%p,%p): %d",
17764+ nxi1, nxi2, ret);
d337f35e 17765+
4bf69007
AM
17766+ return ret;
17767+}
d337f35e 17768+
4bf69007 17769+#endif
d337f35e 17770+
4bf69007 17771+int v4_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
d337f35e 17772+{
4bf69007
AM
17773+ struct in_device *in_dev;
17774+ struct in_ifaddr **ifap;
17775+ struct in_ifaddr *ifa;
17776+ int ret = 0;
d337f35e 17777+
4bf69007
AM
17778+ if (!dev)
17779+ goto out;
17780+ in_dev = in_dev_get(dev);
17781+ if (!in_dev)
17782+ goto out;
d337f35e 17783+
4bf69007
AM
17784+ for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
17785+ ifap = &ifa->ifa_next) {
17786+ if (v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW)) {
17787+ ret = 1;
17788+ break;
17789+ }
17790+ }
17791+ in_dev_put(in_dev);
17792+out:
17793+ return ret;
d337f35e
JR
17794+}
17795+
17796+
4bf69007 17797+#ifdef CONFIG_IPV6
d337f35e 17798+
4bf69007 17799+int v6_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
d337f35e 17800+{
4bf69007
AM
17801+ struct inet6_dev *in_dev;
17802+ struct inet6_ifaddr *ifa;
17803+ int ret = 0;
d337f35e 17804+
4bf69007
AM
17805+ if (!dev)
17806+ goto out;
17807+ in_dev = in6_dev_get(dev);
17808+ if (!in_dev)
17809+ goto out;
d337f35e 17810+
4bf69007
AM
17811+ // for (ifap = &in_dev->addr_list; (ifa = *ifap) != NULL;
17812+ list_for_each_entry(ifa, &in_dev->addr_list, if_list) {
17813+ if (v6_addr_in_nx_info(nxi, &ifa->addr, -1)) {
17814+ ret = 1;
17815+ break;
17816+ }
d337f35e 17817+ }
4bf69007
AM
17818+ in6_dev_put(in_dev);
17819+out:
17820+ return ret;
d337f35e
JR
17821+}
17822+
4bf69007 17823+#endif
d337f35e 17824+
4bf69007
AM
17825+int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
17826+{
17827+ int ret = 1;
d337f35e 17828+
4bf69007
AM
17829+ if (!nxi)
17830+ goto out;
17831+ if (nxi->v4.type && v4_dev_in_nx_info(dev, nxi))
17832+ goto out;
17833+#ifdef CONFIG_IPV6
17834+ ret = 2;
17835+ if (nxi->v6.type && v6_dev_in_nx_info(dev, nxi))
17836+ goto out;
17837+#endif
17838+ ret = 0;
17839+out:
17840+ vxdprintk(VXD_CBIT(net, 3),
17841+ "dev_in_nx_info(%p,%p[#%d]) = %d",
17842+ dev, nxi, nxi ? nxi->nx_id : 0, ret);
17843+ return ret;
17844+}
d337f35e 17845+
4bf69007
AM
17846+struct rtable *ip_v4_find_src(struct net *net, struct nx_info *nxi,
17847+ struct flowi4 *fl4)
d337f35e 17848+{
4bf69007 17849+ struct rtable *rt;
d337f35e 17850+
4bf69007
AM
17851+ if (!nxi)
17852+ return NULL;
d337f35e 17853+
4bf69007
AM
17854+ /* FIXME: handle lback only case */
17855+ if (!NX_IPV4(nxi))
17856+ return ERR_PTR(-EPERM);
d337f35e 17857+
4bf69007
AM
17858+ vxdprintk(VXD_CBIT(net, 4),
17859+ "ip_v4_find_src(%p[#%u]) " NIPQUAD_FMT " -> " NIPQUAD_FMT,
17860+ nxi, nxi ? nxi->nx_id : 0,
17861+ NIPQUAD(fl4->saddr), NIPQUAD(fl4->daddr));
d337f35e 17862+
4bf69007
AM
17863+ /* single IP is unconditional */
17864+ if (nx_info_flags(nxi, NXF_SINGLE_IP, 0) &&
17865+ (fl4->saddr == INADDR_ANY))
17866+ fl4->saddr = nxi->v4.ip[0].s_addr;
d337f35e 17867+
4bf69007
AM
17868+ if (fl4->saddr == INADDR_ANY) {
17869+ struct nx_addr_v4 *ptr;
17870+ __be32 found = 0;
17871+
17872+ rt = __ip_route_output_key(net, fl4);
17873+ if (!IS_ERR(rt)) {
17874+ found = fl4->saddr;
17875+ ip_rt_put(rt);
17876+ vxdprintk(VXD_CBIT(net, 4),
17877+ "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT,
17878+ nxi, nxi ? nxi->nx_id : 0, fl4->flowi4_oif, NIPQUAD(found));
17879+ if (v4_addr_in_nx_info(nxi, found, NXA_MASK_BIND))
17880+ goto found;
17881+ }
d337f35e 17882+
8d50a2ea 17883+ WARN_ON_ONCE(in_irq());
b00e13aa 17884+ spin_lock_bh(&nxi->addr_lock);
4bf69007
AM
17885+ for (ptr = &nxi->v4; ptr; ptr = ptr->next) {
17886+ __be32 primary = ptr->ip[0].s_addr;
17887+ __be32 mask = ptr->mask.s_addr;
17888+ __be32 neta = primary & mask;
d337f35e 17889+
4bf69007
AM
17890+ vxdprintk(VXD_CBIT(net, 4), "ip_v4_find_src(%p[#%u]) chk: "
17891+ NIPQUAD_FMT "/" NIPQUAD_FMT "/" NIPQUAD_FMT,
17892+ nxi, nxi ? nxi->nx_id : 0, NIPQUAD(primary),
17893+ NIPQUAD(mask), NIPQUAD(neta));
17894+ if ((found & mask) != neta)
17895+ continue;
d337f35e 17896+
4bf69007
AM
17897+ fl4->saddr = primary;
17898+ rt = __ip_route_output_key(net, fl4);
17899+ vxdprintk(VXD_CBIT(net, 4),
17900+ "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT,
17901+ nxi, nxi ? nxi->nx_id : 0, fl4->flowi4_oif, NIPQUAD(primary));
17902+ if (!IS_ERR(rt)) {
17903+ found = fl4->saddr;
17904+ ip_rt_put(rt);
17905+ if (found == primary)
5cb1760b 17906+ goto found_unlock;
4bf69007
AM
17907+ }
17908+ }
17909+ /* still no source ip? */
17910+ found = ipv4_is_loopback(fl4->daddr)
17911+ ? IPI_LOOPBACK : nxi->v4.ip[0].s_addr;
5cb1760b 17912+ found_unlock:
b00e13aa 17913+ spin_unlock_bh(&nxi->addr_lock);
4bf69007
AM
17914+ found:
17915+ /* assign src ip to flow */
17916+ fl4->saddr = found;
17917+
17918+ } else {
17919+ if (!v4_addr_in_nx_info(nxi, fl4->saddr, NXA_MASK_BIND))
17920+ return ERR_PTR(-EPERM);
17921+ }
d337f35e 17922+
4bf69007
AM
17923+ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0)) {
17924+ if (ipv4_is_loopback(fl4->daddr))
17925+ fl4->daddr = nxi->v4_lback.s_addr;
17926+ if (ipv4_is_loopback(fl4->saddr))
17927+ fl4->saddr = nxi->v4_lback.s_addr;
17928+ } else if (ipv4_is_loopback(fl4->daddr) &&
17929+ !nx_info_flags(nxi, NXF_LBACK_ALLOW, 0))
17930+ return ERR_PTR(-EPERM);
d337f35e 17931+
4bf69007 17932+ return NULL;
d337f35e
JR
17933+}
17934+
4bf69007 17935+EXPORT_SYMBOL_GPL(ip_v4_find_src);
d337f35e 17936+
8de2f54c 17937diff -NurpP --minimal linux-4.4.111/kernel/vserver/init.c linux-4.4.111-vs2.3.9.5/kernel/vserver/init.c
f19bd705 17938--- linux-4.4.111/kernel/vserver/init.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 17939+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/init.c 2018-01-09 22:31:39.000000000 +0000
927ca606 17940@@ -0,0 +1,46 @@
4bf69007
AM
17941+/*
17942+ * linux/kernel/init.c
17943+ *
17944+ * Virtual Server Init
17945+ *
927ca606 17946+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
17947+ *
17948+ * V0.01 basic structure
17949+ *
17950+ */
d337f35e 17951+
4bf69007 17952+#include <linux/init.h>
927ca606 17953+#include <linux/module.h>
4bf69007
AM
17954+
17955+int vserver_register_sysctl(void);
17956+void vserver_unregister_sysctl(void);
17957+
17958+
17959+static int __init init_vserver(void)
d337f35e 17960+{
4bf69007 17961+ int ret = 0;
d337f35e 17962+
4bf69007
AM
17963+#ifdef CONFIG_VSERVER_DEBUG
17964+ vserver_register_sysctl();
17965+#endif
17966+ return ret;
d337f35e
JR
17967+}
17968+
d337f35e 17969+
4bf69007 17970+static void __exit exit_vserver(void)
d337f35e 17971+{
d337f35e 17972+
4bf69007
AM
17973+#ifdef CONFIG_VSERVER_DEBUG
17974+ vserver_unregister_sysctl();
17975+#endif
17976+ return;
d337f35e
JR
17977+}
17978+
4bf69007
AM
17979+/* FIXME: GFP_ZONETYPES gone
17980+long vx_slab[GFP_ZONETYPES]; */
17981+long vx_area;
d337f35e 17982+
d337f35e 17983+
4bf69007
AM
17984+module_init(init_vserver);
17985+module_exit(exit_vserver);
d337f35e 17986+
8de2f54c 17987diff -NurpP --minimal linux-4.4.111/kernel/vserver/inode.c linux-4.4.111-vs2.3.9.5/kernel/vserver/inode.c
f19bd705 17988--- linux-4.4.111/kernel/vserver/inode.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 17989+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/inode.c 2018-01-09 22:24:56.000000000 +0000
09be7631 17990@@ -0,0 +1,440 @@
4bf69007
AM
17991+/*
17992+ * linux/kernel/vserver/inode.c
17993+ *
17994+ * Virtual Server: File System Support
17995+ *
927ca606 17996+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
17997+ *
17998+ * V0.01 separated from vcontext V0.05
17999+ * V0.02 moved to tag (instead of xid)
18000+ *
18001+ */
d337f35e 18002+
4bf69007
AM
18003+#include <linux/tty.h>
18004+#include <linux/proc_fs.h>
18005+#include <linux/devpts_fs.h>
18006+#include <linux/fs.h>
18007+#include <linux/file.h>
18008+#include <linux/mount.h>
18009+#include <linux/parser.h>
18010+#include <linux/namei.h>
09be7631
JR
18011+#include <linux/magic.h>
18012+#include <linux/slab.h>
4bf69007
AM
18013+#include <linux/vserver/inode.h>
18014+#include <linux/vserver/inode_cmd.h>
18015+#include <linux/vs_base.h>
18016+#include <linux/vs_tag.h>
d337f35e 18017+
4bf69007 18018+#include <asm/uaccess.h>
09be7631 18019+#include <../../fs/proc/internal.h>
d337f35e 18020+
d337f35e 18021+
4bf69007 18022+static int __vc_get_iattr(struct inode *in, uint32_t *tag, uint32_t *flags, uint32_t *mask)
d337f35e 18023+{
4bf69007 18024+ struct proc_dir_entry *entry;
d337f35e 18025+
4bf69007
AM
18026+ if (!in || !in->i_sb)
18027+ return -ESRCH;
d337f35e 18028+
4bf69007
AM
18029+ *flags = IATTR_TAG
18030+ | (IS_IMMUTABLE(in) ? IATTR_IMMUTABLE : 0)
18031+ | (IS_IXUNLINK(in) ? IATTR_IXUNLINK : 0)
18032+ | (IS_BARRIER(in) ? IATTR_BARRIER : 0)
18033+ | (IS_COW(in) ? IATTR_COW : 0);
18034+ *mask = IATTR_IXUNLINK | IATTR_IMMUTABLE | IATTR_COW;
d337f35e 18035+
4bf69007
AM
18036+ if (S_ISDIR(in->i_mode))
18037+ *mask |= IATTR_BARRIER;
d337f35e 18038+
4bf69007
AM
18039+ if (IS_TAGGED(in)) {
18040+ *tag = i_tag_read(in);
18041+ *mask |= IATTR_TAG;
18042+ }
2380c486 18043+
4bf69007
AM
18044+ switch (in->i_sb->s_magic) {
18045+ case PROC_SUPER_MAGIC:
18046+ entry = PROC_I(in)->pde;
d337f35e 18047+
4bf69007
AM
18048+ /* check for specific inodes? */
18049+ if (entry)
18050+ *mask |= IATTR_FLAGS;
18051+ if (entry)
18052+ *flags |= (entry->vx_flags & IATTR_FLAGS);
18053+ else
18054+ *flags |= (PROC_I(in)->vx_flags & IATTR_FLAGS);
18055+ break;
d337f35e 18056+
4bf69007
AM
18057+ case DEVPTS_SUPER_MAGIC:
18058+ *tag = i_tag_read(in);
18059+ *mask |= IATTR_TAG;
18060+ break;
d337f35e 18061+
4bf69007
AM
18062+ default:
18063+ break;
18064+ }
18065+ return 0;
d337f35e
JR
18066+}
18067+
4bf69007 18068+int vc_get_iattr(void __user *data)
d337f35e 18069+{
4bf69007
AM
18070+ struct path path;
18071+ struct vcmd_ctx_iattr_v1 vc_data = { .tag = -1 };
18072+ int ret;
d337f35e 18073+
4bf69007
AM
18074+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18075+ return -EFAULT;
d337f35e 18076+
4bf69007
AM
18077+ ret = user_lpath(vc_data.name, &path);
18078+ if (!ret) {
18079+ ret = __vc_get_iattr(path.dentry->d_inode,
18080+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18081+ path_put(&path);
18082+ }
18083+ if (ret)
18084+ return ret;
d337f35e 18085+
4bf69007
AM
18086+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18087+ ret = -EFAULT;
18088+ return ret;
d337f35e
JR
18089+}
18090+
4bf69007 18091+#ifdef CONFIG_COMPAT
d337f35e 18092+
4bf69007 18093+int vc_get_iattr_x32(void __user *data)
d337f35e 18094+{
4bf69007
AM
18095+ struct path path;
18096+ struct vcmd_ctx_iattr_v1_x32 vc_data = { .tag = -1 };
18097+ int ret;
d337f35e 18098+
4bf69007
AM
18099+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18100+ return -EFAULT;
d337f35e 18101+
4bf69007
AM
18102+ ret = user_lpath(compat_ptr(vc_data.name_ptr), &path);
18103+ if (!ret) {
18104+ ret = __vc_get_iattr(path.dentry->d_inode,
18105+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18106+ path_put(&path);
18107+ }
18108+ if (ret)
18109+ return ret;
d337f35e 18110+
2380c486 18111+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
4bf69007
AM
18112+ ret = -EFAULT;
18113+ return ret;
d337f35e
JR
18114+}
18115+
4bf69007 18116+#endif /* CONFIG_COMPAT */
d337f35e 18117+
d337f35e 18118+
4bf69007 18119+int vc_fget_iattr(uint32_t fd, void __user *data)
d337f35e 18120+{
4bf69007
AM
18121+ struct file *filp;
18122+ struct vcmd_ctx_fiattr_v0 vc_data = { .tag = -1 };
d337f35e
JR
18123+ int ret;
18124+
4bf69007 18125+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
18126+ return -EFAULT;
18127+
4bf69007 18128+ filp = fget(fd);
927ca606 18129+ if (!filp || !filp->f_path.dentry || !filp->f_path.dentry->d_inode)
4bf69007 18130+ return -EBADF;
2380c486 18131+
927ca606 18132+ ret = __vc_get_iattr(filp->f_path.dentry->d_inode,
4bf69007 18133+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
2380c486 18134+
4bf69007 18135+ fput(filp);
2380c486 18136+
4bf69007
AM
18137+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18138+ ret = -EFAULT;
d337f35e
JR
18139+ return ret;
18140+}
18141+
18142+
4bf69007 18143+static int __vc_set_iattr(struct dentry *de, uint32_t *tag, uint32_t *flags, uint32_t *mask)
2380c486 18144+{
4bf69007
AM
18145+ struct inode *in = de->d_inode;
18146+ int error = 0, is_proc = 0, has_tag = 0;
18147+ struct iattr attr = { 0 };
2380c486 18148+
4bf69007
AM
18149+ if (!in || !in->i_sb)
18150+ return -ESRCH;
2380c486 18151+
4bf69007
AM
18152+ is_proc = (in->i_sb->s_magic == PROC_SUPER_MAGIC);
18153+ if ((*mask & IATTR_FLAGS) && !is_proc)
18154+ return -EINVAL;
2380c486 18155+
4bf69007
AM
18156+ has_tag = IS_TAGGED(in) ||
18157+ (in->i_sb->s_magic == DEVPTS_SUPER_MAGIC);
18158+ if ((*mask & IATTR_TAG) && !has_tag)
18159+ return -EINVAL;
2380c486 18160+
4bf69007
AM
18161+ mutex_lock(&in->i_mutex);
18162+ if (*mask & IATTR_TAG) {
8ce283e1 18163+ attr.ia_tag = make_ktag(&init_user_ns, *tag);
4bf69007 18164+ attr.ia_valid |= ATTR_TAG;
2380c486
JR
18165+ }
18166+
4bf69007
AM
18167+ if (*mask & IATTR_FLAGS) {
18168+ struct proc_dir_entry *entry = PROC_I(in)->pde;
18169+ unsigned int iflags = PROC_I(in)->vx_flags;
2380c486 18170+
4bf69007
AM
18171+ iflags = (iflags & ~(*mask & IATTR_FLAGS))
18172+ | (*flags & IATTR_FLAGS);
18173+ PROC_I(in)->vx_flags = iflags;
18174+ if (entry)
18175+ entry->vx_flags = iflags;
18176+ }
9f7054f1 18177+
4bf69007
AM
18178+ if (*mask & (IATTR_IMMUTABLE | IATTR_IXUNLINK |
18179+ IATTR_BARRIER | IATTR_COW)) {
18180+ int iflags = in->i_flags;
18181+ int vflags = in->i_vflags;
9f7054f1 18182+
4bf69007
AM
18183+ if (*mask & IATTR_IMMUTABLE) {
18184+ if (*flags & IATTR_IMMUTABLE)
18185+ iflags |= S_IMMUTABLE;
18186+ else
18187+ iflags &= ~S_IMMUTABLE;
18188+ }
18189+ if (*mask & IATTR_IXUNLINK) {
18190+ if (*flags & IATTR_IXUNLINK)
18191+ iflags |= S_IXUNLINK;
18192+ else
18193+ iflags &= ~S_IXUNLINK;
18194+ }
18195+ if (S_ISDIR(in->i_mode) && (*mask & IATTR_BARRIER)) {
18196+ if (*flags & IATTR_BARRIER)
18197+ vflags |= V_BARRIER;
18198+ else
18199+ vflags &= ~V_BARRIER;
18200+ }
18201+ if (S_ISREG(in->i_mode) && (*mask & IATTR_COW)) {
18202+ if (*flags & IATTR_COW)
18203+ vflags |= V_COW;
18204+ else
18205+ vflags &= ~V_COW;
18206+ }
18207+ if (in->i_op && in->i_op->sync_flags) {
18208+ error = in->i_op->sync_flags(in, iflags, vflags);
18209+ if (error)
18210+ goto out;
18211+ }
18212+ }
9f7054f1 18213+
4bf69007
AM
18214+ if (attr.ia_valid) {
18215+ if (in->i_op && in->i_op->setattr)
18216+ error = in->i_op->setattr(de, &attr);
18217+ else {
18218+ error = inode_change_ok(in, &attr);
18219+ if (!error) {
18220+ setattr_copy(in, &attr);
18221+ mark_inode_dirty(in);
18222+ }
18223+ }
9f7054f1 18224+ }
9f7054f1 18225+
4bf69007
AM
18226+out:
18227+ mutex_unlock(&in->i_mutex);
18228+ return error;
18229+}
2380c486 18230+
4bf69007 18231+int vc_set_iattr(void __user *data)
d337f35e 18232+{
4bf69007
AM
18233+ struct path path;
18234+ struct vcmd_ctx_iattr_v1 vc_data;
18235+ int ret;
d337f35e 18236+
4bf69007
AM
18237+ if (!capable(CAP_LINUX_IMMUTABLE))
18238+ return -EPERM;
18239+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
18240+ return -EFAULT;
18241+
4bf69007
AM
18242+ ret = user_lpath(vc_data.name, &path);
18243+ if (!ret) {
18244+ ret = __vc_set_iattr(path.dentry,
18245+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18246+ path_put(&path);
d337f35e 18247+ }
4bf69007
AM
18248+
18249+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18250+ ret = -EFAULT;
d337f35e
JR
18251+ return ret;
18252+}
18253+
4bf69007
AM
18254+#ifdef CONFIG_COMPAT
18255+
18256+int vc_set_iattr_x32(void __user *data)
d337f35e 18257+{
4bf69007
AM
18258+ struct path path;
18259+ struct vcmd_ctx_iattr_v1_x32 vc_data;
18260+ int ret;
d337f35e 18261+
4bf69007
AM
18262+ if (!capable(CAP_LINUX_IMMUTABLE))
18263+ return -EPERM;
18264+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486
JR
18265+ return -EFAULT;
18266+
4bf69007
AM
18267+ ret = user_lpath(compat_ptr(vc_data.name_ptr), &path);
18268+ if (!ret) {
18269+ ret = __vc_set_iattr(path.dentry,
18270+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18271+ path_put(&path);
2380c486 18272+ }
4bf69007
AM
18273+
18274+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18275+ ret = -EFAULT;
18276+ return ret;
2380c486
JR
18277+}
18278+
4bf69007 18279+#endif /* CONFIG_COMPAT */
2380c486 18280+
4bf69007 18281+int vc_fset_iattr(uint32_t fd, void __user *data)
2380c486 18282+{
4bf69007
AM
18283+ struct file *filp;
18284+ struct vcmd_ctx_fiattr_v0 vc_data;
18285+ int ret;
2380c486 18286+
4bf69007
AM
18287+ if (!capable(CAP_LINUX_IMMUTABLE))
18288+ return -EPERM;
18289+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486
JR
18290+ return -EFAULT;
18291+
4bf69007 18292+ filp = fget(fd);
927ca606 18293+ if (!filp || !filp->f_path.dentry || !filp->f_path.dentry->d_inode)
4bf69007 18294+ return -EBADF;
2380c486 18295+
927ca606 18296+ ret = __vc_set_iattr(filp->f_path.dentry, &vc_data.tag,
4bf69007 18297+ &vc_data.flags, &vc_data.mask);
2380c486 18298+
4bf69007 18299+ fput(filp);
2380c486 18300+
4bf69007
AM
18301+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18302+ return -EFAULT;
18303+ return ret;
2380c486
JR
18304+}
18305+
2380c486 18306+
4bf69007 18307+enum { Opt_notagcheck, Opt_tag, Opt_notag, Opt_tagid, Opt_err };
2380c486 18308+
4bf69007
AM
18309+static match_table_t tokens = {
18310+ {Opt_notagcheck, "notagcheck"},
18311+#ifdef CONFIG_PROPAGATE
18312+ {Opt_notag, "notag"},
18313+ {Opt_tag, "tag"},
18314+ {Opt_tagid, "tagid=%u"},
18315+#endif
18316+ {Opt_err, NULL}
18317+};
2380c486 18318+
9f7054f1 18319+
4bf69007
AM
18320+static void __dx_parse_remove(char *string, char *opt)
18321+{
18322+ char *p = strstr(string, opt);
18323+ char *q = p;
2380c486 18324+
4bf69007
AM
18325+ if (p) {
18326+ while (*q != '\0' && *q != ',')
18327+ q++;
18328+ while (*q)
18329+ *p++ = *q++;
18330+ while (*p)
18331+ *p++ = '\0';
2380c486 18332+ }
2380c486
JR
18333+}
18334+
61333608 18335+int dx_parse_tag(char *string, vtag_t *tag, int remove, int *mnt_flags,
4bf69007 18336+ unsigned long *flags)
9f7054f1 18337+{
4bf69007
AM
18338+ int set = 0;
18339+ substring_t args[MAX_OPT_ARGS];
18340+ int token;
18341+ char *s, *p, *opts;
18342+#if defined(CONFIG_PROPAGATE) || defined(CONFIG_VSERVER_DEBUG)
18343+ int option = 0;
18344+#endif
9f7054f1 18345+
4bf69007
AM
18346+ if (!string)
18347+ return 0;
18348+ s = kstrdup(string, GFP_KERNEL | GFP_ATOMIC);
18349+ if (!s)
18350+ return 0;
9f7054f1 18351+
4bf69007
AM
18352+ opts = s;
18353+ while ((p = strsep(&opts, ",")) != NULL) {
18354+ token = match_token(p, tokens, args);
9f7054f1 18355+
4bf69007
AM
18356+ switch (token) {
18357+#ifdef CONFIG_PROPAGATE
18358+ case Opt_tag:
18359+ if (tag)
18360+ *tag = 0;
18361+ if (remove)
18362+ __dx_parse_remove(s, "tag");
18363+ *mnt_flags |= MNT_TAGID;
18364+ set |= MNT_TAGID;
18365+ break;
18366+ case Opt_notag:
18367+ if (remove)
18368+ __dx_parse_remove(s, "notag");
18369+ *mnt_flags |= MNT_NOTAG;
18370+ set |= MNT_NOTAG;
18371+ break;
18372+ case Opt_tagid:
18373+ if (tag && !match_int(args, &option))
18374+ *tag = option;
18375+ if (remove)
18376+ __dx_parse_remove(s, "tagid");
18377+ *mnt_flags |= MNT_TAGID;
18378+ set |= MNT_TAGID;
18379+ break;
18380+#endif /* CONFIG_PROPAGATE */
18381+ case Opt_notagcheck:
18382+ if (remove)
18383+ __dx_parse_remove(s, "notagcheck");
18384+ *flags |= MS_NOTAGCHECK;
18385+ set |= MS_NOTAGCHECK;
18386+ break;
18387+ }
18388+ vxdprintk(VXD_CBIT(tag, 7),
18389+ "dx_parse_tag(" VS_Q("%s") "): %d:#%d",
18390+ p, token, option);
18391+ }
18392+ if (set)
18393+ strcpy(string, s);
18394+ kfree(s);
18395+ return set;
9f7054f1 18396+}
2380c486 18397+
4bf69007 18398+#ifdef CONFIG_PROPAGATE
2380c486 18399+
4bf69007 18400+void __dx_propagate_tag(struct nameidata *nd, struct inode *inode)
2380c486 18401+{
61333608 18402+ vtag_t new_tag = 0;
4bf69007
AM
18403+ struct vfsmount *mnt;
18404+ int propagate;
2380c486 18405+
4bf69007
AM
18406+ if (!nd)
18407+ return;
18408+ mnt = nd->path.mnt;
18409+ if (!mnt)
18410+ return;
2380c486 18411+
4bf69007
AM
18412+ propagate = (mnt->mnt_flags & MNT_TAGID);
18413+ if (propagate)
18414+ new_tag = mnt->mnt_tag;
2380c486 18415+
4bf69007
AM
18416+ vxdprintk(VXD_CBIT(tag, 7),
18417+ "dx_propagate_tag(%p[#%lu.%d]): %d,%d",
18418+ inode, inode->i_ino, inode->i_tag,
18419+ new_tag, (propagate) ? 1 : 0);
18420+
18421+ if (propagate)
18422+ i_tag_write(inode, new_tag);
2380c486
JR
18423+}
18424+
4bf69007 18425+#include <linux/module.h>
2380c486 18426+
4bf69007 18427+EXPORT_SYMBOL_GPL(__dx_propagate_tag);
2380c486 18428+
4bf69007 18429+#endif /* CONFIG_PROPAGATE */
2380c486 18430+
8de2f54c 18431diff -NurpP --minimal linux-4.4.111/kernel/vserver/limit.c linux-4.4.111-vs2.3.9.5/kernel/vserver/limit.c
f19bd705 18432--- linux-4.4.111/kernel/vserver/limit.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 18433+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/limit.c 2018-01-09 16:36:34.000000000 +0000
927ca606 18434@@ -0,0 +1,343 @@
4bf69007
AM
18435+/*
18436+ * linux/kernel/vserver/limit.c
18437+ *
18438+ * Virtual Server: Context Limits
18439+ *
927ca606 18440+ * Copyright (C) 2004-2010 Herbert P?tzl
4bf69007
AM
18441+ *
18442+ * V0.01 broken out from vcontext V0.05
18443+ * V0.02 changed vcmds to vxi arg
18444+ * V0.03 added memory cgroup support
18445+ *
18446+ */
2380c486 18447+
4bf69007
AM
18448+#include <linux/sched.h>
18449+#include <linux/module.h>
18450+#include <linux/memcontrol.h>
927ca606 18451+#include <linux/page_counter.h>
4bf69007
AM
18452+#include <linux/vs_limit.h>
18453+#include <linux/vserver/limit.h>
18454+#include <linux/vserver/limit_cmd.h>
2380c486 18455+
4bf69007 18456+#include <asm/uaccess.h>
d337f35e 18457+
d337f35e 18458+
4bf69007
AM
18459+const char *vlimit_name[NUM_LIMITS] = {
18460+ [RLIMIT_CPU] = "CPU",
18461+ [RLIMIT_NPROC] = "NPROC",
18462+ [RLIMIT_NOFILE] = "NOFILE",
18463+ [RLIMIT_LOCKS] = "LOCKS",
18464+ [RLIMIT_SIGPENDING] = "SIGP",
18465+ [RLIMIT_MSGQUEUE] = "MSGQ",
d337f35e 18466+
4bf69007
AM
18467+ [VLIMIT_NSOCK] = "NSOCK",
18468+ [VLIMIT_OPENFD] = "OPENFD",
18469+ [VLIMIT_SHMEM] = "SHMEM",
18470+ [VLIMIT_DENTRY] = "DENTRY",
18471+};
2380c486 18472+
4bf69007 18473+EXPORT_SYMBOL_GPL(vlimit_name);
2380c486 18474+
4bf69007 18475+#define MASK_ENTRY(x) (1 << (x))
d337f35e 18476+
4bf69007
AM
18477+const struct vcmd_ctx_rlimit_mask_v0 vlimit_mask = {
18478+ /* minimum */
18479+ 0
18480+ , /* softlimit */
18481+ 0
18482+ , /* maximum */
18483+ MASK_ENTRY( RLIMIT_NPROC ) |
18484+ MASK_ENTRY( RLIMIT_NOFILE ) |
18485+ MASK_ENTRY( RLIMIT_LOCKS ) |
18486+ MASK_ENTRY( RLIMIT_MSGQUEUE ) |
d337f35e 18487+
4bf69007
AM
18488+ MASK_ENTRY( VLIMIT_NSOCK ) |
18489+ MASK_ENTRY( VLIMIT_OPENFD ) |
18490+ MASK_ENTRY( VLIMIT_SHMEM ) |
18491+ MASK_ENTRY( VLIMIT_DENTRY ) |
18492+ 0
18493+};
18494+ /* accounting only */
18495+uint32_t account_mask =
18496+ MASK_ENTRY( VLIMIT_SEMARY ) |
18497+ MASK_ENTRY( VLIMIT_NSEMS ) |
18498+ MASK_ENTRY( VLIMIT_MAPPED ) |
18499+ 0;
d337f35e 18500+
4bf69007
AM
18501+
18502+static int is_valid_vlimit(int id)
18503+{
18504+ uint32_t mask = vlimit_mask.minimum |
18505+ vlimit_mask.softlimit | vlimit_mask.maximum;
18506+ return mask & (1 << id);
d337f35e
JR
18507+}
18508+
4bf69007 18509+static int is_accounted_vlimit(int id)
d337f35e 18510+{
4bf69007
AM
18511+ if (is_valid_vlimit(id))
18512+ return 1;
18513+ return account_mask & (1 << id);
18514+}
d337f35e 18515+
d337f35e 18516+
4bf69007
AM
18517+static inline uint64_t vc_get_soft(struct vx_info *vxi, int id)
18518+{
18519+ rlim_t limit = __rlim_soft(&vxi->limit, id);
18520+ return VX_VLIM(limit);
18521+}
d337f35e 18522+
4bf69007
AM
18523+static inline uint64_t vc_get_hard(struct vx_info *vxi, int id)
18524+{
18525+ rlim_t limit = __rlim_hard(&vxi->limit, id);
18526+ return VX_VLIM(limit);
18527+}
d337f35e 18528+
4bf69007
AM
18529+static int do_get_rlimit(struct vx_info *vxi, uint32_t id,
18530+ uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum)
18531+{
18532+ if (!is_valid_vlimit(id))
18533+ return -EINVAL;
18534+
18535+ if (minimum)
18536+ *minimum = CRLIM_UNSET;
18537+ if (softlimit)
18538+ *softlimit = vc_get_soft(vxi, id);
18539+ if (maximum)
18540+ *maximum = vc_get_hard(vxi, id);
d337f35e
JR
18541+ return 0;
18542+}
18543+
4bf69007 18544+int vc_get_rlimit(struct vx_info *vxi, void __user *data)
d337f35e 18545+{
4bf69007
AM
18546+ struct vcmd_ctx_rlimit_v0 vc_data;
18547+ int ret;
d337f35e 18548+
4bf69007
AM
18549+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18550+ return -EFAULT;
18551+
18552+ ret = do_get_rlimit(vxi, vc_data.id,
18553+ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
18554+ if (ret)
18555+ return ret;
d337f35e 18556+
2380c486 18557+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
d337f35e
JR
18558+ return -EFAULT;
18559+ return 0;
18560+}
18561+
4bf69007
AM
18562+static int do_set_rlimit(struct vx_info *vxi, uint32_t id,
18563+ uint64_t minimum, uint64_t softlimit, uint64_t maximum)
d337f35e 18564+{
4bf69007
AM
18565+ if (!is_valid_vlimit(id))
18566+ return -EINVAL;
d337f35e 18567+
4bf69007
AM
18568+ if (maximum != CRLIM_KEEP)
18569+ __rlim_hard(&vxi->limit, id) = VX_RLIM(maximum);
18570+ if (softlimit != CRLIM_KEEP)
18571+ __rlim_soft(&vxi->limit, id) = VX_RLIM(softlimit);
18572+
18573+ /* clamp soft limit */
18574+ if (__rlim_soft(&vxi->limit, id) > __rlim_hard(&vxi->limit, id))
18575+ __rlim_soft(&vxi->limit, id) = __rlim_hard(&vxi->limit, id);
d337f35e 18576+
d337f35e
JR
18577+ return 0;
18578+}
18579+
4bf69007
AM
18580+int vc_set_rlimit(struct vx_info *vxi, void __user *data)
18581+{
18582+ struct vcmd_ctx_rlimit_v0 vc_data;
d337f35e 18583+
4bf69007
AM
18584+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18585+ return -EFAULT;
d337f35e 18586+
4bf69007
AM
18587+ return do_set_rlimit(vxi, vc_data.id,
18588+ vc_data.minimum, vc_data.softlimit, vc_data.maximum);
18589+}
d337f35e 18590+
4bf69007 18591+#ifdef CONFIG_IA32_EMULATION
2380c486 18592+
4bf69007
AM
18593+int vc_set_rlimit_x32(struct vx_info *vxi, void __user *data)
18594+{
18595+ struct vcmd_ctx_rlimit_v0_x32 vc_data;
d337f35e 18596+
4bf69007
AM
18597+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18598+ return -EFAULT;
d337f35e 18599+
4bf69007
AM
18600+ return do_set_rlimit(vxi, vc_data.id,
18601+ vc_data.minimum, vc_data.softlimit, vc_data.maximum);
18602+}
d337f35e 18603+
4bf69007
AM
18604+int vc_get_rlimit_x32(struct vx_info *vxi, void __user *data)
18605+{
18606+ struct vcmd_ctx_rlimit_v0_x32 vc_data;
18607+ int ret;
d337f35e 18608+
4bf69007
AM
18609+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18610+ return -EFAULT;
d337f35e 18611+
4bf69007
AM
18612+ ret = do_get_rlimit(vxi, vc_data.id,
18613+ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
18614+ if (ret)
18615+ return ret;
2380c486 18616+
4bf69007
AM
18617+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18618+ return -EFAULT;
18619+ return 0;
2380c486 18620+}
d337f35e 18621+
4bf69007 18622+#endif /* CONFIG_IA32_EMULATION */
d337f35e
JR
18623+
18624+
4bf69007
AM
18625+int vc_get_rlimit_mask(uint32_t id, void __user *data)
18626+{
18627+ if (copy_to_user(data, &vlimit_mask, sizeof(vlimit_mask)))
18628+ return -EFAULT;
18629+ return 0;
18630+}
d337f35e
JR
18631+
18632+
4bf69007
AM
18633+static inline void vx_reset_hits(struct _vx_limit *limit)
18634+{
18635+ int lim;
d337f35e 18636+
4bf69007
AM
18637+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18638+ atomic_set(&__rlim_lhit(limit, lim), 0);
18639+ }
18640+}
d337f35e 18641+
4bf69007 18642+int vc_reset_hits(struct vx_info *vxi, void __user *data)
d337f35e 18643+{
4bf69007
AM
18644+ vx_reset_hits(&vxi->limit);
18645+ return 0;
d337f35e
JR
18646+}
18647+
4bf69007 18648+static inline void vx_reset_minmax(struct _vx_limit *limit)
d337f35e 18649+{
4bf69007
AM
18650+ rlim_t value;
18651+ int lim;
18652+
18653+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18654+ value = __rlim_get(limit, lim);
18655+ __rlim_rmax(limit, lim) = value;
18656+ __rlim_rmin(limit, lim) = value;
18657+ }
d337f35e
JR
18658+}
18659+
4bf69007 18660+int vc_reset_minmax(struct vx_info *vxi, void __user *data)
d337f35e 18661+{
4bf69007
AM
18662+ vx_reset_minmax(&vxi->limit);
18663+ return 0;
d337f35e
JR
18664+}
18665+
18666+
4bf69007 18667+int vc_rlimit_stat(struct vx_info *vxi, void __user *data)
d337f35e 18668+{
4bf69007
AM
18669+ struct vcmd_rlimit_stat_v0 vc_data;
18670+ struct _vx_limit *limit = &vxi->limit;
18671+ int id;
d337f35e 18672+
4bf69007
AM
18673+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18674+ return -EFAULT;
d337f35e 18675+
4bf69007
AM
18676+ id = vc_data.id;
18677+ if (!is_accounted_vlimit(id))
18678+ return -EINVAL;
2380c486 18679+
4bf69007
AM
18680+ vx_limit_fixup(limit, id);
18681+ vc_data.hits = atomic_read(&__rlim_lhit(limit, id));
18682+ vc_data.value = __rlim_get(limit, id);
18683+ vc_data.minimum = __rlim_rmin(limit, id);
18684+ vc_data.maximum = __rlim_rmax(limit, id);
2380c486 18685+
4bf69007
AM
18686+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18687+ return -EFAULT;
18688+ return 0;
d337f35e
JR
18689+}
18690+
d337f35e 18691+
927ca606 18692+#ifdef CONFIG_MEMCG
4bf69007 18693+void vx_vsi_meminfo(struct sysinfo *val)
d337f35e 18694+{
4bf69007
AM
18695+ struct mem_cgroup *mcg;
18696+ u64 res_limit, res_usage;
d337f35e 18697+
4bf69007
AM
18698+ rcu_read_lock();
18699+ mcg = mem_cgroup_from_task(current);
18700+ rcu_read_unlock();
18701+ if (!mcg)
18702+ goto out;
d337f35e 18703+
927ca606
AM
18704+ res_limit = mem_cgroup_mem_limit_pages(mcg);
18705+ res_usage = mem_cgroup_mem_usage_pages(mcg);
2380c486 18706+
927ca606
AM
18707+ if (res_limit != PAGE_COUNTER_MAX)
18708+ val->totalram = res_limit;
18709+ val->freeram = val->totalram - res_usage;
4bf69007
AM
18710+ val->bufferram = 0;
18711+ val->totalhigh = 0;
18712+ val->freehigh = 0;
18713+out:
4bf69007 18714+ return;
d337f35e
JR
18715+}
18716+
4bf69007 18717+void vx_vsi_swapinfo(struct sysinfo *val)
d337f35e 18718+{
4bf69007
AM
18719+#ifdef CONFIG_MEMCG_SWAP
18720+ struct mem_cgroup *mcg;
18721+ u64 res_limit, res_usage, memsw_limit, memsw_usage;
18722+ s64 swap_limit, swap_usage;
d337f35e 18723+
4bf69007
AM
18724+ rcu_read_lock();
18725+ mcg = mem_cgroup_from_task(current);
18726+ rcu_read_unlock();
18727+ if (!mcg)
18728+ goto out;
d337f35e 18729+
927ca606
AM
18730+ res_limit = mem_cgroup_mem_limit_pages(mcg);
18731+ res_usage = mem_cgroup_mem_usage_pages(mcg);
18732+ memsw_limit = mem_cgroup_memsw_limit_pages(mcg);
18733+ memsw_usage = mem_cgroup_memsw_usage_pages(mcg);
d337f35e 18734+
4bf69007 18735+ /* memory unlimited */
927ca606 18736+ if (res_limit == PAGE_COUNTER_MAX)
4bf69007 18737+ goto out;
d337f35e 18738+
4bf69007
AM
18739+ swap_limit = memsw_limit - res_limit;
18740+ /* we have a swap limit? */
927ca606
AM
18741+ if (memsw_limit != PAGE_COUNTER_MAX)
18742+ val->totalswap = swap_limit;
d337f35e 18743+
4bf69007
AM
18744+ /* calculate swap part */
18745+ swap_usage = (memsw_usage > res_usage) ?
18746+ memsw_usage - res_usage : 0;
18747+
18748+ /* total shown minus usage gives free swap */
18749+ val->freeswap = (swap_usage < swap_limit) ?
927ca606 18750+ val->totalswap - swap_usage : 0;
4bf69007
AM
18751+out:
18752+#else /* !CONFIG_MEMCG_SWAP */
18753+ val->totalswap = 0;
18754+ val->freeswap = 0;
18755+#endif /* !CONFIG_MEMCG_SWAP */
4bf69007 18756+ return;
d337f35e
JR
18757+}
18758+
4bf69007 18759+long vx_vsi_cached(struct sysinfo *val)
d337f35e 18760+{
4bf69007 18761+ long cache = 0;
927ca606 18762+#ifdef CONFIG_MEMCG_BROKEN
4bf69007 18763+ struct mem_cgroup *mcg;
d337f35e 18764+
4bf69007
AM
18765+ rcu_read_lock();
18766+ mcg = mem_cgroup_from_task(current);
18767+ rcu_read_unlock();
18768+ if (!mcg)
18769+ goto out;
2380c486 18770+
927ca606 18771+ // cache = mem_cgroup_stat_read_cache(mcg);
4bf69007 18772+out:
2380c486 18773+#endif
4bf69007 18774+ return cache;
d337f35e 18775+}
927ca606 18776+#endif /* !CONFIG_MEMCG */
d337f35e 18777+
8de2f54c 18778diff -NurpP --minimal linux-4.4.111/kernel/vserver/limit_init.h linux-4.4.111-vs2.3.9.5/kernel/vserver/limit_init.h
f19bd705 18779--- linux-4.4.111/kernel/vserver/limit_init.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 18780+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/limit_init.h 2018-01-09 16:36:34.000000000 +0000
4bf69007 18781@@ -0,0 +1,31 @@
d337f35e
JR
18782+
18783+
4bf69007
AM
18784+static inline void vx_info_init_limit(struct _vx_limit *limit)
18785+{
18786+ int lim;
d337f35e 18787+
4bf69007
AM
18788+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18789+ __rlim_soft(limit, lim) = RLIM_INFINITY;
18790+ __rlim_hard(limit, lim) = RLIM_INFINITY;
18791+ __rlim_set(limit, lim, 0);
18792+ atomic_set(&__rlim_lhit(limit, lim), 0);
18793+ __rlim_rmin(limit, lim) = 0;
18794+ __rlim_rmax(limit, lim) = 0;
18795+ }
18796+}
d337f35e 18797+
4bf69007 18798+static inline void vx_info_exit_limit(struct _vx_limit *limit)
d337f35e 18799+{
4bf69007
AM
18800+ rlim_t value;
18801+ int lim;
d337f35e 18802+
4bf69007
AM
18803+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18804+ if ((1 << lim) & VLIM_NOCHECK)
18805+ continue;
18806+ value = __rlim_get(limit, lim);
18807+ vxwprintk_xid(value,
18808+ "!!! limit: %p[%s,%d] = %ld on exit.",
18809+ limit, vlimit_name[lim], lim, (long)value);
18810+ }
18811+}
d337f35e 18812+
8de2f54c 18813diff -NurpP --minimal linux-4.4.111/kernel/vserver/limit_proc.h linux-4.4.111-vs2.3.9.5/kernel/vserver/limit_proc.h
f19bd705 18814--- linux-4.4.111/kernel/vserver/limit_proc.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 18815+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/limit_proc.h 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
18816@@ -0,0 +1,57 @@
18817+#ifndef _VX_LIMIT_PROC_H
18818+#define _VX_LIMIT_PROC_H
d337f35e 18819+
4bf69007 18820+#include <linux/vserver/limit_int.h>
d337f35e 18821+
d337f35e 18822+
4bf69007
AM
18823+#define VX_LIMIT_FMT ":\t%8ld\t%8ld/%8ld\t%8lld/%8lld\t%6d\n"
18824+#define VX_LIMIT_TOP \
18825+ "Limit\t current\t min/max\t\t soft/hard\t\thits\n"
d337f35e 18826+
4bf69007
AM
18827+#define VX_LIMIT_ARG(r) \
18828+ (unsigned long)__rlim_get(limit, r), \
18829+ (unsigned long)__rlim_rmin(limit, r), \
18830+ (unsigned long)__rlim_rmax(limit, r), \
18831+ VX_VLIM(__rlim_soft(limit, r)), \
18832+ VX_VLIM(__rlim_hard(limit, r)), \
18833+ atomic_read(&__rlim_lhit(limit, r))
d337f35e 18834+
4bf69007
AM
18835+static inline int vx_info_proc_limit(struct _vx_limit *limit, char *buffer)
18836+{
18837+ vx_limit_fixup(limit, -1);
18838+ return sprintf(buffer, VX_LIMIT_TOP
18839+ "PROC" VX_LIMIT_FMT
18840+ "VM" VX_LIMIT_FMT
18841+ "VML" VX_LIMIT_FMT
18842+ "RSS" VX_LIMIT_FMT
18843+ "ANON" VX_LIMIT_FMT
18844+ "RMAP" VX_LIMIT_FMT
18845+ "FILES" VX_LIMIT_FMT
18846+ "OFD" VX_LIMIT_FMT
18847+ "LOCKS" VX_LIMIT_FMT
18848+ "SOCK" VX_LIMIT_FMT
18849+ "MSGQ" VX_LIMIT_FMT
18850+ "SHM" VX_LIMIT_FMT
18851+ "SEMA" VX_LIMIT_FMT
18852+ "SEMS" VX_LIMIT_FMT
18853+ "DENT" VX_LIMIT_FMT,
18854+ VX_LIMIT_ARG(RLIMIT_NPROC),
18855+ VX_LIMIT_ARG(RLIMIT_AS),
18856+ VX_LIMIT_ARG(RLIMIT_MEMLOCK),
18857+ VX_LIMIT_ARG(RLIMIT_RSS),
18858+ VX_LIMIT_ARG(VLIMIT_ANON),
18859+ VX_LIMIT_ARG(VLIMIT_MAPPED),
18860+ VX_LIMIT_ARG(RLIMIT_NOFILE),
18861+ VX_LIMIT_ARG(VLIMIT_OPENFD),
18862+ VX_LIMIT_ARG(RLIMIT_LOCKS),
18863+ VX_LIMIT_ARG(VLIMIT_NSOCK),
18864+ VX_LIMIT_ARG(RLIMIT_MSGQUEUE),
18865+ VX_LIMIT_ARG(VLIMIT_SHMEM),
18866+ VX_LIMIT_ARG(VLIMIT_SEMARY),
18867+ VX_LIMIT_ARG(VLIMIT_NSEMS),
18868+ VX_LIMIT_ARG(VLIMIT_DENTRY));
d337f35e
JR
18869+}
18870+
4bf69007 18871+#endif /* _VX_LIMIT_PROC_H */
d337f35e 18872+
d337f35e 18873+
8de2f54c 18874diff -NurpP --minimal linux-4.4.111/kernel/vserver/network.c linux-4.4.111-vs2.3.9.5/kernel/vserver/network.c
f19bd705 18875--- linux-4.4.111/kernel/vserver/network.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 18876+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/network.c 2018-01-09 16:36:34.000000000 +0000
5cb1760b 18877@@ -0,0 +1,1053 @@
d337f35e 18878+/*
4bf69007 18879+ * linux/kernel/vserver/network.c
d337f35e 18880+ *
4bf69007
AM
18881+ * Virtual Server: Network Support
18882+ *
927ca606 18883+ * Copyright (C) 2003-2007 Herbert P?tzl
4bf69007
AM
18884+ *
18885+ * V0.01 broken out from vcontext V0.05
18886+ * V0.02 cleaned up implementation
18887+ * V0.03 added equiv nx commands
18888+ * V0.04 switch to RCU based hash
18889+ * V0.05 and back to locking again
18890+ * V0.06 changed vcmds to nxi arg
18891+ * V0.07 have __create claim() the nxi
d337f35e 18892+ *
d337f35e 18893+ */
d337f35e 18894+
4bf69007
AM
18895+#include <linux/err.h>
18896+#include <linux/slab.h>
18897+#include <linux/rcupdate.h>
18898+#include <net/ipv6.h>
d337f35e 18899+
4bf69007
AM
18900+#include <linux/vs_network.h>
18901+#include <linux/vs_pid.h>
18902+#include <linux/vserver/network_cmd.h>
d337f35e
JR
18903+
18904+
4bf69007
AM
18905+atomic_t nx_global_ctotal = ATOMIC_INIT(0);
18906+atomic_t nx_global_cactive = ATOMIC_INIT(0);
d337f35e 18907+
4bf69007
AM
18908+static struct kmem_cache *nx_addr_v4_cachep = NULL;
18909+static struct kmem_cache *nx_addr_v6_cachep = NULL;
d337f35e 18910+
d337f35e 18911+
4bf69007 18912+static int __init init_network(void)
d337f35e 18913+{
4bf69007
AM
18914+ nx_addr_v4_cachep = kmem_cache_create("nx_v4_addr_cache",
18915+ sizeof(struct nx_addr_v4), 0,
18916+ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
18917+ nx_addr_v6_cachep = kmem_cache_create("nx_v6_addr_cache",
18918+ sizeof(struct nx_addr_v6), 0,
18919+ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
d337f35e
JR
18920+ return 0;
18921+}
18922+
18923+
4bf69007 18924+/* __alloc_nx_addr_v4() */
d337f35e 18925+
4bf69007 18926+static inline struct nx_addr_v4 *__alloc_nx_addr_v4(void)
d337f35e 18927+{
4bf69007
AM
18928+ struct nx_addr_v4 *nxa = kmem_cache_alloc(
18929+ nx_addr_v4_cachep, GFP_KERNEL);
92598135 18930+
4bf69007
AM
18931+ if (!IS_ERR(nxa))
18932+ memset(nxa, 0, sizeof(*nxa));
18933+ return nxa;
d337f35e
JR
18934+}
18935+
4bf69007 18936+/* __dealloc_nx_addr_v4() */
d337f35e 18937+
4bf69007
AM
18938+static inline void __dealloc_nx_addr_v4(struct nx_addr_v4 *nxa)
18939+{
18940+ kmem_cache_free(nx_addr_v4_cachep, nxa);
18941+}
d337f35e 18942+
4bf69007 18943+/* __dealloc_nx_addr_v4_all() */
d337f35e 18944+
4bf69007 18945+static inline void __dealloc_nx_addr_v4_all(struct nx_addr_v4 *nxa)
d337f35e 18946+{
4bf69007
AM
18947+ while (nxa) {
18948+ struct nx_addr_v4 *next = nxa->next;
d337f35e 18949+
4bf69007
AM
18950+ __dealloc_nx_addr_v4(nxa);
18951+ nxa = next;
18952+ }
18953+}
d337f35e 18954+
d337f35e 18955+
4bf69007 18956+#ifdef CONFIG_IPV6
d337f35e 18957+
4bf69007 18958+/* __alloc_nx_addr_v6() */
d337f35e 18959+
4bf69007
AM
18960+static inline struct nx_addr_v6 *__alloc_nx_addr_v6(void)
18961+{
18962+ struct nx_addr_v6 *nxa = kmem_cache_alloc(
18963+ nx_addr_v6_cachep, GFP_KERNEL);
d337f35e 18964+
4bf69007
AM
18965+ if (!IS_ERR(nxa))
18966+ memset(nxa, 0, sizeof(*nxa));
18967+ return nxa;
d337f35e
JR
18968+}
18969+
4bf69007
AM
18970+/* __dealloc_nx_addr_v6() */
18971+
18972+static inline void __dealloc_nx_addr_v6(struct nx_addr_v6 *nxa)
d337f35e 18973+{
4bf69007
AM
18974+ kmem_cache_free(nx_addr_v6_cachep, nxa);
18975+}
d337f35e 18976+
4bf69007 18977+/* __dealloc_nx_addr_v6_all() */
d337f35e 18978+
4bf69007
AM
18979+static inline void __dealloc_nx_addr_v6_all(struct nx_addr_v6 *nxa)
18980+{
18981+ while (nxa) {
18982+ struct nx_addr_v6 *next = nxa->next;
d337f35e 18983+
4bf69007
AM
18984+ __dealloc_nx_addr_v6(nxa);
18985+ nxa = next;
18986+ }
18987+}
d337f35e 18988+
4bf69007 18989+#endif /* CONFIG_IPV6 */
d337f35e 18990+
4bf69007 18991+/* __alloc_nx_info()
d337f35e 18992+
4bf69007
AM
18993+ * allocate an initialized nx_info struct
18994+ * doesn't make it visible (hash) */
d337f35e 18995+
61333608 18996+static struct nx_info *__alloc_nx_info(vnid_t nid)
d337f35e 18997+{
4bf69007 18998+ struct nx_info *new = NULL;
d337f35e 18999+
4bf69007 19000+ vxdprintk(VXD_CBIT(nid, 1), "alloc_nx_info(%d)*", nid);
d337f35e 19001+
4bf69007
AM
19002+ /* would this benefit from a slab cache? */
19003+ new = kmalloc(sizeof(struct nx_info), GFP_KERNEL);
19004+ if (!new)
19005+ return 0;
d337f35e 19006+
4bf69007
AM
19007+ memset(new, 0, sizeof(struct nx_info));
19008+ new->nx_id = nid;
19009+ INIT_HLIST_NODE(&new->nx_hlist);
19010+ atomic_set(&new->nx_usecnt, 0);
19011+ atomic_set(&new->nx_tasks, 0);
19012+ spin_lock_init(&new->addr_lock);
19013+ new->nx_state = 0;
d337f35e 19014+
4bf69007 19015+ new->nx_flags = NXF_INIT_SET;
d337f35e 19016+
4bf69007 19017+ /* rest of init goes here */
d337f35e 19018+
4bf69007
AM
19019+ new->v4_lback.s_addr = htonl(INADDR_LOOPBACK);
19020+ new->v4_bcast.s_addr = htonl(INADDR_BROADCAST);
19021+
19022+ vxdprintk(VXD_CBIT(nid, 0),
19023+ "alloc_nx_info(%d) = %p", nid, new);
19024+ atomic_inc(&nx_global_ctotal);
19025+ return new;
d337f35e
JR
19026+}
19027+
4bf69007 19028+/* __dealloc_nx_info()
d337f35e 19029+
4bf69007 19030+ * final disposal of nx_info */
d337f35e 19031+
4bf69007
AM
19032+static void __dealloc_nx_info(struct nx_info *nxi)
19033+{
19034+ vxdprintk(VXD_CBIT(nid, 0),
19035+ "dealloc_nx_info(%p)", nxi);
d337f35e 19036+
4bf69007
AM
19037+ nxi->nx_hlist.next = LIST_POISON1;
19038+ nxi->nx_id = -1;
d337f35e 19039+
4bf69007
AM
19040+ BUG_ON(atomic_read(&nxi->nx_usecnt));
19041+ BUG_ON(atomic_read(&nxi->nx_tasks));
19042+
19043+ __dealloc_nx_addr_v4_all(nxi->v4.next);
19044+#ifdef CONFIG_IPV6
19045+ __dealloc_nx_addr_v6_all(nxi->v6.next);
19046+#endif
19047+
19048+ nxi->nx_state |= NXS_RELEASED;
19049+ kfree(nxi);
19050+ atomic_dec(&nx_global_ctotal);
d337f35e
JR
19051+}
19052+
4bf69007
AM
19053+static void __shutdown_nx_info(struct nx_info *nxi)
19054+{
19055+ nxi->nx_state |= NXS_SHUTDOWN;
19056+ vs_net_change(nxi, VSC_NETDOWN);
19057+}
d337f35e 19058+
4bf69007 19059+/* exported stuff */
d337f35e 19060+
4bf69007
AM
19061+void free_nx_info(struct nx_info *nxi)
19062+{
19063+ /* context shutdown is mandatory */
19064+ BUG_ON(nxi->nx_state != NXS_SHUTDOWN);
d337f35e 19065+
4bf69007
AM
19066+ /* context must not be hashed */
19067+ BUG_ON(nxi->nx_state & NXS_HASHED);
d337f35e 19068+
4bf69007
AM
19069+ BUG_ON(atomic_read(&nxi->nx_usecnt));
19070+ BUG_ON(atomic_read(&nxi->nx_tasks));
d337f35e 19071+
4bf69007
AM
19072+ __dealloc_nx_info(nxi);
19073+}
d337f35e 19074+
d337f35e 19075+
4bf69007
AM
19076+void __nx_set_lback(struct nx_info *nxi)
19077+{
19078+ int nid = nxi->nx_id;
19079+ __be32 lback = htonl(INADDR_LOOPBACK ^ ((nid & 0xFFFF) << 8));
d337f35e 19080+
4bf69007
AM
19081+ nxi->v4_lback.s_addr = lback;
19082+}
d337f35e 19083+
4bf69007
AM
19084+extern int __nx_inet_add_lback(__be32 addr);
19085+extern int __nx_inet_del_lback(__be32 addr);
d337f35e
JR
19086+
19087+
4bf69007 19088+/* hash table for nx_info hash */
d337f35e 19089+
4bf69007 19090+#define NX_HASH_SIZE 13
d337f35e 19091+
4bf69007
AM
19092+struct hlist_head nx_info_hash[NX_HASH_SIZE];
19093+
19094+static DEFINE_SPINLOCK(nx_info_hash_lock);
19095+
19096+
61333608 19097+static inline unsigned int __hashval(vnid_t nid)
d337f35e 19098+{
4bf69007 19099+ return (nid % NX_HASH_SIZE);
d337f35e
JR
19100+}
19101+
d337f35e 19102+
d337f35e 19103+
4bf69007 19104+/* __hash_nx_info()
d337f35e 19105+
4bf69007
AM
19106+ * add the nxi to the global hash table
19107+ * requires the hash_lock to be held */
19108+
19109+static inline void __hash_nx_info(struct nx_info *nxi)
d337f35e 19110+{
4bf69007 19111+ struct hlist_head *head;
d337f35e 19112+
4bf69007
AM
19113+ vxd_assert_lock(&nx_info_hash_lock);
19114+ vxdprintk(VXD_CBIT(nid, 4),
19115+ "__hash_nx_info: %p[#%d]", nxi, nxi->nx_id);
d337f35e 19116+
4bf69007
AM
19117+ /* context must not be hashed */
19118+ BUG_ON(nx_info_state(nxi, NXS_HASHED));
d337f35e 19119+
4bf69007
AM
19120+ nxi->nx_state |= NXS_HASHED;
19121+ head = &nx_info_hash[__hashval(nxi->nx_id)];
19122+ hlist_add_head(&nxi->nx_hlist, head);
19123+ atomic_inc(&nx_global_cactive);
19124+}
d337f35e 19125+
4bf69007 19126+/* __unhash_nx_info()
d337f35e 19127+
4bf69007
AM
19128+ * remove the nxi from the global hash table
19129+ * requires the hash_lock to be held */
d337f35e 19130+
4bf69007
AM
19131+static inline void __unhash_nx_info(struct nx_info *nxi)
19132+{
19133+ vxd_assert_lock(&nx_info_hash_lock);
19134+ vxdprintk(VXD_CBIT(nid, 4),
19135+ "__unhash_nx_info: %p[#%d.%d.%d]", nxi, nxi->nx_id,
19136+ atomic_read(&nxi->nx_usecnt), atomic_read(&nxi->nx_tasks));
d337f35e 19137+
4bf69007
AM
19138+ /* context must be hashed */
19139+ BUG_ON(!nx_info_state(nxi, NXS_HASHED));
19140+ /* but without tasks */
19141+ BUG_ON(atomic_read(&nxi->nx_tasks));
d337f35e 19142+
4bf69007
AM
19143+ nxi->nx_state &= ~NXS_HASHED;
19144+ hlist_del(&nxi->nx_hlist);
19145+ atomic_dec(&nx_global_cactive);
d337f35e
JR
19146+}
19147+
d337f35e 19148+
4bf69007 19149+/* __lookup_nx_info()
d337f35e 19150+
4bf69007
AM
19151+ * requires the hash_lock to be held
19152+ * doesn't increment the nx_refcnt */
d337f35e 19153+
61333608 19154+static inline struct nx_info *__lookup_nx_info(vnid_t nid)
d337f35e 19155+{
4bf69007
AM
19156+ struct hlist_head *head = &nx_info_hash[__hashval(nid)];
19157+ struct hlist_node *pos;
19158+ struct nx_info *nxi;
d337f35e 19159+
4bf69007
AM
19160+ vxd_assert_lock(&nx_info_hash_lock);
19161+ hlist_for_each(pos, head) {
19162+ nxi = hlist_entry(pos, struct nx_info, nx_hlist);
19163+
19164+ if (nxi->nx_id == nid)
19165+ goto found;
d337f35e 19166+ }
4bf69007
AM
19167+ nxi = NULL;
19168+found:
19169+ vxdprintk(VXD_CBIT(nid, 0),
19170+ "__lookup_nx_info(#%u): %p[#%u]",
19171+ nid, nxi, nxi ? nxi->nx_id : 0);
19172+ return nxi;
d337f35e
JR
19173+}
19174+
19175+
4bf69007 19176+/* __create_nx_info()
d337f35e 19177+
4bf69007
AM
19178+ * create the requested context
19179+ * get(), claim() and hash it */
d337f35e 19180+
4bf69007
AM
19181+static struct nx_info *__create_nx_info(int id)
19182+{
19183+ struct nx_info *new, *nxi = NULL;
d337f35e 19184+
4bf69007 19185+ vxdprintk(VXD_CBIT(nid, 1), "create_nx_info(%d)*", id);
d337f35e 19186+
4bf69007
AM
19187+ if (!(new = __alloc_nx_info(id)))
19188+ return ERR_PTR(-ENOMEM);
d337f35e 19189+
4bf69007
AM
19190+ /* required to make dynamic xids unique */
19191+ spin_lock(&nx_info_hash_lock);
d337f35e 19192+
4bf69007
AM
19193+ /* static context requested */
19194+ if ((nxi = __lookup_nx_info(id))) {
19195+ vxdprintk(VXD_CBIT(nid, 0),
19196+ "create_nx_info(%d) = %p (already there)", id, nxi);
19197+ if (nx_info_flags(nxi, NXF_STATE_SETUP, 0))
19198+ nxi = ERR_PTR(-EBUSY);
19199+ else
19200+ nxi = ERR_PTR(-EEXIST);
19201+ goto out_unlock;
19202+ }
19203+ /* new context */
19204+ vxdprintk(VXD_CBIT(nid, 0),
19205+ "create_nx_info(%d) = %p (new)", id, new);
19206+ claim_nx_info(new, NULL);
19207+ __nx_set_lback(new);
19208+ __hash_nx_info(get_nx_info(new));
19209+ nxi = new, new = NULL;
d337f35e 19210+
4bf69007
AM
19211+out_unlock:
19212+ spin_unlock(&nx_info_hash_lock);
19213+ if (new)
19214+ __dealloc_nx_info(new);
19215+ return nxi;
19216+}
d337f35e
JR
19217+
19218+
d337f35e 19219+
4bf69007 19220+/* exported stuff */
d337f35e 19221+
d337f35e 19222+
4bf69007
AM
19223+void unhash_nx_info(struct nx_info *nxi)
19224+{
19225+ __shutdown_nx_info(nxi);
19226+ spin_lock(&nx_info_hash_lock);
19227+ __unhash_nx_info(nxi);
19228+ spin_unlock(&nx_info_hash_lock);
d337f35e
JR
19229+}
19230+
4bf69007 19231+/* lookup_nx_info()
d337f35e 19232+
4bf69007
AM
19233+ * search for a nx_info and get() it
19234+ * negative id means current */
d337f35e 19235+
4bf69007 19236+struct nx_info *lookup_nx_info(int id)
d337f35e 19237+{
4bf69007 19238+ struct nx_info *nxi = NULL;
d337f35e 19239+
4bf69007
AM
19240+ if (id < 0) {
19241+ nxi = get_nx_info(current_nx_info());
19242+ } else if (id > 1) {
19243+ spin_lock(&nx_info_hash_lock);
19244+ nxi = get_nx_info(__lookup_nx_info(id));
19245+ spin_unlock(&nx_info_hash_lock);
d337f35e 19246+ }
4bf69007
AM
19247+ return nxi;
19248+}
d337f35e 19249+
4bf69007 19250+/* nid_is_hashed()
d337f35e 19251+
4bf69007
AM
19252+ * verify that nid is still hashed */
19253+
61333608 19254+int nid_is_hashed(vnid_t nid)
4bf69007
AM
19255+{
19256+ int hashed;
19257+
19258+ spin_lock(&nx_info_hash_lock);
19259+ hashed = (__lookup_nx_info(nid) != NULL);
19260+ spin_unlock(&nx_info_hash_lock);
19261+ return hashed;
d337f35e
JR
19262+}
19263+
19264+
4bf69007 19265+#ifdef CONFIG_PROC_FS
d337f35e 19266+
4bf69007
AM
19267+/* get_nid_list()
19268+
19269+ * get a subset of hashed nids for proc
19270+ * assumes size is at least one */
19271+
19272+int get_nid_list(int index, unsigned int *nids, int size)
d337f35e 19273+{
4bf69007 19274+ int hindex, nr_nids = 0;
d337f35e 19275+
4bf69007
AM
19276+ /* only show current and children */
19277+ if (!nx_check(0, VS_ADMIN | VS_WATCH)) {
19278+ if (index > 0)
19279+ return 0;
19280+ nids[nr_nids] = nx_current_nid();
19281+ return 1;
19282+ }
d337f35e 19283+
4bf69007
AM
19284+ for (hindex = 0; hindex < NX_HASH_SIZE; hindex++) {
19285+ struct hlist_head *head = &nx_info_hash[hindex];
19286+ struct hlist_node *pos;
d337f35e 19287+
4bf69007
AM
19288+ spin_lock(&nx_info_hash_lock);
19289+ hlist_for_each(pos, head) {
19290+ struct nx_info *nxi;
19291+
19292+ if (--index > 0)
19293+ continue;
19294+
19295+ nxi = hlist_entry(pos, struct nx_info, nx_hlist);
19296+ nids[nr_nids] = nxi->nx_id;
19297+ if (++nr_nids >= size) {
19298+ spin_unlock(&nx_info_hash_lock);
d337f35e 19299+ goto out;
4bf69007 19300+ }
d337f35e 19301+ }
4bf69007
AM
19302+ /* keep the lock time short */
19303+ spin_unlock(&nx_info_hash_lock);
d337f35e
JR
19304+ }
19305+out:
4bf69007 19306+ return nr_nids;
d337f35e 19307+}
4bf69007 19308+#endif
d337f35e 19309+
4bf69007
AM
19310+
19311+/*
19312+ * migrate task to new network
19313+ * gets nxi, puts old_nxi on change
19314+ */
19315+
19316+int nx_migrate_task(struct task_struct *p, struct nx_info *nxi)
2380c486 19317+{
4bf69007
AM
19318+ struct nx_info *old_nxi;
19319+ int ret = 0;
2380c486 19320+
4bf69007
AM
19321+ if (!p || !nxi)
19322+ BUG();
d337f35e 19323+
4bf69007
AM
19324+ vxdprintk(VXD_CBIT(nid, 5),
19325+ "nx_migrate_task(%p,%p[#%d.%d.%d])",
19326+ p, nxi, nxi->nx_id,
19327+ atomic_read(&nxi->nx_usecnt),
19328+ atomic_read(&nxi->nx_tasks));
d337f35e 19329+
4bf69007
AM
19330+ if (nx_info_flags(nxi, NXF_INFO_PRIVATE, 0) &&
19331+ !nx_info_flags(nxi, NXF_STATE_SETUP, 0))
19332+ return -EACCES;
d337f35e 19333+
4bf69007
AM
19334+ if (nx_info_state(nxi, NXS_SHUTDOWN))
19335+ return -EFAULT;
d337f35e 19336+
4bf69007
AM
19337+ /* maybe disallow this completely? */
19338+ old_nxi = task_get_nx_info(p);
19339+ if (old_nxi == nxi)
19340+ goto out;
d337f35e 19341+
4bf69007
AM
19342+ task_lock(p);
19343+ if (old_nxi)
19344+ clr_nx_info(&p->nx_info);
19345+ claim_nx_info(nxi, p);
19346+ set_nx_info(&p->nx_info, nxi);
19347+ p->nid = nxi->nx_id;
19348+ task_unlock(p);
d337f35e 19349+
4bf69007
AM
19350+ vxdprintk(VXD_CBIT(nid, 5),
19351+ "moved task %p into nxi:%p[#%d]",
19352+ p, nxi, nxi->nx_id);
d337f35e 19353+
4bf69007
AM
19354+ if (old_nxi)
19355+ release_nx_info(old_nxi, p);
19356+ ret = 0;
19357+out:
19358+ put_nx_info(old_nxi);
19359+ return ret;
19360+}
d337f35e 19361+
d337f35e 19362+
4bf69007
AM
19363+void nx_set_persistent(struct nx_info *nxi)
19364+{
19365+ vxdprintk(VXD_CBIT(nid, 6),
19366+ "nx_set_persistent(%p[#%d])", nxi, nxi->nx_id);
d337f35e 19367+
4bf69007
AM
19368+ get_nx_info(nxi);
19369+ claim_nx_info(nxi, NULL);
d337f35e
JR
19370+}
19371+
4bf69007 19372+void nx_clear_persistent(struct nx_info *nxi)
2380c486 19373+{
4bf69007
AM
19374+ vxdprintk(VXD_CBIT(nid, 6),
19375+ "nx_clear_persistent(%p[#%d])", nxi, nxi->nx_id);
2380c486 19376+
4bf69007
AM
19377+ release_nx_info(nxi, NULL);
19378+ put_nx_info(nxi);
2380c486 19379+}
d337f35e 19380+
4bf69007
AM
19381+void nx_update_persistent(struct nx_info *nxi)
19382+{
19383+ if (nx_info_flags(nxi, NXF_PERSISTENT, 0))
19384+ nx_set_persistent(nxi);
19385+ else
19386+ nx_clear_persistent(nxi);
19387+}
d337f35e 19388+
4bf69007
AM
19389+/* vserver syscall commands below here */
19390+
19391+/* taks nid and nx_info functions */
d337f35e 19392+
4bf69007 19393+#include <asm/uaccess.h>
d337f35e
JR
19394+
19395+
4bf69007 19396+int vc_task_nid(uint32_t id)
d337f35e 19397+{
61333608 19398+ vnid_t nid;
d337f35e 19399+
4bf69007
AM
19400+ if (id) {
19401+ struct task_struct *tsk;
d337f35e 19402+
4bf69007
AM
19403+ rcu_read_lock();
19404+ tsk = find_task_by_real_pid(id);
19405+ nid = (tsk) ? tsk->nid : -ESRCH;
19406+ rcu_read_unlock();
19407+ } else
19408+ nid = nx_current_nid();
19409+ return nid;
d337f35e
JR
19410+}
19411+
19412+
4bf69007
AM
19413+int vc_nx_info(struct nx_info *nxi, void __user *data)
19414+{
19415+ struct vcmd_nx_info_v0 vc_data;
d337f35e 19416+
4bf69007 19417+ vc_data.nid = nxi->nx_id;
d337f35e 19418+
4bf69007
AM
19419+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
19420+ return -EFAULT;
19421+ return 0;
19422+}
d337f35e 19423+
d337f35e 19424+
4bf69007 19425+/* network functions */
d337f35e 19426+
4bf69007
AM
19427+int vc_net_create(uint32_t nid, void __user *data)
19428+{
19429+ struct vcmd_net_create vc_data = { .flagword = NXF_INIT_SET };
19430+ struct nx_info *new_nxi;
19431+ int ret;
d337f35e 19432+
4bf69007
AM
19433+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19434+ return -EFAULT;
d337f35e 19435+
4bf69007
AM
19436+ if ((nid > MAX_S_CONTEXT) || (nid < 2))
19437+ return -EINVAL;
d337f35e 19438+
4bf69007
AM
19439+ new_nxi = __create_nx_info(nid);
19440+ if (IS_ERR(new_nxi))
19441+ return PTR_ERR(new_nxi);
d337f35e 19442+
4bf69007
AM
19443+ /* initial flags */
19444+ new_nxi->nx_flags = vc_data.flagword;
d337f35e 19445+
4bf69007
AM
19446+ ret = -ENOEXEC;
19447+ if (vs_net_change(new_nxi, VSC_NETUP))
19448+ goto out;
d337f35e 19449+
4bf69007
AM
19450+ ret = nx_migrate_task(current, new_nxi);
19451+ if (ret)
d337f35e
JR
19452+ goto out;
19453+
4bf69007
AM
19454+ /* return context id on success */
19455+ ret = new_nxi->nx_id;
d337f35e 19456+
4bf69007
AM
19457+ /* get a reference for persistent contexts */
19458+ if ((vc_data.flagword & NXF_PERSISTENT))
19459+ nx_set_persistent(new_nxi);
d337f35e 19460+out:
4bf69007
AM
19461+ release_nx_info(new_nxi, NULL);
19462+ put_nx_info(new_nxi);
19463+ return ret;
d337f35e
JR
19464+}
19465+
d337f35e 19466+
4bf69007
AM
19467+int vc_net_migrate(struct nx_info *nxi, void __user *data)
19468+{
19469+ return nx_migrate_task(current, nxi);
19470+}
d337f35e 19471+
2380c486 19472+
4bf69007
AM
19473+static inline
19474+struct nx_addr_v4 *__find_v4_addr(struct nx_info *nxi,
19475+ __be32 ip, __be32 ip2, __be32 mask, uint16_t type, uint16_t flags,
19476+ struct nx_addr_v4 **prev)
d337f35e 19477+{
4bf69007
AM
19478+ struct nx_addr_v4 *nxa = &nxi->v4;
19479+
19480+ for (; nxa; nxa = nxa->next) {
19481+ if ((nxa->ip[0].s_addr == ip) &&
19482+ (nxa->ip[1].s_addr == ip2) &&
19483+ (nxa->mask.s_addr == mask) &&
19484+ (nxa->type == type) &&
19485+ (nxa->flags == flags))
19486+ return nxa;
19487+
19488+ /* save previous entry */
19489+ if (prev)
19490+ *prev = nxa;
19491+ }
19492+ return NULL;
2380c486
JR
19493+}
19494+
4bf69007
AM
19495+int do_add_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask,
19496+ uint16_t type, uint16_t flags)
d337f35e 19497+{
4bf69007
AM
19498+ struct nx_addr_v4 *nxa = NULL;
19499+ struct nx_addr_v4 *new = __alloc_nx_addr_v4();
5cb1760b 19500+ unsigned long irqflags;
4bf69007 19501+ int ret = -EEXIST;
d337f35e 19502+
4bf69007
AM
19503+ if (IS_ERR(new))
19504+ return PTR_ERR(new);
d337f35e 19505+
5cb1760b 19506+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19507+ if (__find_v4_addr(nxi, ip, ip2, mask, type, flags, &nxa))
19508+ goto out_unlock;
2380c486 19509+
4bf69007
AM
19510+ if (NX_IPV4(nxi)) {
19511+ nxa->next = new;
19512+ nxa = new;
19513+ new = NULL;
19514+
19515+ /* remove single ip for ip list */
19516+ nxi->nx_flags &= ~NXF_SINGLE_IP;
19517+ }
19518+
19519+ nxa->ip[0].s_addr = ip;
19520+ nxa->ip[1].s_addr = ip2;
19521+ nxa->mask.s_addr = mask;
19522+ nxa->type = type;
19523+ nxa->flags = flags;
19524+ ret = 0;
19525+out_unlock:
5cb1760b 19526+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19527+ if (new)
19528+ __dealloc_nx_addr_v4(new);
19529+ return ret;
d337f35e
JR
19530+}
19531+
4bf69007
AM
19532+int do_remove_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask,
19533+ uint16_t type, uint16_t flags)
2380c486 19534+{
4bf69007
AM
19535+ struct nx_addr_v4 *nxa = NULL;
19536+ struct nx_addr_v4 *old = NULL;
5cb1760b 19537+ unsigned long irqflags;
4bf69007 19538+ int ret = 0;
2380c486 19539+
5cb1760b 19540+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19541+ switch (type) {
19542+ case NXA_TYPE_ADDR:
19543+ old = __find_v4_addr(nxi, ip, ip2, mask, type, flags, &nxa);
19544+ if (old) {
19545+ if (nxa) {
19546+ nxa->next = old->next;
19547+ old->next = NULL;
19548+ } else {
19549+ if (old->next) {
19550+ nxa = old;
19551+ old = old->next;
19552+ *nxa = *old;
19553+ old->next = NULL;
19554+ } else {
19555+ memset(old, 0, sizeof(*old));
19556+ old = NULL;
19557+ }
19558+ }
19559+ } else
19560+ ret = -ESRCH;
19561+ break;
2380c486 19562+
4bf69007
AM
19563+ case NXA_TYPE_ANY:
19564+ nxa = &nxi->v4;
19565+ old = nxa->next;
19566+ memset(nxa, 0, sizeof(*nxa));
19567+ break;
19568+
19569+ default:
19570+ ret = -EINVAL;
19571+ }
5cb1760b 19572+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19573+ __dealloc_nx_addr_v4_all(old);
19574+ return ret;
2380c486
JR
19575+}
19576+
4bf69007
AM
19577+
19578+int vc_net_add(struct nx_info *nxi, void __user *data)
2380c486 19579+{
4bf69007
AM
19580+ struct vcmd_net_addr_v0 vc_data;
19581+ int index, ret = 0;
2380c486 19582+
4bf69007 19583+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486
JR
19584+ return -EFAULT;
19585+
4bf69007
AM
19586+ switch (vc_data.type) {
19587+ case NXA_TYPE_IPV4:
19588+ if ((vc_data.count < 1) || (vc_data.count > 4))
19589+ return -EINVAL;
adc1caaa 19590+
4bf69007
AM
19591+ index = 0;
19592+ while (index < vc_data.count) {
19593+ ret = do_add_v4_addr(nxi, vc_data.ip[index].s_addr, 0,
19594+ vc_data.mask[index].s_addr, NXA_TYPE_ADDR, 0);
19595+ if (ret)
19596+ return ret;
19597+ index++;
19598+ }
19599+ ret = index;
19600+ break;
2380c486 19601+
4bf69007
AM
19602+ case NXA_TYPE_IPV4|NXA_MOD_BCAST:
19603+ nxi->v4_bcast = vc_data.ip[0];
19604+ ret = 1;
19605+ break;
2380c486 19606+
4bf69007
AM
19607+ case NXA_TYPE_IPV4|NXA_MOD_LBACK:
19608+ nxi->v4_lback = vc_data.ip[0];
19609+ ret = 1;
19610+ break;
19611+
19612+ default:
19613+ ret = -EINVAL;
19614+ break;
19615+ }
19616+ return ret;
19617+}
19618+
19619+int vc_net_remove(struct nx_info *nxi, void __user *data)
19620+{
19621+ struct vcmd_net_addr_v0 vc_data;
19622+
19623+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486 19624+ return -EFAULT;
4bf69007
AM
19625+
19626+ switch (vc_data.type) {
19627+ case NXA_TYPE_ANY:
19628+ return do_remove_v4_addr(nxi, 0, 0, 0, vc_data.type, 0);
19629+ default:
19630+ return -EINVAL;
19631+ }
2380c486
JR
19632+ return 0;
19633+}
19634+
d337f35e 19635+
4bf69007 19636+int vc_net_add_ipv4_v1(struct nx_info *nxi, void __user *data)
d337f35e 19637+{
4bf69007
AM
19638+ struct vcmd_net_addr_ipv4_v1 vc_data;
19639+
19640+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19641+ return -EFAULT;
19642+
19643+ switch (vc_data.type) {
19644+ case NXA_TYPE_ADDR:
19645+ case NXA_TYPE_MASK:
19646+ return do_add_v4_addr(nxi, vc_data.ip.s_addr, 0,
19647+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
19648+
19649+ case NXA_TYPE_ADDR | NXA_MOD_BCAST:
19650+ nxi->v4_bcast = vc_data.ip;
19651+ break;
19652+
19653+ case NXA_TYPE_ADDR | NXA_MOD_LBACK:
19654+ nxi->v4_lback = vc_data.ip;
19655+ break;
19656+
19657+ default:
19658+ return -EINVAL;
19659+ }
19660+ return 0;
d337f35e
JR
19661+}
19662+
4bf69007 19663+int vc_net_add_ipv4(struct nx_info *nxi, void __user *data)
d337f35e 19664+{
4bf69007 19665+ struct vcmd_net_addr_ipv4_v2 vc_data;
d337f35e 19666+
4bf69007
AM
19667+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19668+ return -EFAULT;
19669+
19670+ switch (vc_data.type) {
19671+ case NXA_TYPE_ADDR:
19672+ case NXA_TYPE_MASK:
19673+ case NXA_TYPE_RANGE:
19674+ return do_add_v4_addr(nxi, vc_data.ip.s_addr, vc_data.ip2.s_addr,
19675+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
19676+
19677+ case NXA_TYPE_ADDR | NXA_MOD_BCAST:
19678+ nxi->v4_bcast = vc_data.ip;
19679+ break;
19680+
19681+ case NXA_TYPE_ADDR | NXA_MOD_LBACK:
19682+ nxi->v4_lback = vc_data.ip;
19683+ break;
19684+
19685+ default:
19686+ return -EINVAL;
19687+ }
19688+ return 0;
d337f35e
JR
19689+}
19690+
4bf69007 19691+int vc_net_rem_ipv4_v1(struct nx_info *nxi, void __user *data)
d337f35e 19692+{
4bf69007
AM
19693+ struct vcmd_net_addr_ipv4_v1 vc_data;
19694+
19695+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19696+ return -EFAULT;
19697+
19698+ return do_remove_v4_addr(nxi, vc_data.ip.s_addr, 0,
19699+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
d337f35e
JR
19700+}
19701+
4bf69007 19702+int vc_net_rem_ipv4(struct nx_info *nxi, void __user *data)
d337f35e 19703+{
4bf69007
AM
19704+ struct vcmd_net_addr_ipv4_v2 vc_data;
19705+
19706+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19707+ return -EFAULT;
19708+
19709+ return do_remove_v4_addr(nxi, vc_data.ip.s_addr, vc_data.ip2.s_addr,
19710+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
d337f35e 19711+}
d337f35e 19712+
4bf69007 19713+#ifdef CONFIG_IPV6
d337f35e
JR
19714+
19715+static inline
4bf69007
AM
19716+struct nx_addr_v6 *__find_v6_addr(struct nx_info *nxi,
19717+ struct in6_addr *ip, struct in6_addr *mask,
19718+ uint32_t prefix, uint16_t type, uint16_t flags,
19719+ struct nx_addr_v6 **prev)
d337f35e 19720+{
4bf69007 19721+ struct nx_addr_v6 *nxa = &nxi->v6;
d337f35e 19722+
4bf69007
AM
19723+ for (; nxa; nxa = nxa->next) {
19724+ if (ipv6_addr_equal(&nxa->ip, ip) &&
19725+ ipv6_addr_equal(&nxa->mask, mask) &&
19726+ (nxa->prefix == prefix) &&
19727+ (nxa->type == type) &&
19728+ (nxa->flags == flags))
19729+ return nxa;
19730+
19731+ /* save previous entry */
19732+ if (prev)
19733+ *prev = nxa;
19734+ }
19735+ return NULL;
d337f35e
JR
19736+}
19737+
d337f35e 19738+
4bf69007
AM
19739+int do_add_v6_addr(struct nx_info *nxi,
19740+ struct in6_addr *ip, struct in6_addr *mask,
19741+ uint32_t prefix, uint16_t type, uint16_t flags)
19742+{
19743+ struct nx_addr_v6 *nxa = NULL;
19744+ struct nx_addr_v6 *new = __alloc_nx_addr_v6();
5cb1760b 19745+ unsigned long irqflags;
4bf69007 19746+ int ret = -EEXIST;
d337f35e 19747+
4bf69007
AM
19748+ if (IS_ERR(new))
19749+ return PTR_ERR(new);
d337f35e 19750+
5cb1760b 19751+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19752+ if (__find_v6_addr(nxi, ip, mask, prefix, type, flags, &nxa))
19753+ goto out_unlock;
d337f35e 19754+
4bf69007
AM
19755+ if (NX_IPV6(nxi)) {
19756+ nxa->next = new;
19757+ nxa = new;
19758+ new = NULL;
19759+ }
d337f35e 19760+
4bf69007
AM
19761+ nxa->ip = *ip;
19762+ nxa->mask = *mask;
19763+ nxa->prefix = prefix;
19764+ nxa->type = type;
19765+ nxa->flags = flags;
19766+ ret = 0;
19767+out_unlock:
5cb1760b 19768+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19769+ if (new)
19770+ __dealloc_nx_addr_v6(new);
19771+ return ret;
19772+}
d337f35e 19773+
4bf69007
AM
19774+int do_remove_v6_addr(struct nx_info *nxi,
19775+ struct in6_addr *ip, struct in6_addr *mask,
19776+ uint32_t prefix, uint16_t type, uint16_t flags)
d337f35e 19777+{
4bf69007
AM
19778+ struct nx_addr_v6 *nxa = NULL;
19779+ struct nx_addr_v6 *old = NULL;
5cb1760b 19780+ unsigned long irqflags;
4bf69007 19781+ int ret = 0;
d337f35e 19782+
5cb1760b 19783+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19784+ switch (type) {
19785+ case NXA_TYPE_ADDR:
19786+ old = __find_v6_addr(nxi, ip, mask, prefix, type, flags, &nxa);
19787+ if (old) {
19788+ if (nxa) {
19789+ nxa->next = old->next;
19790+ old->next = NULL;
19791+ } else {
19792+ if (old->next) {
19793+ nxa = old;
19794+ old = old->next;
19795+ *nxa = *old;
19796+ old->next = NULL;
19797+ } else {
19798+ memset(old, 0, sizeof(*old));
19799+ old = NULL;
19800+ }
19801+ }
19802+ } else
19803+ ret = -ESRCH;
19804+ break;
d337f35e 19805+
4bf69007
AM
19806+ case NXA_TYPE_ANY:
19807+ nxa = &nxi->v6;
19808+ old = nxa->next;
19809+ memset(nxa, 0, sizeof(*nxa));
d337f35e
JR
19810+ break;
19811+
d337f35e 19812+ default:
4bf69007 19813+ ret = -EINVAL;
d337f35e 19814+ }
5cb1760b 19815+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19816+ __dealloc_nx_addr_v6_all(old);
19817+ return ret;
d337f35e
JR
19818+}
19819+
4bf69007 19820+int vc_net_add_ipv6(struct nx_info *nxi, void __user *data)
d337f35e 19821+{
4bf69007 19822+ struct vcmd_net_addr_ipv6_v1 vc_data;
d337f35e 19823+
4bf69007 19824+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
19825+ return -EFAULT;
19826+
4bf69007
AM
19827+ switch (vc_data.type) {
19828+ case NXA_TYPE_ADDR:
19829+ memset(&vc_data.mask, ~0, sizeof(vc_data.mask));
19830+ /* fallthrough */
19831+ case NXA_TYPE_MASK:
19832+ return do_add_v6_addr(nxi, &vc_data.ip, &vc_data.mask,
19833+ vc_data.prefix, vc_data.type, vc_data.flags);
19834+ default:
19835+ return -EINVAL;
19836+ }
19837+ return 0;
19838+}
d337f35e 19839+
4bf69007
AM
19840+int vc_net_remove_ipv6(struct nx_info *nxi, void __user *data)
19841+{
19842+ struct vcmd_net_addr_ipv6_v1 vc_data;
19843+
19844+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19845+ return -EFAULT;
19846+
19847+ switch (vc_data.type) {
19848+ case NXA_TYPE_ADDR:
19849+ memset(&vc_data.mask, ~0, sizeof(vc_data.mask));
19850+ /* fallthrough */
19851+ case NXA_TYPE_MASK:
19852+ return do_remove_v6_addr(nxi, &vc_data.ip, &vc_data.mask,
19853+ vc_data.prefix, vc_data.type, vc_data.flags);
19854+ case NXA_TYPE_ANY:
19855+ return do_remove_v6_addr(nxi, NULL, NULL, 0, vc_data.type, 0);
19856+ default:
19857+ return -EINVAL;
19858+ }
19859+ return 0;
d337f35e
JR
19860+}
19861+
4bf69007 19862+#endif /* CONFIG_IPV6 */
d337f35e 19863+
4bf69007
AM
19864+
19865+int vc_get_nflags(struct nx_info *nxi, void __user *data)
d337f35e 19866+{
4bf69007 19867+ struct vcmd_net_flags_v0 vc_data;
d337f35e 19868+
4bf69007 19869+ vc_data.flagword = nxi->nx_flags;
d337f35e 19870+
4bf69007
AM
19871+ /* special STATE flag handling */
19872+ vc_data.mask = vs_mask_flags(~0ULL, nxi->nx_flags, NXF_ONE_TIME);
d337f35e 19873+
4bf69007
AM
19874+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
19875+ return -EFAULT;
19876+ return 0;
d337f35e
JR
19877+}
19878+
4bf69007
AM
19879+int vc_set_nflags(struct nx_info *nxi, void __user *data)
19880+{
19881+ struct vcmd_net_flags_v0 vc_data;
19882+ uint64_t mask, trigger;
19883+
19884+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
19885+ return -EFAULT;
d337f35e 19886+
4bf69007
AM
19887+ /* special STATE flag handling */
19888+ mask = vs_mask_mask(vc_data.mask, nxi->nx_flags, NXF_ONE_TIME);
19889+ trigger = (mask & nxi->nx_flags) ^ (mask & vc_data.flagword);
d337f35e 19890+
4bf69007
AM
19891+ nxi->nx_flags = vs_mask_flags(nxi->nx_flags,
19892+ vc_data.flagword, mask);
19893+ if (trigger & NXF_PERSISTENT)
19894+ nx_update_persistent(nxi);
19895+
19896+ return 0;
19897+}
19898+
19899+int vc_get_ncaps(struct nx_info *nxi, void __user *data)
d337f35e 19900+{
4bf69007 19901+ struct vcmd_net_caps_v0 vc_data;
d337f35e 19902+
4bf69007
AM
19903+ vc_data.ncaps = nxi->nx_ncaps;
19904+ vc_data.cmask = ~0ULL;
d337f35e 19905+
2380c486 19906+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
4bf69007
AM
19907+ return -EFAULT;
19908+ return 0;
d337f35e
JR
19909+}
19910+
4bf69007
AM
19911+int vc_set_ncaps(struct nx_info *nxi, void __user *data)
19912+{
19913+ struct vcmd_net_caps_v0 vc_data;
19914+
19915+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
19916+ return -EFAULT;
19917+
19918+ nxi->nx_ncaps = vs_mask_flags(nxi->nx_ncaps,
19919+ vc_data.ncaps, vc_data.cmask);
19920+ return 0;
19921+}
19922+
19923+
19924+#include <linux/module.h>
19925+
19926+module_init(init_network);
19927+
19928+EXPORT_SYMBOL_GPL(free_nx_info);
19929+EXPORT_SYMBOL_GPL(unhash_nx_info);
19930+
8de2f54c 19931diff -NurpP --minimal linux-4.4.111/kernel/vserver/proc.c linux-4.4.111-vs2.3.9.5/kernel/vserver/proc.c
f19bd705 19932--- linux-4.4.111/kernel/vserver/proc.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c
AM
19933+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/proc.c 2018-01-11 12:02:42.000000000 +0000
19934@@ -0,0 +1,1040 @@
d337f35e 19935+/*
4bf69007 19936+ * linux/kernel/vserver/proc.c
d337f35e 19937+ *
4bf69007 19938+ * Virtual Context Support
d337f35e 19939+ *
927ca606 19940+ * Copyright (C) 2003-2011 Herbert P?tzl
d337f35e 19941+ *
4bf69007
AM
19942+ * V0.01 basic structure
19943+ * V0.02 adaptation vs1.3.0
19944+ * V0.03 proc permissions
19945+ * V0.04 locking/generic
19946+ * V0.05 next generation procfs
19947+ * V0.06 inode validation
19948+ * V0.07 generic rewrite vid
19949+ * V0.08 remove inode type
19950+ * V0.09 added u/wmask info
d337f35e
JR
19951+ *
19952+ */
19953+
4bf69007 19954+#include <linux/proc_fs.h>
ec22aa5c 19955+#include <linux/fs_struct.h>
4bf69007
AM
19956+#include <linux/mount.h>
19957+#include <linux/namei.h>
19958+#include <asm/unistd.h>
2380c486 19959+
d337f35e 19960+#include <linux/vs_context.h>
4bf69007
AM
19961+#include <linux/vs_network.h>
19962+#include <linux/vs_cvirt.h>
d337f35e 19963+
4bf69007
AM
19964+#include <linux/in.h>
19965+#include <linux/inetdevice.h>
19966+#include <linux/vs_inet.h>
19967+#include <linux/vs_inet6.h>
d337f35e 19968+
4bf69007 19969+#include <linux/vserver/global.h>
d337f35e 19970+
4bf69007
AM
19971+#include "cvirt_proc.h"
19972+#include "cacct_proc.h"
19973+#include "limit_proc.h"
19974+#include "sched_proc.h"
19975+#include "vci_config.h"
d337f35e 19976+
09be7631
JR
19977+#include <../../fs/proc/internal.h>
19978+
2380c486 19979+
4bf69007
AM
19980+static inline char *print_cap_t(char *buffer, kernel_cap_t *c)
19981+{
19982+ unsigned __capi;
2380c486 19983+
4bf69007
AM
19984+ CAP_FOR_EACH_U32(__capi) {
19985+ buffer += sprintf(buffer, "%08x",
19986+ c->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]);
19987+ }
19988+ return buffer;
19989+}
2380c486 19990+
d337f35e 19991+
4bf69007 19992+static struct proc_dir_entry *proc_virtual;
d337f35e 19993+
4bf69007 19994+static struct proc_dir_entry *proc_virtnet;
d337f35e 19995+
d337f35e 19996+
4bf69007 19997+/* first the actual feeds */
d337f35e 19998+
d337f35e 19999+
4bf69007
AM
20000+static int proc_vci(char *buffer)
20001+{
20002+ return sprintf(buffer,
20003+ "VCIVersion:\t%04x:%04x\n"
20004+ "VCISyscall:\t%d\n"
20005+ "VCIKernel:\t%08x\n",
20006+ VCI_VERSION >> 16,
20007+ VCI_VERSION & 0xFFFF,
20008+ __NR_vserver,
20009+ vci_kernel_config());
20010+}
d337f35e 20011+
4bf69007
AM
20012+static int proc_virtual_info(char *buffer)
20013+{
20014+ return proc_vci(buffer);
d337f35e
JR
20015+}
20016+
4bf69007
AM
20017+static int proc_virtual_status(char *buffer)
20018+{
20019+ return sprintf(buffer,
20020+ "#CTotal:\t%d\n"
20021+ "#CActive:\t%d\n"
20022+ "#NSProxy:\t%d\t%d %d %d %d %d %d\n"
20023+ "#InitTask:\t%d\t%d %d\n",
20024+ atomic_read(&vx_global_ctotal),
20025+ atomic_read(&vx_global_cactive),
20026+ atomic_read(&vs_global_nsproxy),
20027+ atomic_read(&vs_global_fs),
20028+ atomic_read(&vs_global_mnt_ns),
20029+ atomic_read(&vs_global_uts_ns),
20030+ atomic_read(&nr_ipc_ns),
20031+ atomic_read(&vs_global_user_ns),
20032+ atomic_read(&vs_global_pid_ns),
20033+ atomic_read(&init_task.usage),
20034+ atomic_read(&init_task.nsproxy->count),
20035+ init_task.fs->users);
20036+}
2380c486 20037+
2380c486 20038+
4bf69007 20039+int proc_vxi_info(struct vx_info *vxi, char *buffer)
d337f35e 20040+{
4bf69007 20041+ int length;
d337f35e 20042+
4bf69007
AM
20043+ length = sprintf(buffer,
20044+ "ID:\t%d\n"
20045+ "Info:\t%p\n"
20046+ "Init:\t%d\n"
20047+ "OOM:\t%lld\n",
20048+ vxi->vx_id,
20049+ vxi,
20050+ vxi->vx_initpid,
20051+ vxi->vx_badness_bias);
20052+ return length;
d337f35e
JR
20053+}
20054+
4bf69007 20055+int proc_vxi_status(struct vx_info *vxi, char *buffer)
d337f35e 20056+{
4bf69007 20057+ char *orig = buffer;
d337f35e 20058+
4bf69007
AM
20059+ buffer += sprintf(buffer,
20060+ "UseCnt:\t%d\n"
20061+ "Tasks:\t%d\n"
20062+ "Flags:\t%016llx\n",
20063+ atomic_read(&vxi->vx_usecnt),
20064+ atomic_read(&vxi->vx_tasks),
20065+ (unsigned long long)vxi->vx_flags);
d337f35e 20066+
4bf69007
AM
20067+ buffer += sprintf(buffer, "BCaps:\t");
20068+ buffer = print_cap_t(buffer, &vxi->vx_bcaps);
20069+ buffer += sprintf(buffer, "\n");
ab30d09f 20070+
4bf69007
AM
20071+ buffer += sprintf(buffer,
20072+ "CCaps:\t%016llx\n"
20073+ "Umask:\t%16llx\n"
20074+ "Wmask:\t%16llx\n"
20075+ "Spaces:\t%08lx %08lx\n",
20076+ (unsigned long long)vxi->vx_ccaps,
20077+ (unsigned long long)vxi->vx_umask,
20078+ (unsigned long long)vxi->vx_wmask,
20079+ vxi->space[0].vx_nsmask, vxi->space[1].vx_nsmask);
20080+ return buffer - orig;
20081+}
ab30d09f 20082+
4bf69007
AM
20083+int proc_vxi_limit(struct vx_info *vxi, char *buffer)
20084+{
20085+ return vx_info_proc_limit(&vxi->limit, buffer);
20086+}
d337f35e 20087+
4bf69007
AM
20088+int proc_vxi_sched(struct vx_info *vxi, char *buffer)
20089+{
20090+ int cpu, length;
d337f35e 20091+
4bf69007
AM
20092+ length = vx_info_proc_sched(&vxi->sched, buffer);
20093+ for_each_online_cpu(cpu) {
20094+ length += vx_info_proc_sched_pc(
20095+ &vx_per_cpu(vxi, sched_pc, cpu),
20096+ buffer + length, cpu);
ec22aa5c 20097+ }
4bf69007
AM
20098+ return length;
20099+}
ec22aa5c 20100+
4bf69007
AM
20101+int proc_vxi_nsproxy0(struct vx_info *vxi, char *buffer)
20102+{
20103+ return vx_info_proc_nsproxy(vxi->space[0].vx_nsproxy, buffer);
20104+}
d337f35e 20105+
4bf69007
AM
20106+int proc_vxi_nsproxy1(struct vx_info *vxi, char *buffer)
20107+{
20108+ return vx_info_proc_nsproxy(vxi->space[1].vx_nsproxy, buffer);
20109+}
ec22aa5c 20110+
4bf69007
AM
20111+int proc_vxi_cvirt(struct vx_info *vxi, char *buffer)
20112+{
20113+ int cpu, length;
d33d7b00 20114+
4bf69007
AM
20115+ vx_update_load(vxi);
20116+ length = vx_info_proc_cvirt(&vxi->cvirt, buffer);
20117+ for_each_online_cpu(cpu) {
20118+ length += vx_info_proc_cvirt_pc(
20119+ &vx_per_cpu(vxi, cvirt_pc, cpu),
20120+ buffer + length, cpu);
3bac966d 20121+ }
4bf69007
AM
20122+ return length;
20123+}
3bac966d 20124+
4bf69007
AM
20125+int proc_vxi_cacct(struct vx_info *vxi, char *buffer)
20126+{
20127+ return vx_info_proc_cacct(&vxi->cacct, buffer);
d337f35e
JR
20128+}
20129+
20130+
4bf69007 20131+static int proc_virtnet_info(char *buffer)
d337f35e 20132+{
4bf69007
AM
20133+ return proc_vci(buffer);
20134+}
ab30d09f 20135+
4bf69007
AM
20136+static int proc_virtnet_status(char *buffer)
20137+{
20138+ return sprintf(buffer,
20139+ "#CTotal:\t%d\n"
20140+ "#CActive:\t%d\n",
20141+ atomic_read(&nx_global_ctotal),
20142+ atomic_read(&nx_global_cactive));
20143+}
d337f35e 20144+
4bf69007
AM
20145+int proc_nxi_info(struct nx_info *nxi, char *buffer)
20146+{
20147+ struct nx_addr_v4 *v4a;
20148+#ifdef CONFIG_IPV6
20149+ struct nx_addr_v6 *v6a;
20150+#endif
20151+ int length, i;
ab30d09f 20152+
4bf69007
AM
20153+ length = sprintf(buffer,
20154+ "ID:\t%d\n"
20155+ "Info:\t%p\n"
20156+ "Bcast:\t" NIPQUAD_FMT "\n"
20157+ "Lback:\t" NIPQUAD_FMT "\n",
20158+ nxi->nx_id,
20159+ nxi,
20160+ NIPQUAD(nxi->v4_bcast.s_addr),
20161+ NIPQUAD(nxi->v4_lback.s_addr));
ab30d09f 20162+
4bf69007
AM
20163+ if (!NX_IPV4(nxi))
20164+ goto skip_v4;
20165+ for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next)
20166+ length += sprintf(buffer + length, "%d:\t" NXAV4_FMT "\n",
20167+ i, NXAV4(v4a));
20168+skip_v4:
20169+#ifdef CONFIG_IPV6
20170+ if (!NX_IPV6(nxi))
20171+ goto skip_v6;
20172+ for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next)
20173+ length += sprintf(buffer + length, "%d:\t" NXAV6_FMT "\n",
20174+ i, NXAV6(v6a));
20175+skip_v6:
20176+#endif
20177+ return length;
20178+}
2380c486 20179+
4bf69007
AM
20180+int proc_nxi_status(struct nx_info *nxi, char *buffer)
20181+{
20182+ int length;
ec22aa5c 20183+
4bf69007
AM
20184+ length = sprintf(buffer,
20185+ "UseCnt:\t%d\n"
20186+ "Tasks:\t%d\n"
20187+ "Flags:\t%016llx\n"
20188+ "NCaps:\t%016llx\n",
20189+ atomic_read(&nxi->nx_usecnt),
20190+ atomic_read(&nxi->nx_tasks),
20191+ (unsigned long long)nxi->nx_flags,
20192+ (unsigned long long)nxi->nx_ncaps);
20193+ return length;
20194+}
ec22aa5c 20195+
ec22aa5c 20196+
d337f35e 20197+
4bf69007 20198+/* here the inode helpers */
d337f35e 20199+
4bf69007
AM
20200+struct vs_entry {
20201+ int len;
20202+ char *name;
20203+ mode_t mode;
20204+ struct inode_operations *iop;
20205+ struct file_operations *fop;
20206+ union proc_op op;
20207+};
d337f35e 20208+
4bf69007
AM
20209+static struct inode *vs_proc_make_inode(struct super_block *sb, struct vs_entry *p)
20210+{
20211+ struct inode *inode = new_inode(sb);
3bac966d 20212+
4bf69007
AM
20213+ if (!inode)
20214+ goto out;
3bac966d 20215+
4bf69007
AM
20216+ inode->i_mode = p->mode;
20217+ if (p->iop)
20218+ inode->i_op = p->iop;
20219+ if (p->fop)
20220+ inode->i_fop = p->fop;
3bac966d 20221+
4bf69007
AM
20222+ set_nlink(inode, (p->mode & S_IFDIR) ? 2 : 1);
20223+ inode->i_flags |= S_IMMUTABLE;
3bac966d 20224+
4bf69007 20225+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
2380c486 20226+
8ce283e1
AM
20227+ i_uid_write(inode, 0);
20228+ i_gid_write(inode, 0);
20229+ i_tag_write(inode, 0);
4bf69007
AM
20230+out:
20231+ return inode;
d337f35e
JR
20232+}
20233+
4bf69007
AM
20234+static struct dentry *vs_proc_instantiate(struct inode *dir,
20235+ struct dentry *dentry, int id, void *ptr)
2380c486 20236+{
4bf69007
AM
20237+ struct vs_entry *p = ptr;
20238+ struct inode *inode = vs_proc_make_inode(dir->i_sb, p);
20239+ struct dentry *error = ERR_PTR(-EINVAL);
2380c486 20240+
4bf69007
AM
20241+ if (!inode)
20242+ goto out;
2380c486 20243+
4bf69007
AM
20244+ PROC_I(inode)->op = p->op;
20245+ PROC_I(inode)->fd = id;
20246+ d_add(dentry, inode);
20247+ error = NULL;
20248+out:
20249+ return error;
2380c486
JR
20250+}
20251+
4bf69007 20252+/* Lookups */
2380c486 20253+
09be7631
JR
20254+typedef struct dentry *vx_instantiate_t(struct inode *, struct dentry *, int, void *);
20255+
2380c486 20256+
4bf69007
AM
20257+/*
20258+ * Fill a directory entry.
20259+ *
20260+ * If possible create the dcache entry and derive our inode number and
20261+ * file type from dcache entry.
20262+ *
20263+ * Since all of the proc inode numbers are dynamically generated, the inode
20264+ * numbers do not exist until the inode is cache. This means creating the
c2e5f7c8
JR
20265+ * the dcache entry in iterate is necessary to keep the inode numbers
20266+ * reported by iterate in sync with the inode numbers reported
4bf69007
AM
20267+ * by stat.
20268+ */
c2e5f7c8 20269+static int vx_proc_fill_cache(struct file *filp, struct dir_context *ctx,
09be7631 20270+ char *name, int len, vx_instantiate_t instantiate, int id, void *ptr)
2380c486 20271+{
927ca606 20272+ struct dentry *child, *dir = filp->f_path.dentry;
4bf69007
AM
20273+ struct inode *inode;
20274+ struct qstr qname;
20275+ ino_t ino = 0;
20276+ unsigned type = DT_UNKNOWN;
d337f35e 20277+
4bf69007
AM
20278+ qname.name = name;
20279+ qname.len = len;
20280+ qname.hash = full_name_hash(name, len);
d337f35e 20281+
4bf69007
AM
20282+ child = d_lookup(dir, &qname);
20283+ if (!child) {
20284+ struct dentry *new;
20285+ new = d_alloc(dir, &qname);
20286+ if (new) {
20287+ child = instantiate(dir->d_inode, new, id, ptr);
20288+ if (child)
20289+ dput(new);
20290+ else
20291+ child = new;
20292+ }
20293+ }
20294+ if (!child || IS_ERR(child) || !child->d_inode)
20295+ goto end_instantiate;
20296+ inode = child->d_inode;
20297+ if (inode) {
20298+ ino = inode->i_ino;
20299+ type = inode->i_mode >> 12;
20300+ }
20301+ dput(child);
20302+end_instantiate:
20303+ if (!ino)
4bf69007 20304+ ino = 1;
c2e5f7c8 20305+ return !dir_emit(ctx, name, len, ino, type);
4bf69007 20306+}
d337f35e 20307+
d337f35e 20308+
d337f35e 20309+
4bf69007 20310+/* get and revalidate vx_info/xid */
2380c486 20311+
4bf69007
AM
20312+static inline
20313+struct vx_info *get_proc_vx_info(struct inode *inode)
20314+{
20315+ return lookup_vx_info(PROC_I(inode)->fd);
d337f35e
JR
20316+}
20317+
4bf69007 20318+static int proc_xid_revalidate(struct dentry *dentry, unsigned int flags)
d337f35e 20319+{
4bf69007 20320+ struct inode *inode = dentry->d_inode;
61333608 20321+ vxid_t xid = PROC_I(inode)->fd;
2380c486 20322+
4bf69007
AM
20323+ if (flags & LOOKUP_RCU) /* FIXME: can be dropped? */
20324+ return -ECHILD;
2380c486 20325+
4bf69007
AM
20326+ if (!xid || xid_is_hashed(xid))
20327+ return 1;
20328+ d_drop(dentry);
d337f35e
JR
20329+ return 0;
20330+}
20331+
d337f35e 20332+
4bf69007 20333+/* get and revalidate nx_info/nid */
d337f35e 20334+
4bf69007
AM
20335+static int proc_nid_revalidate(struct dentry *dentry, unsigned int flags)
20336+{
20337+ struct inode *inode = dentry->d_inode;
61333608 20338+ vnid_t nid = PROC_I(inode)->fd;
2380c486 20339+
4bf69007
AM
20340+ if (flags & LOOKUP_RCU) /* FIXME: can be dropped? */
20341+ return -ECHILD;
2380c486 20342+
4bf69007
AM
20343+ if (!nid || nid_is_hashed(nid))
20344+ return 1;
20345+ d_drop(dentry);
20346+ return 0;
d337f35e
JR
20347+}
20348+
4bf69007
AM
20349+
20350+
20351+#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
20352+
20353+static ssize_t proc_vs_info_read(struct file *file, char __user *buf,
20354+ size_t count, loff_t *ppos)
d337f35e 20355+{
927ca606 20356+ struct inode *inode = file->f_path.dentry->d_inode;
4bf69007
AM
20357+ unsigned long page;
20358+ ssize_t length = 0;
20359+
20360+ if (count > PROC_BLOCK_SIZE)
20361+ count = PROC_BLOCK_SIZE;
20362+
20363+ /* fade that out as soon as stable */
20364+ WARN_ON(PROC_I(inode)->fd);
20365+
20366+ if (!(page = __get_free_page(GFP_KERNEL)))
20367+ return -ENOMEM;
20368+
20369+ BUG_ON(!PROC_I(inode)->op.proc_vs_read);
20370+ length = PROC_I(inode)->op.proc_vs_read((char *)page);
20371+
20372+ if (length >= 0)
20373+ length = simple_read_from_buffer(buf, count, ppos,
20374+ (char *)page, length);
20375+
20376+ free_page(page);
20377+ return length;
d337f35e
JR
20378+}
20379+
4bf69007
AM
20380+static ssize_t proc_vx_info_read(struct file *file, char __user *buf,
20381+ size_t count, loff_t *ppos)
20382+{
927ca606 20383+ struct inode *inode = file->f_path.dentry->d_inode;
4bf69007 20384+ struct vx_info *vxi = NULL;
61333608 20385+ vxid_t xid = PROC_I(inode)->fd;
4bf69007
AM
20386+ unsigned long page;
20387+ ssize_t length = 0;
d337f35e 20388+
4bf69007
AM
20389+ if (count > PROC_BLOCK_SIZE)
20390+ count = PROC_BLOCK_SIZE;
20391+
20392+ /* fade that out as soon as stable */
20393+ WARN_ON(!xid);
20394+ vxi = lookup_vx_info(xid);
20395+ if (!vxi)
20396+ goto out;
d337f35e 20397+
4bf69007
AM
20398+ length = -ENOMEM;
20399+ if (!(page = __get_free_page(GFP_KERNEL)))
20400+ goto out_put;
d337f35e 20401+
4bf69007
AM
20402+ BUG_ON(!PROC_I(inode)->op.proc_vxi_read);
20403+ length = PROC_I(inode)->op.proc_vxi_read(vxi, (char *)page);
d337f35e 20404+
4bf69007
AM
20405+ if (length >= 0)
20406+ length = simple_read_from_buffer(buf, count, ppos,
20407+ (char *)page, length);
d337f35e 20408+
4bf69007
AM
20409+ free_page(page);
20410+out_put:
20411+ put_vx_info(vxi);
20412+out:
20413+ return length;
20414+}
20415+
20416+static ssize_t proc_nx_info_read(struct file *file, char __user *buf,
20417+ size_t count, loff_t *ppos)
d337f35e 20418+{
927ca606 20419+ struct inode *inode = file->f_path.dentry->d_inode;
4bf69007 20420+ struct nx_info *nxi = NULL;
61333608 20421+ vnid_t nid = PROC_I(inode)->fd;
4bf69007
AM
20422+ unsigned long page;
20423+ ssize_t length = 0;
d337f35e 20424+
4bf69007
AM
20425+ if (count > PROC_BLOCK_SIZE)
20426+ count = PROC_BLOCK_SIZE;
d337f35e 20427+
4bf69007
AM
20428+ /* fade that out as soon as stable */
20429+ WARN_ON(!nid);
20430+ nxi = lookup_nx_info(nid);
20431+ if (!nxi)
20432+ goto out;
d337f35e 20433+
4bf69007
AM
20434+ length = -ENOMEM;
20435+ if (!(page = __get_free_page(GFP_KERNEL)))
20436+ goto out_put;
d337f35e 20437+
4bf69007
AM
20438+ BUG_ON(!PROC_I(inode)->op.proc_nxi_read);
20439+ length = PROC_I(inode)->op.proc_nxi_read(nxi, (char *)page);
2380c486 20440+
4bf69007
AM
20441+ if (length >= 0)
20442+ length = simple_read_from_buffer(buf, count, ppos,
20443+ (char *)page, length);
d337f35e 20444+
4bf69007
AM
20445+ free_page(page);
20446+out_put:
20447+ put_nx_info(nxi);
20448+out:
20449+ return length;
20450+}
2380c486 20451+
d337f35e 20452+
763640ca 20453+
4bf69007 20454+/* here comes the lower level */
763640ca 20455+
265d6dcc 20456+
4bf69007
AM
20457+#define NOD(NAME, MODE, IOP, FOP, OP) { \
20458+ .len = sizeof(NAME) - 1, \
20459+ .name = (NAME), \
20460+ .mode = MODE, \
20461+ .iop = IOP, \
20462+ .fop = FOP, \
20463+ .op = OP, \
20464+}
d337f35e 20465+
d337f35e 20466+
4bf69007
AM
20467+#define DIR(NAME, MODE, OTYPE) \
20468+ NOD(NAME, (S_IFDIR | (MODE)), \
20469+ &proc_ ## OTYPE ## _inode_operations, \
20470+ &proc_ ## OTYPE ## _file_operations, { } )
d337f35e 20471+
4bf69007
AM
20472+#define INF(NAME, MODE, OTYPE) \
20473+ NOD(NAME, (S_IFREG | (MODE)), NULL, \
20474+ &proc_vs_info_file_operations, \
20475+ { .proc_vs_read = &proc_##OTYPE } )
d337f35e 20476+
4bf69007
AM
20477+#define VINF(NAME, MODE, OTYPE) \
20478+ NOD(NAME, (S_IFREG | (MODE)), NULL, \
20479+ &proc_vx_info_file_operations, \
20480+ { .proc_vxi_read = &proc_##OTYPE } )
2380c486 20481+
4bf69007
AM
20482+#define NINF(NAME, MODE, OTYPE) \
20483+ NOD(NAME, (S_IFREG | (MODE)), NULL, \
20484+ &proc_nx_info_file_operations, \
20485+ { .proc_nxi_read = &proc_##OTYPE } )
d337f35e 20486+
d337f35e 20487+
4bf69007
AM
20488+static struct file_operations proc_vs_info_file_operations = {
20489+ .read = proc_vs_info_read,
20490+};
d337f35e 20491+
4bf69007
AM
20492+static struct file_operations proc_vx_info_file_operations = {
20493+ .read = proc_vx_info_read,
20494+};
d337f35e 20495+
4bf69007
AM
20496+static struct dentry_operations proc_xid_dentry_operations = {
20497+ .d_revalidate = proc_xid_revalidate,
20498+};
d337f35e 20499+
4bf69007
AM
20500+static struct vs_entry vx_base_stuff[] = {
20501+ VINF("info", S_IRUGO, vxi_info),
20502+ VINF("status", S_IRUGO, vxi_status),
20503+ VINF("limit", S_IRUGO, vxi_limit),
20504+ VINF("sched", S_IRUGO, vxi_sched),
20505+ VINF("nsproxy", S_IRUGO, vxi_nsproxy0),
20506+ VINF("nsproxy1",S_IRUGO, vxi_nsproxy1),
20507+ VINF("cvirt", S_IRUGO, vxi_cvirt),
20508+ VINF("cacct", S_IRUGO, vxi_cacct),
20509+ {}
20510+};
2380c486 20511+
d337f35e 20512+
d337f35e 20513+
d337f35e 20514+
4bf69007
AM
20515+static struct dentry *proc_xid_instantiate(struct inode *dir,
20516+ struct dentry *dentry, int id, void *ptr)
20517+{
20518+ dentry->d_op = &proc_xid_dentry_operations;
20519+ return vs_proc_instantiate(dir, dentry, id, ptr);
20520+}
2380c486 20521+
4bf69007
AM
20522+static struct dentry *proc_xid_lookup(struct inode *dir,
20523+ struct dentry *dentry, unsigned int flags)
20524+{
20525+ struct vs_entry *p = vx_base_stuff;
20526+ struct dentry *error = ERR_PTR(-ENOENT);
2380c486 20527+
4bf69007
AM
20528+ for (; p->name; p++) {
20529+ if (p->len != dentry->d_name.len)
20530+ continue;
20531+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20532+ break;
20533+ }
20534+ if (!p->name)
20535+ goto out;
d337f35e 20536+
4bf69007
AM
20537+ error = proc_xid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
20538+out:
20539+ return error;
20540+}
9f7054f1 20541+
c2e5f7c8 20542+static int proc_xid_iterate(struct file *filp, struct dir_context *ctx)
4bf69007 20543+{
927ca606 20544+ struct dentry *dentry = filp->f_path.dentry;
4bf69007
AM
20545+ struct inode *inode = dentry->d_inode;
20546+ struct vs_entry *p = vx_base_stuff;
20547+ int size = sizeof(vx_base_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20548+ int index;
2380c486 20549+
8de2f54c
AM
20550+ if (!dir_emit_dots(filp, ctx))
20551+ return 0;
20552+
20553+ index = ctx->pos - 2;
20554+ if (index < size) {
4bf69007 20555+ for (p += index; p->name; p++) {
c2e5f7c8 20556+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007 20557+ vs_proc_instantiate, PROC_I(inode)->fd, p))
8de2f54c 20558+ return 0;
c2e5f7c8 20559+ ctx->pos++;
4bf69007 20560+ }
d337f35e 20561+ }
4bf69007 20562+ return 1;
d337f35e
JR
20563+}
20564+
20565+
d337f35e 20566+
4bf69007
AM
20567+static struct file_operations proc_nx_info_file_operations = {
20568+ .read = proc_nx_info_read,
20569+};
d337f35e 20570+
4bf69007
AM
20571+static struct dentry_operations proc_nid_dentry_operations = {
20572+ .d_revalidate = proc_nid_revalidate,
20573+};
d337f35e 20574+
4bf69007
AM
20575+static struct vs_entry nx_base_stuff[] = {
20576+ NINF("info", S_IRUGO, nxi_info),
20577+ NINF("status", S_IRUGO, nxi_status),
20578+ {}
20579+};
2380c486 20580+
d337f35e 20581+
4bf69007
AM
20582+static struct dentry *proc_nid_instantiate(struct inode *dir,
20583+ struct dentry *dentry, int id, void *ptr)
d337f35e 20584+{
4bf69007
AM
20585+ dentry->d_op = &proc_nid_dentry_operations;
20586+ return vs_proc_instantiate(dir, dentry, id, ptr);
20587+}
d337f35e 20588+
4bf69007
AM
20589+static struct dentry *proc_nid_lookup(struct inode *dir,
20590+ struct dentry *dentry, unsigned int flags)
20591+{
20592+ struct vs_entry *p = nx_base_stuff;
20593+ struct dentry *error = ERR_PTR(-ENOENT);
d337f35e 20594+
4bf69007
AM
20595+ for (; p->name; p++) {
20596+ if (p->len != dentry->d_name.len)
20597+ continue;
20598+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20599+ break;
20600+ }
20601+ if (!p->name)
20602+ goto out;
d337f35e 20603+
4bf69007
AM
20604+ error = proc_nid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
20605+out:
20606+ return error;
20607+}
d337f35e 20608+
c2e5f7c8 20609+static int proc_nid_iterate(struct file *filp, struct dir_context *ctx)
4bf69007 20610+{
927ca606 20611+ struct dentry *dentry = filp->f_path.dentry;
4bf69007
AM
20612+ struct inode *inode = dentry->d_inode;
20613+ struct vs_entry *p = nx_base_stuff;
20614+ int size = sizeof(nx_base_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20615+ int index;
d337f35e 20616+
8de2f54c
AM
20617+ if (!dir_emit_dots(filp, ctx))
20618+ return 0;
20619+
20620+ index = ctx->pos - 2;
20621+ if (index < size) {
4bf69007 20622+ for (p += index; p->name; p++) {
c2e5f7c8 20623+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007 20624+ vs_proc_instantiate, PROC_I(inode)->fd, p))
8de2f54c 20625+ return 0;
c2e5f7c8 20626+ ctx->pos++;
4bf69007
AM
20627+ }
20628+ }
4bf69007
AM
20629+ return 1;
20630+}
2380c486 20631+
d337f35e 20632+
4bf69007 20633+#define MAX_MULBY10 ((~0U - 9) / 10)
d337f35e 20634+
4bf69007
AM
20635+static inline int atovid(const char *str, int len)
20636+{
20637+ int vid, c;
d337f35e 20638+
4bf69007
AM
20639+ vid = 0;
20640+ while (len-- > 0) {
20641+ c = *str - '0';
20642+ str++;
20643+ if (c > 9)
20644+ return -1;
20645+ if (vid >= MAX_MULBY10)
20646+ return -1;
20647+ vid *= 10;
20648+ vid += c;
20649+ if (!vid)
20650+ return -1;
20651+ }
20652+ return vid;
20653+}
2380c486 20654+
4bf69007 20655+/* now the upper level (virtual) */
2380c486 20656+
2380c486 20657+
4bf69007
AM
20658+static struct file_operations proc_xid_file_operations = {
20659+ .read = generic_read_dir,
c2e5f7c8 20660+ .iterate = proc_xid_iterate,
4bf69007 20661+};
2380c486 20662+
4bf69007
AM
20663+static struct inode_operations proc_xid_inode_operations = {
20664+ .lookup = proc_xid_lookup,
20665+};
d337f35e 20666+
4bf69007
AM
20667+static struct vs_entry vx_virtual_stuff[] = {
20668+ INF("info", S_IRUGO, virtual_info),
20669+ INF("status", S_IRUGO, virtual_status),
20670+ DIR(NULL, S_IRUGO | S_IXUGO, xid),
20671+};
2380c486 20672+
d337f35e 20673+
4bf69007
AM
20674+static struct dentry *proc_virtual_lookup(struct inode *dir,
20675+ struct dentry *dentry, unsigned int flags)
20676+{
20677+ struct vs_entry *p = vx_virtual_stuff;
20678+ struct dentry *error = ERR_PTR(-ENOENT);
20679+ int id = 0;
d337f35e 20680+
4bf69007
AM
20681+ for (; p->name; p++) {
20682+ if (p->len != dentry->d_name.len)
20683+ continue;
20684+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20685+ break;
20686+ }
20687+ if (p->name)
20688+ goto instantiate;
d337f35e 20689+
4bf69007
AM
20690+ id = atovid(dentry->d_name.name, dentry->d_name.len);
20691+ if ((id < 0) || !xid_is_hashed(id))
d337f35e
JR
20692+ goto out;
20693+
4bf69007
AM
20694+instantiate:
20695+ error = proc_xid_instantiate(dir, dentry, id, p);
20696+out:
20697+ return error;
20698+}
d337f35e 20699+
4bf69007
AM
20700+static struct file_operations proc_nid_file_operations = {
20701+ .read = generic_read_dir,
c2e5f7c8 20702+ .iterate = proc_nid_iterate,
4bf69007 20703+};
d337f35e 20704+
4bf69007
AM
20705+static struct inode_operations proc_nid_inode_operations = {
20706+ .lookup = proc_nid_lookup,
20707+};
d337f35e 20708+
4bf69007
AM
20709+static struct vs_entry nx_virtnet_stuff[] = {
20710+ INF("info", S_IRUGO, virtnet_info),
20711+ INF("status", S_IRUGO, virtnet_status),
20712+ DIR(NULL, S_IRUGO | S_IXUGO, nid),
20713+};
d337f35e 20714+
d337f35e 20715+
4bf69007
AM
20716+static struct dentry *proc_virtnet_lookup(struct inode *dir,
20717+ struct dentry *dentry, unsigned int flags)
20718+{
20719+ struct vs_entry *p = nx_virtnet_stuff;
20720+ struct dentry *error = ERR_PTR(-ENOENT);
20721+ int id = 0;
d337f35e 20722+
4bf69007
AM
20723+ for (; p->name; p++) {
20724+ if (p->len != dentry->d_name.len)
20725+ continue;
20726+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20727+ break;
20728+ }
20729+ if (p->name)
20730+ goto instantiate;
d337f35e 20731+
4bf69007
AM
20732+ id = atovid(dentry->d_name.name, dentry->d_name.len);
20733+ if ((id < 0) || !nid_is_hashed(id))
d337f35e
JR
20734+ goto out;
20735+
4bf69007
AM
20736+instantiate:
20737+ error = proc_nid_instantiate(dir, dentry, id, p);
20738+out:
20739+ return error;
20740+}
2380c486 20741+
d337f35e 20742+
4bf69007
AM
20743+#define PROC_MAXVIDS 32
20744+
c2e5f7c8 20745+int proc_virtual_iterate(struct file *filp, struct dir_context *ctx)
4bf69007 20746+{
4bf69007
AM
20747+ struct vs_entry *p = vx_virtual_stuff;
20748+ int size = sizeof(vx_virtual_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20749+ int index;
4bf69007
AM
20750+ unsigned int xid_array[PROC_MAXVIDS];
20751+ char buf[PROC_NUMBUF];
20752+ unsigned int nr_xids, i;
4bf69007 20753+
8de2f54c
AM
20754+ if (!dir_emit_dots(filp, ctx))
20755+ return 0;
20756+
20757+ index = ctx->pos - 2;
20758+ if (index < size) {
4bf69007 20759+ for (p += index; p->name; p++) {
c2e5f7c8 20760+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007 20761+ vs_proc_instantiate, 0, p))
8de2f54c 20762+ return 0;
c2e5f7c8 20763+ ctx->pos++;
d337f35e
JR
20764+ }
20765+ }
8de2f54c
AM
20766+
20767+ index = ctx->pos - size;
20768+ p = &vx_virtual_stuff[size - 1];
20769+ nr_xids = get_xid_list(index, xid_array, PROC_MAXVIDS);
20770+ for (i = 0; i < nr_xids; i++) {
20771+ int n, xid = xid_array[i];
20772+ unsigned int j = PROC_NUMBUF;
20773+
20774+ n = xid;
20775+ do
20776+ buf[--j] = '0' + (n % 10);
20777+ while (n /= 10);
20778+
20779+ if (vx_proc_fill_cache(filp, ctx,
20780+ buf + j, PROC_NUMBUF - j,
20781+ vs_proc_instantiate, xid, p))
20782+ return 0;
20783+ ctx->pos++;
20784+ }
4bf69007 20785+ return 0;
d337f35e
JR
20786+}
20787+
4bf69007
AM
20788+static int proc_virtual_getattr(struct vfsmount *mnt,
20789+ struct dentry *dentry, struct kstat *stat)
d337f35e 20790+{
4bf69007 20791+ struct inode *inode = dentry->d_inode;
d337f35e 20792+
4bf69007
AM
20793+ generic_fillattr(inode, stat);
20794+ stat->nlink = 2 + atomic_read(&vx_global_cactive);
20795+ return 0;
d337f35e
JR
20796+}
20797+
4bf69007
AM
20798+static struct file_operations proc_virtual_dir_operations = {
20799+ .read = generic_read_dir,
c2e5f7c8 20800+ .iterate = proc_virtual_iterate,
d337f35e
JR
20801+};
20802+
4bf69007
AM
20803+static struct inode_operations proc_virtual_dir_inode_operations = {
20804+ .getattr = proc_virtual_getattr,
20805+ .lookup = proc_virtual_lookup,
20806+};
d337f35e 20807+
d337f35e
JR
20808+
20809+
c2e5f7c8 20810+int proc_virtnet_iterate(struct file *filp, struct dir_context *ctx)
d337f35e 20811+{
4bf69007
AM
20812+ struct vs_entry *p = nx_virtnet_stuff;
20813+ int size = sizeof(nx_virtnet_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20814+ int index;
4bf69007
AM
20815+ unsigned int nid_array[PROC_MAXVIDS];
20816+ char buf[PROC_NUMBUF];
20817+ unsigned int nr_nids, i;
d337f35e 20818+
8de2f54c
AM
20819+ if (!dir_emit_dots(filp, ctx))
20820+ return 0;
20821+
20822+ index = ctx->pos - 2;
20823+ if (index < size) {
4bf69007 20824+ for (p += index; p->name; p++) {
c2e5f7c8 20825+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007 20826+ vs_proc_instantiate, 0, p))
8de2f54c 20827+ return 0;
c2e5f7c8 20828+ ctx->pos++;
d337f35e
JR
20829+ }
20830+ }
8de2f54c
AM
20831+
20832+ index = ctx->pos - size;
20833+ p = &nx_virtnet_stuff[size - 1];
20834+ nr_nids = get_nid_list(index, nid_array, PROC_MAXVIDS);
20835+ for (i = 0; i < nr_nids; i++) {
20836+ int n, nid = nid_array[i];
20837+ unsigned int j = PROC_NUMBUF;
20838+
20839+ n = nid;
20840+ do
20841+ buf[--j] = '0' + (n % 10);
20842+ while (n /= 10);
20843+
20844+ if (vx_proc_fill_cache(filp, ctx,
20845+ buf + j, PROC_NUMBUF - j,
20846+ vs_proc_instantiate, nid, p))
20847+ return 0;
20848+ ctx->pos++;
20849+ }
d337f35e
JR
20850+ return 0;
20851+}
20852+
4bf69007
AM
20853+static int proc_virtnet_getattr(struct vfsmount *mnt,
20854+ struct dentry *dentry, struct kstat *stat)
20855+{
20856+ struct inode *inode = dentry->d_inode;
d337f35e 20857+
4bf69007
AM
20858+ generic_fillattr(inode, stat);
20859+ stat->nlink = 2 + atomic_read(&nx_global_cactive);
20860+ return 0;
20861+}
d337f35e 20862+
4bf69007
AM
20863+static struct file_operations proc_virtnet_dir_operations = {
20864+ .read = generic_read_dir,
c2e5f7c8 20865+ .iterate = proc_virtnet_iterate,
d337f35e
JR
20866+};
20867+
4bf69007
AM
20868+static struct inode_operations proc_virtnet_dir_inode_operations = {
20869+ .getattr = proc_virtnet_getattr,
20870+ .lookup = proc_virtnet_lookup,
d337f35e
JR
20871+};
20872+
d337f35e
JR
20873+
20874+
4bf69007 20875+void proc_vx_init(void)
d337f35e 20876+{
4bf69007 20877+ struct proc_dir_entry *ent;
d337f35e 20878+
4bf69007
AM
20879+ ent = proc_mkdir("virtual", 0);
20880+ if (ent) {
20881+ ent->proc_fops = &proc_virtual_dir_operations;
20882+ ent->proc_iops = &proc_virtual_dir_inode_operations;
20883+ }
20884+ proc_virtual = ent;
d337f35e 20885+
4bf69007
AM
20886+ ent = proc_mkdir("virtnet", 0);
20887+ if (ent) {
20888+ ent->proc_fops = &proc_virtnet_dir_operations;
20889+ ent->proc_iops = &proc_virtnet_dir_inode_operations;
d337f35e 20890+ }
4bf69007 20891+ proc_virtnet = ent;
d337f35e
JR
20892+}
20893+
d337f35e 20894+
2380c486 20895+
2380c486 20896+
4bf69007 20897+/* per pid info */
2380c486 20898+
bb20add7
AM
20899+void render_cap_t(struct seq_file *, const char *,
20900+ struct vx_info *, kernel_cap_t *);
20901+
2380c486 20902+
bb20add7
AM
20903+int proc_pid_vx_info(
20904+ struct seq_file *m,
20905+ struct pid_namespace *ns,
20906+ struct pid *pid,
20907+ struct task_struct *p)
2380c486 20908+{
4bf69007 20909+ struct vx_info *vxi;
2380c486 20910+
bb20add7 20911+ seq_printf(m, "XID:\t%d\n", vx_task_xid(p));
2380c486 20912+
4bf69007
AM
20913+ vxi = task_get_vx_info(p);
20914+ if (!vxi)
bb20add7 20915+ return 0;
2380c486 20916+
bb20add7
AM
20917+ render_cap_t(m, "BCaps:\t", vxi, &vxi->vx_bcaps);
20918+ seq_printf(m, "CCaps:\t%016llx\n",
4bf69007 20919+ (unsigned long long)vxi->vx_ccaps);
bb20add7 20920+ seq_printf(m, "CFlags:\t%016llx\n",
4bf69007 20921+ (unsigned long long)vxi->vx_flags);
bb20add7 20922+ seq_printf(m, "CIPid:\t%d\n", vxi->vx_initpid);
4bf69007
AM
20923+
20924+ put_vx_info(vxi);
bb20add7 20925+ return 0;
2380c486
JR
20926+}
20927+
2380c486 20928+
bb20add7
AM
20929+int proc_pid_nx_info(
20930+ struct seq_file *m,
20931+ struct pid_namespace *ns,
20932+ struct pid *pid,
20933+ struct task_struct *p)
4bf69007
AM
20934+{
20935+ struct nx_info *nxi;
20936+ struct nx_addr_v4 *v4a;
20937+#ifdef CONFIG_IPV6
20938+ struct nx_addr_v6 *v6a;
20939+#endif
4bf69007 20940+ int i;
2380c486 20941+
bb20add7 20942+ seq_printf(m, "NID:\t%d\n", nx_task_nid(p));
2380c486 20943+
4bf69007
AM
20944+ nxi = task_get_nx_info(p);
20945+ if (!nxi)
bb20add7 20946+ return 0;
2380c486 20947+
bb20add7 20948+ seq_printf(m, "NCaps:\t%016llx\n",
4bf69007 20949+ (unsigned long long)nxi->nx_ncaps);
bb20add7 20950+ seq_printf(m, "NFlags:\t%016llx\n",
4bf69007
AM
20951+ (unsigned long long)nxi->nx_flags);
20952+
bb20add7 20953+ seq_printf(m, "V4Root[bcast]:\t" NIPQUAD_FMT "\n",
4bf69007 20954+ NIPQUAD(nxi->v4_bcast.s_addr));
bb20add7 20955+ seq_printf(m, "V4Root[lback]:\t" NIPQUAD_FMT "\n",
4bf69007
AM
20956+ NIPQUAD(nxi->v4_lback.s_addr));
20957+ if (!NX_IPV4(nxi))
20958+ goto skip_v4;
20959+ for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next)
bb20add7 20960+ seq_printf(m, "V4Root[%d]:\t" NXAV4_FMT "\n",
4bf69007
AM
20961+ i, NXAV4(v4a));
20962+skip_v4:
20963+#ifdef CONFIG_IPV6
20964+ if (!NX_IPV6(nxi))
20965+ goto skip_v6;
20966+ for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next)
bb20add7 20967+ seq_printf(m, "V6Root[%d]:\t" NXAV6_FMT "\n",
4bf69007
AM
20968+ i, NXAV6(v6a));
20969+skip_v6:
20970+#endif
20971+ put_nx_info(nxi);
bb20add7 20972+ return 0;
2380c486
JR
20973+}
20974+
8de2f54c 20975diff -NurpP --minimal linux-4.4.111/kernel/vserver/sched.c linux-4.4.111-vs2.3.9.5/kernel/vserver/sched.c
f19bd705 20976--- linux-4.4.111/kernel/vserver/sched.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 20977+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/sched.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
20978@@ -0,0 +1,83 @@
20979+/*
20980+ * linux/kernel/vserver/sched.c
20981+ *
20982+ * Virtual Server: Scheduler Support
20983+ *
927ca606 20984+ * Copyright (C) 2004-2010 Herbert P?tzl
4bf69007
AM
20985+ *
20986+ * V0.01 adapted Sam Vilains version to 2.6.3
20987+ * V0.02 removed legacy interface
20988+ * V0.03 changed vcmds to vxi arg
20989+ * V0.04 removed older and legacy interfaces
20990+ * V0.05 removed scheduler code/commands
20991+ *
20992+ */
20993+
20994+#include <linux/vs_context.h>
20995+#include <linux/vs_sched.h>
20996+#include <linux/cpumask.h>
20997+#include <linux/vserver/sched_cmd.h>
2380c486 20998+
4bf69007
AM
20999+#include <asm/uaccess.h>
21000+
21001+
21002+void vx_update_sched_param(struct _vx_sched *sched,
21003+ struct _vx_sched_pc *sched_pc)
2380c486 21004+{
4bf69007 21005+ sched_pc->prio_bias = sched->prio_bias;
2380c486
JR
21006+}
21007+
4bf69007
AM
21008+static int do_set_prio_bias(struct vx_info *vxi, struct vcmd_prio_bias *data)
21009+{
21010+ int cpu;
2380c486 21011+
4bf69007
AM
21012+ if (data->prio_bias > MAX_PRIO_BIAS)
21013+ data->prio_bias = MAX_PRIO_BIAS;
21014+ if (data->prio_bias < MIN_PRIO_BIAS)
21015+ data->prio_bias = MIN_PRIO_BIAS;
2380c486 21016+
4bf69007 21017+ if (data->cpu_id != ~0) {
927ca606 21018+ vxi->sched.update = *get_cpu_mask(data->cpu_id);
4bf69007
AM
21019+ cpumask_and(&vxi->sched.update, &vxi->sched.update,
21020+ cpu_online_mask);
21021+ } else
21022+ cpumask_copy(&vxi->sched.update, cpu_online_mask);
2380c486 21023+
927ca606 21024+ for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)vxi->sched.update)
4bf69007
AM
21025+ vx_update_sched_param(&vxi->sched,
21026+ &vx_per_cpu(vxi, sched_pc, cpu));
21027+ return 0;
21028+}
2380c486 21029+
4bf69007
AM
21030+int vc_set_prio_bias(struct vx_info *vxi, void __user *data)
21031+{
21032+ struct vcmd_prio_bias vc_data;
d337f35e 21033+
4bf69007
AM
21034+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21035+ return -EFAULT;
d337f35e 21036+
4bf69007
AM
21037+ return do_set_prio_bias(vxi, &vc_data);
21038+}
d337f35e 21039+
4bf69007
AM
21040+int vc_get_prio_bias(struct vx_info *vxi, void __user *data)
21041+{
21042+ struct vcmd_prio_bias vc_data;
21043+ struct _vx_sched_pc *pcd;
21044+ int cpu;
d337f35e 21045+
4bf69007
AM
21046+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21047+ return -EFAULT;
2380c486 21048+
4bf69007 21049+ cpu = vc_data.cpu_id;
d337f35e 21050+
4bf69007
AM
21051+ if (!cpu_possible(cpu))
21052+ return -EINVAL;
d337f35e 21053+
4bf69007
AM
21054+ pcd = &vx_per_cpu(vxi, sched_pc, cpu);
21055+ vc_data.prio_bias = pcd->prio_bias;
d337f35e 21056+
4bf69007
AM
21057+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
21058+ return -EFAULT;
21059+ return 0;
21060+}
d337f35e 21061+
8de2f54c 21062diff -NurpP --minimal linux-4.4.111/kernel/vserver/sched_init.h linux-4.4.111-vs2.3.9.5/kernel/vserver/sched_init.h
f19bd705 21063--- linux-4.4.111/kernel/vserver/sched_init.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 21064+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/sched_init.h 2018-01-09 16:36:34.000000000 +0000
4bf69007 21065@@ -0,0 +1,27 @@
2380c486 21066+
4bf69007
AM
21067+static inline void vx_info_init_sched(struct _vx_sched *sched)
21068+{
21069+ /* scheduling; hard code starting values as constants */
21070+ sched->prio_bias = 0;
d337f35e
JR
21071+}
21072+
4bf69007
AM
21073+static inline
21074+void vx_info_init_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
e3afe727 21075+{
4bf69007
AM
21076+ sched_pc->prio_bias = 0;
21077+
21078+ sched_pc->user_ticks = 0;
21079+ sched_pc->sys_ticks = 0;
21080+ sched_pc->hold_ticks = 0;
e3afe727
AM
21081+}
21082+
4bf69007 21083+static inline void vx_info_exit_sched(struct _vx_sched *sched)
e3afe727 21084+{
4bf69007 21085+ return;
e3afe727
AM
21086+}
21087+
4bf69007
AM
21088+static inline
21089+void vx_info_exit_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
e3afe727 21090+{
4bf69007 21091+ return;
e3afe727 21092+}
8de2f54c 21093diff -NurpP --minimal linux-4.4.111/kernel/vserver/sched_proc.h linux-4.4.111-vs2.3.9.5/kernel/vserver/sched_proc.h
f19bd705 21094--- linux-4.4.111/kernel/vserver/sched_proc.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 21095+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/sched_proc.h 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
21096@@ -0,0 +1,32 @@
21097+#ifndef _VX_SCHED_PROC_H
21098+#define _VX_SCHED_PROC_H
e3afe727 21099+
4bf69007
AM
21100+
21101+static inline
21102+int vx_info_proc_sched(struct _vx_sched *sched, char *buffer)
e3afe727 21103+{
4bf69007
AM
21104+ int length = 0;
21105+
21106+ length += sprintf(buffer,
21107+ "PrioBias:\t%8d\n",
21108+ sched->prio_bias);
21109+ return length;
e3afe727
AM
21110+}
21111+
4bf69007
AM
21112+static inline
21113+int vx_info_proc_sched_pc(struct _vx_sched_pc *sched_pc,
21114+ char *buffer, int cpu)
e3afe727 21115+{
4bf69007 21116+ int length = 0;
e3afe727 21117+
4bf69007
AM
21118+ length += sprintf(buffer + length,
21119+ "cpu %d: %lld %lld %lld", cpu,
21120+ (unsigned long long)sched_pc->user_ticks,
21121+ (unsigned long long)sched_pc->sys_ticks,
21122+ (unsigned long long)sched_pc->hold_ticks);
21123+ length += sprintf(buffer + length,
21124+ " %d\n", sched_pc->prio_bias);
21125+ return length;
21126+}
93de0823 21127+
4bf69007 21128+#endif /* _VX_SCHED_PROC_H */
8de2f54c 21129diff -NurpP --minimal linux-4.4.111/kernel/vserver/signal.c linux-4.4.111-vs2.3.9.5/kernel/vserver/signal.c
f19bd705 21130--- linux-4.4.111/kernel/vserver/signal.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 21131+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/signal.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
21132@@ -0,0 +1,134 @@
21133+/*
21134+ * linux/kernel/vserver/signal.c
21135+ *
21136+ * Virtual Server: Signal Support
21137+ *
927ca606 21138+ * Copyright (C) 2003-2007 Herbert P?tzl
4bf69007
AM
21139+ *
21140+ * V0.01 broken out from vcontext V0.05
21141+ * V0.02 changed vcmds to vxi arg
21142+ * V0.03 adjusted siginfo for kill
21143+ *
21144+ */
99a884b4 21145+
4bf69007 21146+#include <asm/uaccess.h>
93de0823 21147+
4bf69007
AM
21148+#include <linux/vs_context.h>
21149+#include <linux/vs_pid.h>
21150+#include <linux/vserver/signal_cmd.h>
d337f35e 21151+
d337f35e 21152+
4bf69007
AM
21153+int vx_info_kill(struct vx_info *vxi, int pid, int sig)
21154+{
21155+ int retval, count = 0;
21156+ struct task_struct *p;
21157+ struct siginfo *sip = SEND_SIG_PRIV;
d33d7b00 21158+
4bf69007
AM
21159+ retval = -ESRCH;
21160+ vxdprintk(VXD_CBIT(misc, 4),
21161+ "vx_info_kill(%p[#%d],%d,%d)*",
21162+ vxi, vxi->vx_id, pid, sig);
21163+ read_lock(&tasklist_lock);
21164+ switch (pid) {
21165+ case 0:
21166+ case -1:
21167+ for_each_process(p) {
21168+ int err = 0;
d337f35e 21169+
4bf69007
AM
21170+ if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 ||
21171+ (pid && vxi->vx_initpid == p->pid))
21172+ continue;
d337f35e 21173+
4bf69007
AM
21174+ err = group_send_sig_info(sig, sip, p);
21175+ ++count;
21176+ if (err != -EPERM)
21177+ retval = err;
21178+ }
21179+ break;
d337f35e 21180+
4bf69007
AM
21181+ case 1:
21182+ if (vxi->vx_initpid) {
21183+ pid = vxi->vx_initpid;
21184+ /* for now, only SIGINT to private init ... */
21185+ if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
21186+ /* ... as long as there are tasks left */
21187+ (atomic_read(&vxi->vx_tasks) > 1))
21188+ sig = SIGINT;
21189+ }
21190+ /* fallthrough */
21191+ default:
21192+ rcu_read_lock();
21193+ p = find_task_by_real_pid(pid);
21194+ rcu_read_unlock();
21195+ if (p) {
21196+ if (vx_task_xid(p) == vxi->vx_id)
21197+ retval = group_send_sig_info(sig, sip, p);
21198+ }
21199+ break;
21200+ }
21201+ read_unlock(&tasklist_lock);
21202+ vxdprintk(VXD_CBIT(misc, 4),
21203+ "vx_info_kill(%p[#%d],%d,%d,%ld) = %d",
21204+ vxi, vxi->vx_id, pid, sig, (long)sip, retval);
21205+ return retval;
21206+}
d337f35e 21207+
4bf69007 21208+int vc_ctx_kill(struct vx_info *vxi, void __user *data)
d337f35e 21209+{
4bf69007 21210+ struct vcmd_ctx_kill_v0 vc_data;
d337f35e 21211+
4bf69007
AM
21212+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21213+ return -EFAULT;
d337f35e 21214+
4bf69007
AM
21215+ /* special check to allow guest shutdown */
21216+ if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
21217+ /* forbid killall pid=0 when init is present */
21218+ (((vc_data.pid < 1) && vxi->vx_initpid) ||
21219+ (vc_data.pid > 1)))
21220+ return -EACCES;
21221+
21222+ return vx_info_kill(vxi, vc_data.pid, vc_data.sig);
d337f35e
JR
21223+}
21224+
4bf69007
AM
21225+
21226+static int __wait_exit(struct vx_info *vxi)
d337f35e 21227+{
4bf69007
AM
21228+ DECLARE_WAITQUEUE(wait, current);
21229+ int ret = 0;
d337f35e 21230+
4bf69007
AM
21231+ add_wait_queue(&vxi->vx_wait, &wait);
21232+ set_current_state(TASK_INTERRUPTIBLE);
d337f35e 21233+
4bf69007
AM
21234+wait:
21235+ if (vx_info_state(vxi,
21236+ VXS_SHUTDOWN | VXS_HASHED | VXS_HELPER) == VXS_SHUTDOWN)
21237+ goto out;
21238+ if (signal_pending(current)) {
21239+ ret = -ERESTARTSYS;
21240+ goto out;
21241+ }
21242+ schedule();
21243+ goto wait;
21244+
21245+out:
21246+ set_current_state(TASK_RUNNING);
21247+ remove_wait_queue(&vxi->vx_wait, &wait);
21248+ return ret;
d337f35e
JR
21249+}
21250+
4a036bed 21251+
7b17263b 21252+
4bf69007 21253+int vc_wait_exit(struct vx_info *vxi, void __user *data)
7b17263b 21254+{
4bf69007
AM
21255+ struct vcmd_wait_exit_v0 vc_data;
21256+ int ret;
7b17263b 21257+
4bf69007
AM
21258+ ret = __wait_exit(vxi);
21259+ vc_data.reboot_cmd = vxi->reboot_cmd;
21260+ vc_data.exit_code = vxi->exit_code;
21261+
21262+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
21263+ ret = -EFAULT;
21264+ return ret;
7b17263b 21265+}
2380c486 21266+
8de2f54c 21267diff -NurpP --minimal linux-4.4.111/kernel/vserver/space.c linux-4.4.111-vs2.3.9.5/kernel/vserver/space.c
f19bd705 21268--- linux-4.4.111/kernel/vserver/space.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 21269+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/space.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
21270@@ -0,0 +1,436 @@
21271+/*
21272+ * linux/kernel/vserver/space.c
21273+ *
21274+ * Virtual Server: Context Space Support
21275+ *
927ca606 21276+ * Copyright (C) 2003-2010 Herbert P?tzl
4bf69007
AM
21277+ *
21278+ * V0.01 broken out from context.c 0.07
21279+ * V0.02 added task locking for namespace
21280+ * V0.03 broken out vx_enter_namespace
21281+ * V0.04 added *space support and commands
21282+ * V0.05 added credential support
21283+ *
21284+ */
21285+
21286+#include <linux/utsname.h>
21287+#include <linux/nsproxy.h>
21288+#include <linux/err.h>
21289+#include <linux/fs_struct.h>
21290+#include <linux/cred.h>
21291+#include <asm/uaccess.h>
d337f35e 21292+
d337f35e 21293+#include <linux/vs_context.h>
4bf69007
AM
21294+#include <linux/vserver/space.h>
21295+#include <linux/vserver/space_cmd.h>
2380c486 21296+
4bf69007
AM
21297+atomic_t vs_global_nsproxy = ATOMIC_INIT(0);
21298+atomic_t vs_global_fs = ATOMIC_INIT(0);
21299+atomic_t vs_global_mnt_ns = ATOMIC_INIT(0);
21300+atomic_t vs_global_uts_ns = ATOMIC_INIT(0);
21301+atomic_t vs_global_user_ns = ATOMIC_INIT(0);
21302+atomic_t vs_global_pid_ns = ATOMIC_INIT(0);
d337f35e 21303+
2380c486 21304+
4bf69007 21305+/* namespace functions */
2380c486 21306+
4bf69007
AM
21307+#include <linux/mnt_namespace.h>
21308+#include <linux/user_namespace.h>
21309+#include <linux/pid_namespace.h>
21310+#include <linux/ipc_namespace.h>
21311+#include <net/net_namespace.h>
21312+#include "../fs/mount.h"
2380c486 21313+
2380c486 21314+
4bf69007
AM
21315+static const struct vcmd_space_mask_v1 space_mask_v0 = {
21316+ .mask = CLONE_FS |
21317+ CLONE_NEWNS |
21318+#ifdef CONFIG_UTS_NS
21319+ CLONE_NEWUTS |
21320+#endif
21321+#ifdef CONFIG_IPC_NS
21322+ CLONE_NEWIPC |
21323+#endif
21324+#ifdef CONFIG_USER_NS
21325+ CLONE_NEWUSER |
21326+#endif
21327+ 0
21328+};
2380c486 21329+
4bf69007
AM
21330+static const struct vcmd_space_mask_v1 space_mask = {
21331+ .mask = CLONE_FS |
21332+ CLONE_NEWNS |
21333+#ifdef CONFIG_UTS_NS
21334+ CLONE_NEWUTS |
21335+#endif
21336+#ifdef CONFIG_IPC_NS
21337+ CLONE_NEWIPC |
21338+#endif
21339+#ifdef CONFIG_USER_NS
21340+ CLONE_NEWUSER |
21341+#endif
21342+#ifdef CONFIG_PID_NS
21343+ CLONE_NEWPID |
21344+#endif
21345+#ifdef CONFIG_NET_NS
21346+ CLONE_NEWNET |
21347+#endif
21348+ 0
21349+};
2380c486 21350+
4bf69007
AM
21351+static const struct vcmd_space_mask_v1 default_space_mask = {
21352+ .mask = CLONE_FS |
21353+ CLONE_NEWNS |
21354+#ifdef CONFIG_UTS_NS
21355+ CLONE_NEWUTS |
21356+#endif
21357+#ifdef CONFIG_IPC_NS
21358+ CLONE_NEWIPC |
21359+#endif
21360+#ifdef CONFIG_USER_NS
bb20add7 21361+// CLONE_NEWUSER |
4bf69007
AM
21362+#endif
21363+#ifdef CONFIG_PID_NS
21364+// CLONE_NEWPID |
21365+#endif
21366+ 0
21367+};
2380c486 21368+
4bf69007
AM
21369+/*
21370+ * build a new nsproxy mix
21371+ * assumes that both proxies are 'const'
21372+ * does not touch nsproxy refcounts
21373+ * will hold a reference on the result.
21374+ */
7b17263b 21375+
4bf69007
AM
21376+struct nsproxy *vs_mix_nsproxy(struct nsproxy *old_nsproxy,
21377+ struct nsproxy *new_nsproxy, unsigned long mask)
21378+{
21379+ struct mnt_namespace *old_ns;
21380+ struct uts_namespace *old_uts;
21381+ struct ipc_namespace *old_ipc;
21382+#ifdef CONFIG_PID_NS
21383+ struct pid_namespace *old_pid;
21384+#endif
21385+#ifdef CONFIG_NET_NS
21386+ struct net *old_net;
21387+#endif
21388+ struct nsproxy *nsproxy;
d337f35e 21389+
4bf69007
AM
21390+ nsproxy = copy_nsproxy(old_nsproxy);
21391+ if (!nsproxy)
21392+ goto out;
bd0a9c15 21393+
4bf69007
AM
21394+ if (mask & CLONE_NEWNS) {
21395+ old_ns = nsproxy->mnt_ns;
21396+ nsproxy->mnt_ns = new_nsproxy->mnt_ns;
21397+ if (nsproxy->mnt_ns)
21398+ get_mnt_ns(nsproxy->mnt_ns);
21399+ } else
21400+ old_ns = NULL;
d337f35e 21401+
4bf69007
AM
21402+ if (mask & CLONE_NEWUTS) {
21403+ old_uts = nsproxy->uts_ns;
21404+ nsproxy->uts_ns = new_nsproxy->uts_ns;
21405+ if (nsproxy->uts_ns)
21406+ get_uts_ns(nsproxy->uts_ns);
21407+ } else
21408+ old_uts = NULL;
2380c486 21409+
4bf69007
AM
21410+ if (mask & CLONE_NEWIPC) {
21411+ old_ipc = nsproxy->ipc_ns;
21412+ nsproxy->ipc_ns = new_nsproxy->ipc_ns;
21413+ if (nsproxy->ipc_ns)
21414+ get_ipc_ns(nsproxy->ipc_ns);
21415+ } else
21416+ old_ipc = NULL;
ec22aa5c 21417+
4bf69007
AM
21418+#ifdef CONFIG_PID_NS
21419+ if (mask & CLONE_NEWPID) {
5f23d63e
AM
21420+ old_pid = nsproxy->pid_ns_for_children;
21421+ nsproxy->pid_ns_for_children = new_nsproxy->pid_ns_for_children;
21422+ if (nsproxy->pid_ns_for_children)
21423+ get_pid_ns(nsproxy->pid_ns_for_children);
4bf69007
AM
21424+ } else
21425+ old_pid = NULL;
21426+#endif
21427+#ifdef CONFIG_NET_NS
21428+ if (mask & CLONE_NEWNET) {
21429+ old_net = nsproxy->net_ns;
21430+ nsproxy->net_ns = new_nsproxy->net_ns;
21431+ if (nsproxy->net_ns)
21432+ get_net(nsproxy->net_ns);
21433+ } else
21434+ old_net = NULL;
21435+#endif
21436+ if (old_ns)
21437+ put_mnt_ns(old_ns);
21438+ if (old_uts)
21439+ put_uts_ns(old_uts);
21440+ if (old_ipc)
21441+ put_ipc_ns(old_ipc);
21442+#ifdef CONFIG_PID_NS
21443+ if (old_pid)
21444+ put_pid_ns(old_pid);
21445+#endif
21446+#ifdef CONFIG_NET_NS
21447+ if (old_net)
21448+ put_net(old_net);
21449+#endif
21450+out:
21451+ return nsproxy;
21452+}
2380c486 21453+
bd0a9c15 21454+
4bf69007
AM
21455+/*
21456+ * merge two nsproxy structs into a new one.
21457+ * will hold a reference on the result.
21458+ */
d337f35e 21459+
4bf69007
AM
21460+static inline
21461+struct nsproxy *__vs_merge_nsproxy(struct nsproxy *old,
21462+ struct nsproxy *proxy, unsigned long mask)
21463+{
21464+ struct nsproxy null_proxy = { .mnt_ns = NULL };
2380c486 21465+
4bf69007
AM
21466+ if (!proxy)
21467+ return NULL;
d337f35e 21468+
4bf69007
AM
21469+ if (mask) {
21470+ /* vs_mix_nsproxy returns with reference */
21471+ return vs_mix_nsproxy(old ? old : &null_proxy,
21472+ proxy, mask);
21473+ }
21474+ get_nsproxy(proxy);
21475+ return proxy;
21476+}
2380c486 21477+
ec22aa5c 21478+
4bf69007
AM
21479+int vx_enter_space(struct vx_info *vxi, unsigned long mask, unsigned index)
21480+{
21481+ struct nsproxy *proxy, *proxy_cur, *proxy_new;
21482+ struct fs_struct *fs_cur, *fs = NULL;
21483+ struct _vx_space *space;
21484+ int ret, kill = 0;
2380c486 21485+
4bf69007
AM
21486+ vxdprintk(VXD_CBIT(space, 8), "vx_enter_space(%p[#%u],0x%08lx,%d)",
21487+ vxi, vxi->vx_id, mask, index);
2380c486 21488+
4bf69007
AM
21489+ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
21490+ return -EACCES;
2380c486 21491+
4bf69007
AM
21492+ if (index >= VX_SPACES)
21493+ return -EINVAL;
2380c486 21494+
4bf69007
AM
21495+ space = &vxi->space[index];
21496+
21497+ if (!mask)
21498+ mask = space->vx_nsmask;
21499+
21500+ if ((mask & space->vx_nsmask) != mask)
21501+ return -EINVAL;
21502+
21503+ if (mask & CLONE_FS) {
21504+ fs = copy_fs_struct(space->vx_fs);
21505+ if (!fs)
21506+ return -ENOMEM;
2380c486 21507+ }
4bf69007
AM
21508+ proxy = space->vx_nsproxy;
21509+
21510+ vxdprintk(VXD_CBIT(space, 9),
21511+ "vx_enter_space(%p[#%u],0x%08lx,%d) -> (%p,%p)",
21512+ vxi, vxi->vx_id, mask, index, proxy, fs);
21513+
21514+ task_lock(current);
21515+ fs_cur = current->fs;
21516+
21517+ if (mask & CLONE_FS) {
21518+ spin_lock(&fs_cur->lock);
21519+ current->fs = fs;
21520+ kill = !--fs_cur->users;
21521+ spin_unlock(&fs_cur->lock);
ec22aa5c 21522+ }
ec22aa5c 21523+
4bf69007
AM
21524+ proxy_cur = current->nsproxy;
21525+ get_nsproxy(proxy_cur);
21526+ task_unlock(current);
21527+
21528+ if (kill)
21529+ free_fs_struct(fs_cur);
21530+
21531+ proxy_new = __vs_merge_nsproxy(proxy_cur, proxy, mask);
21532+ if (IS_ERR(proxy_new)) {
21533+ ret = PTR_ERR(proxy_new);
21534+ goto out_put;
eab5a9a6 21535+ }
4bf69007
AM
21536+
21537+ proxy_new = xchg(&current->nsproxy, proxy_new);
21538+
21539+ if (mask & CLONE_NEWUSER) {
21540+ struct cred *cred;
21541+
21542+ vxdprintk(VXD_CBIT(space, 10),
21543+ "vx_enter_space(%p[#%u],%p) cred (%p,%p)",
21544+ vxi, vxi->vx_id, space->vx_cred,
21545+ current->real_cred, current->cred);
21546+
21547+ if (space->vx_cred) {
21548+ cred = __prepare_creds(space->vx_cred);
21549+ if (cred)
21550+ commit_creds(cred);
21551+ }
d337f35e 21552+ }
4bf69007
AM
21553+
21554+ ret = 0;
21555+
21556+ if (proxy_new)
21557+ put_nsproxy(proxy_new);
21558+out_put:
21559+ if (proxy_cur)
21560+ put_nsproxy(proxy_cur);
21561+ return ret;
21562+}
21563+
21564+
21565+int vx_set_space(struct vx_info *vxi, unsigned long mask, unsigned index)
21566+{
21567+ struct nsproxy *proxy_vxi, *proxy_cur, *proxy_new;
21568+ struct fs_struct *fs_vxi, *fs = NULL;
21569+ struct _vx_space *space;
21570+ int ret, kill = 0;
21571+
21572+ vxdprintk(VXD_CBIT(space, 8), "vx_set_space(%p[#%u],0x%08lx,%d)",
21573+ vxi, vxi->vx_id, mask, index);
21574+
21575+ if ((mask & space_mask.mask) != mask)
21576+ return -EINVAL;
21577+
21578+ if (index >= VX_SPACES)
21579+ return -EINVAL;
21580+
21581+ space = &vxi->space[index];
21582+
21583+ proxy_vxi = space->vx_nsproxy;
21584+ fs_vxi = space->vx_fs;
21585+
21586+ if (mask & CLONE_FS) {
21587+ fs = copy_fs_struct(current->fs);
21588+ if (!fs)
21589+ return -ENOMEM;
2380c486 21590+ }
d337f35e 21591+
4bf69007 21592+ task_lock(current);
2ba6f0dd 21593+
4bf69007
AM
21594+ if (mask & CLONE_FS) {
21595+ spin_lock(&fs_vxi->lock);
21596+ space->vx_fs = fs;
21597+ kill = !--fs_vxi->users;
21598+ spin_unlock(&fs_vxi->lock);
21599+ }
2ba6f0dd 21600+
4bf69007
AM
21601+ proxy_cur = current->nsproxy;
21602+ get_nsproxy(proxy_cur);
21603+ task_unlock(current);
2ba6f0dd 21604+
4bf69007
AM
21605+ if (kill)
21606+ free_fs_struct(fs_vxi);
2ba6f0dd 21607+
4bf69007
AM
21608+ proxy_new = __vs_merge_nsproxy(proxy_vxi, proxy_cur, mask);
21609+ if (IS_ERR(proxy_new)) {
21610+ ret = PTR_ERR(proxy_new);
21611+ goto out_put;
21612+ }
2ba6f0dd 21613+
4bf69007
AM
21614+ proxy_new = xchg(&space->vx_nsproxy, proxy_new);
21615+ space->vx_nsmask |= mask;
2ba6f0dd 21616+
4bf69007
AM
21617+ if (mask & CLONE_NEWUSER) {
21618+ struct cred *cred;
2ba6f0dd 21619+
4bf69007
AM
21620+ vxdprintk(VXD_CBIT(space, 10),
21621+ "vx_set_space(%p[#%u],%p) cred (%p,%p)",
21622+ vxi, vxi->vx_id, space->vx_cred,
21623+ current->real_cred, current->cred);
2ba6f0dd 21624+
4bf69007
AM
21625+ cred = prepare_creds();
21626+ cred = (struct cred *)xchg(&space->vx_cred, cred);
21627+ if (cred)
21628+ abort_creds(cred);
21629+ }
2ba6f0dd 21630+
4bf69007 21631+ ret = 0;
2ba6f0dd 21632+
4bf69007
AM
21633+ if (proxy_new)
21634+ put_nsproxy(proxy_new);
21635+out_put:
21636+ if (proxy_cur)
21637+ put_nsproxy(proxy_cur);
21638+ return ret;
21639+}
2ba6f0dd
AM
21640+
21641+
4bf69007
AM
21642+int vc_enter_space_v1(struct vx_info *vxi, void __user *data)
21643+{
21644+ struct vcmd_space_mask_v1 vc_data = { .mask = 0 };
2ba6f0dd 21645+
4bf69007
AM
21646+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21647+ return -EFAULT;
2ba6f0dd 21648+
4bf69007
AM
21649+ return vx_enter_space(vxi, vc_data.mask, 0);
21650+}
2ba6f0dd 21651+
4bf69007
AM
21652+int vc_enter_space(struct vx_info *vxi, void __user *data)
21653+{
21654+ struct vcmd_space_mask_v2 vc_data = { .mask = 0 };
2ba6f0dd 21655+
4bf69007
AM
21656+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21657+ return -EFAULT;
2ba6f0dd 21658+
4bf69007
AM
21659+ if (vc_data.index >= VX_SPACES)
21660+ return -EINVAL;
2ba6f0dd 21661+
4bf69007
AM
21662+ return vx_enter_space(vxi, vc_data.mask, vc_data.index);
21663+}
2ba6f0dd 21664+
4bf69007
AM
21665+int vc_set_space_v1(struct vx_info *vxi, void __user *data)
21666+{
21667+ struct vcmd_space_mask_v1 vc_data = { .mask = 0 };
2ba6f0dd 21668+
4bf69007
AM
21669+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21670+ return -EFAULT;
2ba6f0dd 21671+
4bf69007
AM
21672+ return vx_set_space(vxi, vc_data.mask, 0);
21673+}
2ba6f0dd 21674+
4bf69007
AM
21675+int vc_set_space(struct vx_info *vxi, void __user *data)
21676+{
21677+ struct vcmd_space_mask_v2 vc_data = { .mask = 0 };
2ba6f0dd 21678+
4bf69007
AM
21679+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21680+ return -EFAULT;
2ba6f0dd 21681+
4bf69007
AM
21682+ if (vc_data.index >= VX_SPACES)
21683+ return -EINVAL;
2ba6f0dd 21684+
4bf69007
AM
21685+ return vx_set_space(vxi, vc_data.mask, vc_data.index);
21686+}
2ba6f0dd 21687+
4bf69007
AM
21688+int vc_get_space_mask(void __user *data, int type)
21689+{
21690+ const struct vcmd_space_mask_v1 *mask;
2ba6f0dd 21691+
4bf69007
AM
21692+ if (type == 0)
21693+ mask = &space_mask_v0;
21694+ else if (type == 1)
21695+ mask = &space_mask;
21696+ else
21697+ mask = &default_space_mask;
2ba6f0dd 21698+
4bf69007
AM
21699+ vxdprintk(VXD_CBIT(space, 10),
21700+ "vc_get_space_mask(%d) = %08llx", type, mask->mask);
2ba6f0dd 21701+
4bf69007
AM
21702+ if (copy_to_user(data, mask, sizeof(*mask)))
21703+ return -EFAULT;
21704+ return 0;
21705+}
2ba6f0dd 21706+
8de2f54c 21707diff -NurpP --minimal linux-4.4.111/kernel/vserver/switch.c linux-4.4.111-vs2.3.9.5/kernel/vserver/switch.c
f19bd705 21708--- linux-4.4.111/kernel/vserver/switch.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 21709+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/switch.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
21710@@ -0,0 +1,556 @@
21711+/*
21712+ * linux/kernel/vserver/switch.c
21713+ *
21714+ * Virtual Server: Syscall Switch
21715+ *
927ca606 21716+ * Copyright (C) 2003-2011 Herbert P?tzl
4bf69007
AM
21717+ *
21718+ * V0.01 syscall switch
21719+ * V0.02 added signal to context
21720+ * V0.03 added rlimit functions
21721+ * V0.04 added iattr, task/xid functions
21722+ * V0.05 added debug/history stuff
21723+ * V0.06 added compat32 layer
21724+ * V0.07 vcmd args and perms
21725+ * V0.08 added status commands
21726+ * V0.09 added tag commands
21727+ * V0.10 added oom bias
21728+ * V0.11 added device commands
21729+ * V0.12 added warn mask
21730+ *
21731+ */
2ba6f0dd 21732+
4bf69007
AM
21733+#include <linux/vs_context.h>
21734+#include <linux/vs_network.h>
21735+#include <linux/vserver/switch.h>
2ba6f0dd 21736+
4bf69007 21737+#include "vci_config.h"
2ba6f0dd 21738+
2ba6f0dd 21739+
4bf69007
AM
21740+static inline
21741+int vc_get_version(uint32_t id)
21742+{
21743+ return VCI_VERSION;
21744+}
2ba6f0dd 21745+
4bf69007
AM
21746+static inline
21747+int vc_get_vci(uint32_t id)
21748+{
21749+ return vci_kernel_config();
21750+}
2ba6f0dd 21751+
4bf69007
AM
21752+#include <linux/vserver/context_cmd.h>
21753+#include <linux/vserver/cvirt_cmd.h>
21754+#include <linux/vserver/cacct_cmd.h>
21755+#include <linux/vserver/limit_cmd.h>
21756+#include <linux/vserver/network_cmd.h>
21757+#include <linux/vserver/sched_cmd.h>
21758+#include <linux/vserver/debug_cmd.h>
21759+#include <linux/vserver/inode_cmd.h>
21760+#include <linux/vserver/dlimit_cmd.h>
21761+#include <linux/vserver/signal_cmd.h>
21762+#include <linux/vserver/space_cmd.h>
21763+#include <linux/vserver/tag_cmd.h>
21764+#include <linux/vserver/device_cmd.h>
2ba6f0dd 21765+
4bf69007
AM
21766+#include <linux/vserver/inode.h>
21767+#include <linux/vserver/dlimit.h>
2ba6f0dd 21768+
2ba6f0dd 21769+
4bf69007
AM
21770+#ifdef CONFIG_COMPAT
21771+#define __COMPAT(name, id, data, compat) \
21772+ (compat) ? name ## _x32(id, data) : name(id, data)
21773+#define __COMPAT_NO_ID(name, data, compat) \
21774+ (compat) ? name ## _x32(data) : name(data)
21775+#else
21776+#define __COMPAT(name, id, data, compat) \
21777+ name(id, data)
21778+#define __COMPAT_NO_ID(name, data, compat) \
21779+ name(data)
21780+#endif
2ba6f0dd 21781+
2ba6f0dd 21782+
4bf69007
AM
21783+static inline
21784+long do_vcmd(uint32_t cmd, uint32_t id,
21785+ struct vx_info *vxi, struct nx_info *nxi,
21786+ void __user *data, int compat)
21787+{
21788+ switch (cmd) {
2ba6f0dd 21789+
4bf69007
AM
21790+ case VCMD_get_version:
21791+ return vc_get_version(id);
21792+ case VCMD_get_vci:
21793+ return vc_get_vci(id);
2ba6f0dd 21794+
4bf69007
AM
21795+ case VCMD_task_xid:
21796+ return vc_task_xid(id);
21797+ case VCMD_vx_info:
21798+ return vc_vx_info(vxi, data);
2ba6f0dd 21799+
4bf69007
AM
21800+ case VCMD_task_nid:
21801+ return vc_task_nid(id);
21802+ case VCMD_nx_info:
21803+ return vc_nx_info(nxi, data);
2ba6f0dd 21804+
4bf69007
AM
21805+ case VCMD_task_tag:
21806+ return vc_task_tag(id);
2ba6f0dd 21807+
4bf69007
AM
21808+ case VCMD_set_space_v1:
21809+ return vc_set_space_v1(vxi, data);
21810+ /* this is version 2 */
21811+ case VCMD_set_space:
21812+ return vc_set_space(vxi, data);
2ba6f0dd 21813+
4bf69007
AM
21814+ case VCMD_get_space_mask_v0:
21815+ return vc_get_space_mask(data, 0);
21816+ /* this is version 1 */
21817+ case VCMD_get_space_mask:
21818+ return vc_get_space_mask(data, 1);
2ba6f0dd 21819+
4bf69007
AM
21820+ case VCMD_get_space_default:
21821+ return vc_get_space_mask(data, -1);
2ba6f0dd 21822+
4bf69007
AM
21823+ case VCMD_set_umask:
21824+ return vc_set_umask(vxi, data);
2ba6f0dd 21825+
4bf69007
AM
21826+ case VCMD_get_umask:
21827+ return vc_get_umask(vxi, data);
2ba6f0dd 21828+
4bf69007
AM
21829+ case VCMD_set_wmask:
21830+ return vc_set_wmask(vxi, data);
2ba6f0dd 21831+
4bf69007
AM
21832+ case VCMD_get_wmask:
21833+ return vc_get_wmask(vxi, data);
21834+#ifdef CONFIG_IA32_EMULATION
21835+ case VCMD_get_rlimit:
21836+ return __COMPAT(vc_get_rlimit, vxi, data, compat);
21837+ case VCMD_set_rlimit:
21838+ return __COMPAT(vc_set_rlimit, vxi, data, compat);
21839+#else
21840+ case VCMD_get_rlimit:
21841+ return vc_get_rlimit(vxi, data);
21842+ case VCMD_set_rlimit:
21843+ return vc_set_rlimit(vxi, data);
21844+#endif
21845+ case VCMD_get_rlimit_mask:
21846+ return vc_get_rlimit_mask(id, data);
21847+ case VCMD_reset_hits:
21848+ return vc_reset_hits(vxi, data);
21849+ case VCMD_reset_minmax:
21850+ return vc_reset_minmax(vxi, data);
2ba6f0dd 21851+
4bf69007
AM
21852+ case VCMD_get_vhi_name:
21853+ return vc_get_vhi_name(vxi, data);
21854+ case VCMD_set_vhi_name:
21855+ return vc_set_vhi_name(vxi, data);
2ba6f0dd 21856+
4bf69007
AM
21857+ case VCMD_ctx_stat:
21858+ return vc_ctx_stat(vxi, data);
21859+ case VCMD_virt_stat:
21860+ return vc_virt_stat(vxi, data);
21861+ case VCMD_sock_stat:
21862+ return vc_sock_stat(vxi, data);
21863+ case VCMD_rlimit_stat:
21864+ return vc_rlimit_stat(vxi, data);
2ba6f0dd 21865+
4bf69007
AM
21866+ case VCMD_set_cflags:
21867+ return vc_set_cflags(vxi, data);
21868+ case VCMD_get_cflags:
21869+ return vc_get_cflags(vxi, data);
2ba6f0dd 21870+
4bf69007
AM
21871+ /* this is version 1 */
21872+ case VCMD_set_ccaps:
21873+ return vc_set_ccaps(vxi, data);
21874+ /* this is version 1 */
21875+ case VCMD_get_ccaps:
21876+ return vc_get_ccaps(vxi, data);
21877+ case VCMD_set_bcaps:
21878+ return vc_set_bcaps(vxi, data);
21879+ case VCMD_get_bcaps:
21880+ return vc_get_bcaps(vxi, data);
2ba6f0dd 21881+
4bf69007
AM
21882+ case VCMD_set_badness:
21883+ return vc_set_badness(vxi, data);
21884+ case VCMD_get_badness:
21885+ return vc_get_badness(vxi, data);
2ba6f0dd 21886+
4bf69007
AM
21887+ case VCMD_set_nflags:
21888+ return vc_set_nflags(nxi, data);
21889+ case VCMD_get_nflags:
21890+ return vc_get_nflags(nxi, data);
2ba6f0dd 21891+
4bf69007
AM
21892+ case VCMD_set_ncaps:
21893+ return vc_set_ncaps(nxi, data);
21894+ case VCMD_get_ncaps:
21895+ return vc_get_ncaps(nxi, data);
2ba6f0dd 21896+
4bf69007
AM
21897+ case VCMD_set_prio_bias:
21898+ return vc_set_prio_bias(vxi, data);
21899+ case VCMD_get_prio_bias:
21900+ return vc_get_prio_bias(vxi, data);
21901+ case VCMD_add_dlimit:
21902+ return __COMPAT(vc_add_dlimit, id, data, compat);
21903+ case VCMD_rem_dlimit:
21904+ return __COMPAT(vc_rem_dlimit, id, data, compat);
21905+ case VCMD_set_dlimit:
21906+ return __COMPAT(vc_set_dlimit, id, data, compat);
21907+ case VCMD_get_dlimit:
21908+ return __COMPAT(vc_get_dlimit, id, data, compat);
2ba6f0dd 21909+
4bf69007
AM
21910+ case VCMD_ctx_kill:
21911+ return vc_ctx_kill(vxi, data);
2ba6f0dd 21912+
4bf69007
AM
21913+ case VCMD_wait_exit:
21914+ return vc_wait_exit(vxi, data);
2ba6f0dd 21915+
4bf69007
AM
21916+ case VCMD_get_iattr:
21917+ return __COMPAT_NO_ID(vc_get_iattr, data, compat);
21918+ case VCMD_set_iattr:
21919+ return __COMPAT_NO_ID(vc_set_iattr, data, compat);
2ba6f0dd 21920+
4bf69007
AM
21921+ case VCMD_fget_iattr:
21922+ return vc_fget_iattr(id, data);
21923+ case VCMD_fset_iattr:
21924+ return vc_fset_iattr(id, data);
2ba6f0dd 21925+
4bf69007
AM
21926+ case VCMD_enter_space_v0:
21927+ return vc_enter_space_v1(vxi, NULL);
21928+ case VCMD_enter_space_v1:
21929+ return vc_enter_space_v1(vxi, data);
21930+ /* this is version 2 */
21931+ case VCMD_enter_space:
21932+ return vc_enter_space(vxi, data);
2ba6f0dd 21933+
4bf69007
AM
21934+ case VCMD_ctx_create_v0:
21935+ return vc_ctx_create(id, NULL);
21936+ case VCMD_ctx_create:
21937+ return vc_ctx_create(id, data);
21938+ case VCMD_ctx_migrate_v0:
21939+ return vc_ctx_migrate(vxi, NULL);
21940+ case VCMD_ctx_migrate:
21941+ return vc_ctx_migrate(vxi, data);
2ba6f0dd 21942+
4bf69007
AM
21943+ case VCMD_net_create_v0:
21944+ return vc_net_create(id, NULL);
21945+ case VCMD_net_create:
21946+ return vc_net_create(id, data);
21947+ case VCMD_net_migrate:
21948+ return vc_net_migrate(nxi, data);
2ba6f0dd 21949+
4bf69007
AM
21950+ case VCMD_tag_migrate:
21951+ return vc_tag_migrate(id);
2ba6f0dd 21952+
4bf69007
AM
21953+ case VCMD_net_add:
21954+ return vc_net_add(nxi, data);
21955+ case VCMD_net_remove:
21956+ return vc_net_remove(nxi, data);
2ba6f0dd 21957+
4bf69007
AM
21958+ case VCMD_net_add_ipv4_v1:
21959+ return vc_net_add_ipv4_v1(nxi, data);
21960+ /* this is version 2 */
21961+ case VCMD_net_add_ipv4:
21962+ return vc_net_add_ipv4(nxi, data);
2ba6f0dd 21963+
4bf69007
AM
21964+ case VCMD_net_rem_ipv4_v1:
21965+ return vc_net_rem_ipv4_v1(nxi, data);
21966+ /* this is version 2 */
21967+ case VCMD_net_rem_ipv4:
21968+ return vc_net_rem_ipv4(nxi, data);
21969+#ifdef CONFIG_IPV6
21970+ case VCMD_net_add_ipv6:
21971+ return vc_net_add_ipv6(nxi, data);
21972+ case VCMD_net_remove_ipv6:
21973+ return vc_net_remove_ipv6(nxi, data);
21974+#endif
21975+/* case VCMD_add_match_ipv4:
21976+ return vc_add_match_ipv4(nxi, data);
21977+ case VCMD_get_match_ipv4:
21978+ return vc_get_match_ipv4(nxi, data);
21979+#ifdef CONFIG_IPV6
21980+ case VCMD_add_match_ipv6:
21981+ return vc_add_match_ipv6(nxi, data);
21982+ case VCMD_get_match_ipv6:
21983+ return vc_get_match_ipv6(nxi, data);
21984+#endif */
2ba6f0dd 21985+
4bf69007
AM
21986+#ifdef CONFIG_VSERVER_DEVICE
21987+ case VCMD_set_mapping:
21988+ return __COMPAT(vc_set_mapping, vxi, data, compat);
21989+ case VCMD_unset_mapping:
21990+ return __COMPAT(vc_unset_mapping, vxi, data, compat);
21991+#endif
21992+#ifdef CONFIG_VSERVER_HISTORY
21993+ case VCMD_dump_history:
21994+ return vc_dump_history(id);
21995+ case VCMD_read_history:
21996+ return __COMPAT(vc_read_history, id, data, compat);
21997+#endif
21998+ default:
21999+ vxwprintk_task(1, "unimplemented VCMD_%02d_%d[%d]",
22000+ VC_CATEGORY(cmd), VC_COMMAND(cmd), VC_VERSION(cmd));
22001+ }
22002+ return -ENOSYS;
22003+}
2ba6f0dd 22004+
2ba6f0dd 22005+
4bf69007
AM
22006+#define __VCMD(vcmd, _perm, _args, _flags) \
22007+ case VCMD_ ## vcmd: perm = _perm; \
22008+ args = _args; flags = _flags; break
2ba6f0dd 22009+
2ba6f0dd 22010+
4bf69007
AM
22011+#define VCA_NONE 0x00
22012+#define VCA_VXI 0x01
22013+#define VCA_NXI 0x02
2ba6f0dd 22014+
4bf69007
AM
22015+#define VCF_NONE 0x00
22016+#define VCF_INFO 0x01
22017+#define VCF_ADMIN 0x02
22018+#define VCF_ARES 0x06 /* includes admin */
22019+#define VCF_SETUP 0x08
2ba6f0dd 22020+
4bf69007 22021+#define VCF_ZIDOK 0x10 /* zero id okay */
2ba6f0dd 22022+
2ba6f0dd
AM
22023+
22024+static inline
4bf69007 22025+long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat)
2ba6f0dd 22026+{
4bf69007
AM
22027+ long ret;
22028+ int permit = -1, state = 0;
22029+ int perm = -1, args = 0, flags = 0;
22030+ struct vx_info *vxi = NULL;
22031+ struct nx_info *nxi = NULL;
2ba6f0dd 22032+
4bf69007
AM
22033+ switch (cmd) {
22034+ /* unpriviledged commands */
22035+ __VCMD(get_version, 0, VCA_NONE, 0);
22036+ __VCMD(get_vci, 0, VCA_NONE, 0);
22037+ __VCMD(get_rlimit_mask, 0, VCA_NONE, 0);
22038+ __VCMD(get_space_mask_v0,0, VCA_NONE, 0);
22039+ __VCMD(get_space_mask, 0, VCA_NONE, 0);
22040+ __VCMD(get_space_default,0, VCA_NONE, 0);
2ba6f0dd 22041+
4bf69007
AM
22042+ /* info commands */
22043+ __VCMD(task_xid, 2, VCA_NONE, 0);
22044+ __VCMD(reset_hits, 2, VCA_VXI, 0);
22045+ __VCMD(reset_minmax, 2, VCA_VXI, 0);
22046+ __VCMD(vx_info, 3, VCA_VXI, VCF_INFO);
22047+ __VCMD(get_bcaps, 3, VCA_VXI, VCF_INFO);
22048+ __VCMD(get_ccaps, 3, VCA_VXI, VCF_INFO);
22049+ __VCMD(get_cflags, 3, VCA_VXI, VCF_INFO);
22050+ __VCMD(get_umask, 3, VCA_VXI, VCF_INFO);
22051+ __VCMD(get_wmask, 3, VCA_VXI, VCF_INFO);
22052+ __VCMD(get_badness, 3, VCA_VXI, VCF_INFO);
22053+ __VCMD(get_vhi_name, 3, VCA_VXI, VCF_INFO);
22054+ __VCMD(get_rlimit, 3, VCA_VXI, VCF_INFO);
2ba6f0dd 22055+
4bf69007
AM
22056+ __VCMD(ctx_stat, 3, VCA_VXI, VCF_INFO);
22057+ __VCMD(virt_stat, 3, VCA_VXI, VCF_INFO);
22058+ __VCMD(sock_stat, 3, VCA_VXI, VCF_INFO);
22059+ __VCMD(rlimit_stat, 3, VCA_VXI, VCF_INFO);
2ba6f0dd 22060+
4bf69007
AM
22061+ __VCMD(task_nid, 2, VCA_NONE, 0);
22062+ __VCMD(nx_info, 3, VCA_NXI, VCF_INFO);
22063+ __VCMD(get_ncaps, 3, VCA_NXI, VCF_INFO);
22064+ __VCMD(get_nflags, 3, VCA_NXI, VCF_INFO);
2ba6f0dd 22065+
4bf69007 22066+ __VCMD(task_tag, 2, VCA_NONE, 0);
2ba6f0dd 22067+
4bf69007
AM
22068+ __VCMD(get_iattr, 2, VCA_NONE, 0);
22069+ __VCMD(fget_iattr, 2, VCA_NONE, 0);
22070+ __VCMD(get_dlimit, 3, VCA_NONE, VCF_INFO);
22071+ __VCMD(get_prio_bias, 3, VCA_VXI, VCF_INFO);
2ba6f0dd 22072+
4bf69007
AM
22073+ /* lower admin commands */
22074+ __VCMD(wait_exit, 4, VCA_VXI, VCF_INFO);
22075+ __VCMD(ctx_create_v0, 5, VCA_NONE, 0);
22076+ __VCMD(ctx_create, 5, VCA_NONE, 0);
22077+ __VCMD(ctx_migrate_v0, 5, VCA_VXI, VCF_ADMIN);
22078+ __VCMD(ctx_migrate, 5, VCA_VXI, VCF_ADMIN);
22079+ __VCMD(enter_space_v0, 5, VCA_VXI, VCF_ADMIN);
22080+ __VCMD(enter_space_v1, 5, VCA_VXI, VCF_ADMIN);
22081+ __VCMD(enter_space, 5, VCA_VXI, VCF_ADMIN);
2ba6f0dd 22082+
4bf69007
AM
22083+ __VCMD(net_create_v0, 5, VCA_NONE, 0);
22084+ __VCMD(net_create, 5, VCA_NONE, 0);
22085+ __VCMD(net_migrate, 5, VCA_NXI, VCF_ADMIN);
2ba6f0dd 22086+
4bf69007 22087+ __VCMD(tag_migrate, 5, VCA_NONE, VCF_ADMIN);
2ba6f0dd 22088+
4bf69007
AM
22089+ /* higher admin commands */
22090+ __VCMD(ctx_kill, 6, VCA_VXI, VCF_ARES);
22091+ __VCMD(set_space_v1, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22092+ __VCMD(set_space, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
2ba6f0dd 22093+
4bf69007
AM
22094+ __VCMD(set_ccaps, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22095+ __VCMD(set_bcaps, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22096+ __VCMD(set_cflags, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22097+ __VCMD(set_umask, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22098+ __VCMD(set_wmask, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22099+ __VCMD(set_badness, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
2ba6f0dd 22100+
4bf69007
AM
22101+ __VCMD(set_vhi_name, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22102+ __VCMD(set_rlimit, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22103+ __VCMD(set_prio_bias, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
2ba6f0dd 22104+
4bf69007
AM
22105+ __VCMD(set_ncaps, 7, VCA_NXI, VCF_ARES | VCF_SETUP);
22106+ __VCMD(set_nflags, 7, VCA_NXI, VCF_ARES | VCF_SETUP);
22107+ __VCMD(net_add, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22108+ __VCMD(net_remove, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22109+ __VCMD(net_add_ipv4_v1, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22110+ __VCMD(net_rem_ipv4_v1, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22111+ __VCMD(net_add_ipv4, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22112+ __VCMD(net_rem_ipv4, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22113+#ifdef CONFIG_IPV6
22114+ __VCMD(net_add_ipv6, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22115+ __VCMD(net_remove_ipv6, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22116+#endif
22117+ __VCMD(set_iattr, 7, VCA_NONE, 0);
22118+ __VCMD(fset_iattr, 7, VCA_NONE, 0);
22119+ __VCMD(set_dlimit, 7, VCA_NONE, VCF_ARES);
22120+ __VCMD(add_dlimit, 8, VCA_NONE, VCF_ARES);
22121+ __VCMD(rem_dlimit, 8, VCA_NONE, VCF_ARES);
2ba6f0dd 22122+
4bf69007
AM
22123+#ifdef CONFIG_VSERVER_DEVICE
22124+ __VCMD(set_mapping, 8, VCA_VXI, VCF_ARES|VCF_ZIDOK);
22125+ __VCMD(unset_mapping, 8, VCA_VXI, VCF_ARES|VCF_ZIDOK);
22126+#endif
22127+ /* debug level admin commands */
22128+#ifdef CONFIG_VSERVER_HISTORY
22129+ __VCMD(dump_history, 9, VCA_NONE, 0);
22130+ __VCMD(read_history, 9, VCA_NONE, 0);
22131+#endif
2ba6f0dd 22132+
4bf69007
AM
22133+ default:
22134+ perm = -1;
22135+ }
2ba6f0dd 22136+
4bf69007
AM
22137+ vxdprintk(VXD_CBIT(switch, 0),
22138+ "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]",
22139+ VC_CATEGORY(cmd), VC_COMMAND(cmd),
22140+ VC_VERSION(cmd), id, data, compat,
22141+ perm, args, flags);
2ba6f0dd 22142+
4bf69007
AM
22143+ ret = -ENOSYS;
22144+ if (perm < 0)
22145+ goto out;
2ba6f0dd 22146+
4bf69007
AM
22147+ state = 1;
22148+ if (!capable(CAP_CONTEXT))
22149+ goto out;
2ba6f0dd 22150+
4bf69007
AM
22151+ state = 2;
22152+ /* moved here from the individual commands */
22153+ ret = -EPERM;
22154+ if ((perm > 1) && !capable(CAP_SYS_ADMIN))
22155+ goto out;
2ba6f0dd 22156+
4bf69007
AM
22157+ state = 3;
22158+ /* vcmd involves resource management */
22159+ ret = -EPERM;
22160+ if ((flags & VCF_ARES) && !capable(CAP_SYS_RESOURCE))
22161+ goto out;
2ba6f0dd 22162+
4bf69007
AM
22163+ state = 4;
22164+ /* various legacy exceptions */
22165+ switch (cmd) {
22166+ /* will go away when spectator is a cap */
22167+ case VCMD_ctx_migrate_v0:
22168+ case VCMD_ctx_migrate:
22169+ if (id == 1) {
22170+ current->xid = 1;
22171+ ret = 1;
22172+ goto out;
22173+ }
22174+ break;
2ba6f0dd 22175+
4bf69007
AM
22176+ /* will go away when spectator is a cap */
22177+ case VCMD_net_migrate:
22178+ if (id == 1) {
22179+ current->nid = 1;
22180+ ret = 1;
22181+ goto out;
22182+ }
22183+ break;
22184+ }
2ba6f0dd 22185+
4bf69007
AM
22186+ /* vcmds are fine by default */
22187+ permit = 1;
2ba6f0dd 22188+
4bf69007
AM
22189+ /* admin type vcmds require admin ... */
22190+ if (flags & VCF_ADMIN)
22191+ permit = vx_check(0, VS_ADMIN) ? 1 : 0;
2ba6f0dd 22192+
4bf69007
AM
22193+ /* ... but setup type vcmds override that */
22194+ if (!permit && (flags & VCF_SETUP))
22195+ permit = vx_flags(VXF_STATE_SETUP, 0) ? 2 : 0;
2ba6f0dd 22196+
4bf69007
AM
22197+ state = 5;
22198+ ret = -EPERM;
22199+ if (!permit)
22200+ goto out;
2ba6f0dd 22201+
4bf69007
AM
22202+ state = 6;
22203+ if (!id && (flags & VCF_ZIDOK))
22204+ goto skip_id;
2ba6f0dd 22205+
4bf69007
AM
22206+ ret = -ESRCH;
22207+ if (args & VCA_VXI) {
22208+ vxi = lookup_vx_info(id);
22209+ if (!vxi)
22210+ goto out;
2ba6f0dd 22211+
4bf69007
AM
22212+ if ((flags & VCF_ADMIN) &&
22213+ /* special case kill for shutdown */
22214+ (cmd != VCMD_ctx_kill) &&
22215+ /* can context be administrated? */
22216+ !vx_info_flags(vxi, VXF_STATE_ADMIN, 0)) {
22217+ ret = -EACCES;
22218+ goto out_vxi;
22219+ }
22220+ }
22221+ state = 7;
22222+ if (args & VCA_NXI) {
22223+ nxi = lookup_nx_info(id);
22224+ if (!nxi)
22225+ goto out_vxi;
2ba6f0dd 22226+
4bf69007
AM
22227+ if ((flags & VCF_ADMIN) &&
22228+ /* can context be administrated? */
22229+ !nx_info_flags(nxi, NXF_STATE_ADMIN, 0)) {
22230+ ret = -EACCES;
22231+ goto out_nxi;
22232+ }
22233+ }
22234+skip_id:
22235+ state = 8;
22236+ ret = do_vcmd(cmd, id, vxi, nxi, data, compat);
2ba6f0dd 22237+
4bf69007
AM
22238+out_nxi:
22239+ if ((args & VCA_NXI) && nxi)
22240+ put_nx_info(nxi);
22241+out_vxi:
22242+ if ((args & VCA_VXI) && vxi)
22243+ put_vx_info(vxi);
22244+out:
22245+ vxdprintk(VXD_CBIT(switch, 1),
22246+ "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]",
22247+ VC_CATEGORY(cmd), VC_COMMAND(cmd),
22248+ VC_VERSION(cmd), ret, ret, state, permit);
22249+ return ret;
22250+}
2ba6f0dd 22251+
4bf69007
AM
22252+asmlinkage long
22253+sys_vserver(uint32_t cmd, uint32_t id, void __user *data)
22254+{
22255+ return do_vserver(cmd, id, data, 0);
22256+}
2ba6f0dd 22257+
4bf69007 22258+#ifdef CONFIG_COMPAT
2ba6f0dd 22259+
4bf69007
AM
22260+asmlinkage long
22261+sys32_vserver(uint32_t cmd, uint32_t id, void __user *data)
22262+{
22263+ return do_vserver(cmd, id, data, 1);
22264+}
2ba6f0dd 22265+
4bf69007 22266+#endif /* CONFIG_COMPAT */
8de2f54c 22267diff -NurpP --minimal linux-4.4.111/kernel/vserver/sysctl.c linux-4.4.111-vs2.3.9.5/kernel/vserver/sysctl.c
f19bd705 22268--- linux-4.4.111/kernel/vserver/sysctl.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 22269+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/sysctl.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
22270@@ -0,0 +1,247 @@
22271+/*
22272+ * kernel/vserver/sysctl.c
22273+ *
22274+ * Virtual Context Support
22275+ *
927ca606 22276+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
22277+ *
22278+ * V0.01 basic structure
22279+ *
22280+ */
2ba6f0dd 22281+
4bf69007
AM
22282+#include <linux/module.h>
22283+#include <linux/ctype.h>
22284+#include <linux/sysctl.h>
22285+#include <linux/parser.h>
22286+#include <asm/uaccess.h>
2ba6f0dd 22287+
4bf69007
AM
22288+enum {
22289+ CTL_DEBUG_ERROR = 0,
22290+ CTL_DEBUG_SWITCH = 1,
22291+ CTL_DEBUG_XID,
22292+ CTL_DEBUG_NID,
22293+ CTL_DEBUG_TAG,
22294+ CTL_DEBUG_NET,
22295+ CTL_DEBUG_LIMIT,
22296+ CTL_DEBUG_CRES,
22297+ CTL_DEBUG_DLIM,
22298+ CTL_DEBUG_QUOTA,
22299+ CTL_DEBUG_CVIRT,
22300+ CTL_DEBUG_SPACE,
22301+ CTL_DEBUG_PERM,
22302+ CTL_DEBUG_MISC,
2ba6f0dd
AM
22303+};
22304+
2ba6f0dd 22305+
4bf69007
AM
22306+unsigned int vs_debug_switch = 0;
22307+unsigned int vs_debug_xid = 0;
22308+unsigned int vs_debug_nid = 0;
22309+unsigned int vs_debug_tag = 0;
22310+unsigned int vs_debug_net = 0;
22311+unsigned int vs_debug_limit = 0;
22312+unsigned int vs_debug_cres = 0;
22313+unsigned int vs_debug_dlim = 0;
22314+unsigned int vs_debug_quota = 0;
22315+unsigned int vs_debug_cvirt = 0;
22316+unsigned int vs_debug_space = 0;
22317+unsigned int vs_debug_perm = 0;
22318+unsigned int vs_debug_misc = 0;
2ba6f0dd 22319+
2ba6f0dd 22320+
4bf69007 22321+static struct ctl_table_header *vserver_table_header;
bb20add7 22322+static struct ctl_table vserver_root_table[];
4bf69007 22323+
2ba6f0dd 22324+
4bf69007
AM
22325+void vserver_register_sysctl(void)
22326+{
22327+ if (!vserver_table_header) {
22328+ vserver_table_header = register_sysctl_table(vserver_root_table);
22329+ }
2ba6f0dd 22330+
4bf69007 22331+}
2ba6f0dd 22332+
4bf69007
AM
22333+void vserver_unregister_sysctl(void)
22334+{
22335+ if (vserver_table_header) {
22336+ unregister_sysctl_table(vserver_table_header);
22337+ vserver_table_header = NULL;
22338+ }
22339+}
2ba6f0dd 22340+
2ba6f0dd 22341+
bb20add7 22342+static int proc_dodebug(struct ctl_table *table, int write,
4bf69007
AM
22343+ void __user *buffer, size_t *lenp, loff_t *ppos)
22344+{
22345+ char tmpbuf[20], *p, c;
22346+ unsigned int value;
22347+ size_t left, len;
2ba6f0dd 22348+
4bf69007
AM
22349+ if ((*ppos && !write) || !*lenp) {
22350+ *lenp = 0;
22351+ return 0;
22352+ }
2ba6f0dd 22353+
4bf69007 22354+ left = *lenp;
2ba6f0dd 22355+
4bf69007
AM
22356+ if (write) {
22357+ if (!access_ok(VERIFY_READ, buffer, left))
22358+ return -EFAULT;
22359+ p = (char *)buffer;
22360+ while (left && __get_user(c, p) >= 0 && isspace(c))
22361+ left--, p++;
22362+ if (!left)
22363+ goto done;
2ba6f0dd 22364+
4bf69007
AM
22365+ if (left > sizeof(tmpbuf) - 1)
22366+ return -EINVAL;
22367+ if (copy_from_user(tmpbuf, p, left))
22368+ return -EFAULT;
22369+ tmpbuf[left] = '\0';
2ba6f0dd 22370+
4bf69007
AM
22371+ for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--)
22372+ value = 10 * value + (*p - '0');
22373+ if (*p && !isspace(*p))
22374+ return -EINVAL;
22375+ while (left && isspace(*p))
22376+ left--, p++;
22377+ *(unsigned int *)table->data = value;
22378+ } else {
22379+ if (!access_ok(VERIFY_WRITE, buffer, left))
22380+ return -EFAULT;
22381+ len = sprintf(tmpbuf, "%d", *(unsigned int *)table->data);
22382+ if (len > left)
22383+ len = left;
22384+ if (__copy_to_user(buffer, tmpbuf, len))
22385+ return -EFAULT;
22386+ if ((left -= len) > 0) {
22387+ if (put_user('\n', (char *)buffer + len))
22388+ return -EFAULT;
22389+ left--;
22390+ }
22391+ }
2ba6f0dd 22392+
4bf69007
AM
22393+done:
22394+ *lenp -= left;
22395+ *ppos += *lenp;
22396+ return 0;
22397+}
2ba6f0dd 22398+
4bf69007 22399+static int zero;
2ba6f0dd 22400+
4bf69007
AM
22401+#define CTL_ENTRY(ctl, name) \
22402+ { \
22403+ .procname = #name, \
22404+ .data = &vs_ ## name, \
22405+ .maxlen = sizeof(int), \
22406+ .mode = 0644, \
22407+ .proc_handler = &proc_dodebug, \
22408+ .extra1 = &zero, \
22409+ .extra2 = &zero, \
22410+ }
2ba6f0dd 22411+
bb20add7 22412+static struct ctl_table vserver_debug_table[] = {
4bf69007
AM
22413+ CTL_ENTRY(CTL_DEBUG_SWITCH, debug_switch),
22414+ CTL_ENTRY(CTL_DEBUG_XID, debug_xid),
22415+ CTL_ENTRY(CTL_DEBUG_NID, debug_nid),
22416+ CTL_ENTRY(CTL_DEBUG_TAG, debug_tag),
22417+ CTL_ENTRY(CTL_DEBUG_NET, debug_net),
22418+ CTL_ENTRY(CTL_DEBUG_LIMIT, debug_limit),
22419+ CTL_ENTRY(CTL_DEBUG_CRES, debug_cres),
22420+ CTL_ENTRY(CTL_DEBUG_DLIM, debug_dlim),
22421+ CTL_ENTRY(CTL_DEBUG_QUOTA, debug_quota),
22422+ CTL_ENTRY(CTL_DEBUG_CVIRT, debug_cvirt),
22423+ CTL_ENTRY(CTL_DEBUG_SPACE, debug_space),
22424+ CTL_ENTRY(CTL_DEBUG_PERM, debug_perm),
22425+ CTL_ENTRY(CTL_DEBUG_MISC, debug_misc),
22426+ { 0 }
22427+};
2ba6f0dd 22428+
bb20add7 22429+static struct ctl_table vserver_root_table[] = {
4bf69007
AM
22430+ {
22431+ .procname = "vserver",
22432+ .mode = 0555,
22433+ .child = vserver_debug_table
22434+ },
22435+ { 0 }
22436+};
2ba6f0dd 22437+
2ba6f0dd 22438+
4bf69007
AM
22439+static match_table_t tokens = {
22440+ { CTL_DEBUG_SWITCH, "switch=%x" },
22441+ { CTL_DEBUG_XID, "xid=%x" },
22442+ { CTL_DEBUG_NID, "nid=%x" },
22443+ { CTL_DEBUG_TAG, "tag=%x" },
22444+ { CTL_DEBUG_NET, "net=%x" },
22445+ { CTL_DEBUG_LIMIT, "limit=%x" },
22446+ { CTL_DEBUG_CRES, "cres=%x" },
22447+ { CTL_DEBUG_DLIM, "dlim=%x" },
22448+ { CTL_DEBUG_QUOTA, "quota=%x" },
22449+ { CTL_DEBUG_CVIRT, "cvirt=%x" },
22450+ { CTL_DEBUG_SPACE, "space=%x" },
22451+ { CTL_DEBUG_PERM, "perm=%x" },
22452+ { CTL_DEBUG_MISC, "misc=%x" },
22453+ { CTL_DEBUG_ERROR, NULL }
22454+};
2ba6f0dd 22455+
4bf69007
AM
22456+#define HANDLE_CASE(id, name, val) \
22457+ case CTL_DEBUG_ ## id: \
22458+ vs_debug_ ## name = val; \
22459+ printk("vs_debug_" #name "=0x%x\n", val); \
22460+ break
2ba6f0dd 22461+
2ba6f0dd 22462+
4bf69007
AM
22463+static int __init vs_debug_setup(char *str)
22464+{
22465+ char *p;
22466+ int token;
2ba6f0dd 22467+
4bf69007
AM
22468+ printk("vs_debug_setup(%s)\n", str);
22469+ while ((p = strsep(&str, ",")) != NULL) {
22470+ substring_t args[MAX_OPT_ARGS];
22471+ unsigned int value;
2ba6f0dd 22472+
4bf69007
AM
22473+ if (!*p)
22474+ continue;
2ba6f0dd 22475+
4bf69007
AM
22476+ token = match_token(p, tokens, args);
22477+ value = (token > 0) ? simple_strtoul(args[0].from, NULL, 0) : 0;
2ba6f0dd 22478+
4bf69007
AM
22479+ switch (token) {
22480+ HANDLE_CASE(SWITCH, switch, value);
22481+ HANDLE_CASE(XID, xid, value);
22482+ HANDLE_CASE(NID, nid, value);
22483+ HANDLE_CASE(TAG, tag, value);
22484+ HANDLE_CASE(NET, net, value);
22485+ HANDLE_CASE(LIMIT, limit, value);
22486+ HANDLE_CASE(CRES, cres, value);
22487+ HANDLE_CASE(DLIM, dlim, value);
22488+ HANDLE_CASE(QUOTA, quota, value);
22489+ HANDLE_CASE(CVIRT, cvirt, value);
22490+ HANDLE_CASE(SPACE, space, value);
22491+ HANDLE_CASE(PERM, perm, value);
22492+ HANDLE_CASE(MISC, misc, value);
22493+ default:
22494+ return -EINVAL;
22495+ break;
22496+ }
22497+ }
22498+ return 1;
22499+}
2ba6f0dd 22500+
4bf69007 22501+__setup("vsdebug=", vs_debug_setup);
2ba6f0dd 22502+
2ba6f0dd 22503+
2ba6f0dd 22504+
4bf69007
AM
22505+EXPORT_SYMBOL_GPL(vs_debug_switch);
22506+EXPORT_SYMBOL_GPL(vs_debug_xid);
22507+EXPORT_SYMBOL_GPL(vs_debug_nid);
22508+EXPORT_SYMBOL_GPL(vs_debug_net);
22509+EXPORT_SYMBOL_GPL(vs_debug_limit);
22510+EXPORT_SYMBOL_GPL(vs_debug_cres);
22511+EXPORT_SYMBOL_GPL(vs_debug_dlim);
22512+EXPORT_SYMBOL_GPL(vs_debug_quota);
22513+EXPORT_SYMBOL_GPL(vs_debug_cvirt);
22514+EXPORT_SYMBOL_GPL(vs_debug_space);
22515+EXPORT_SYMBOL_GPL(vs_debug_perm);
22516+EXPORT_SYMBOL_GPL(vs_debug_misc);
2ba6f0dd 22517+
8de2f54c 22518diff -NurpP --minimal linux-4.4.111/kernel/vserver/tag.c linux-4.4.111-vs2.3.9.5/kernel/vserver/tag.c
f19bd705 22519--- linux-4.4.111/kernel/vserver/tag.c 1970-01-01 00:00:00.000000000 +0000
8de2f54c 22520+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/tag.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
22521@@ -0,0 +1,63 @@
22522+/*
22523+ * linux/kernel/vserver/tag.c
22524+ *
22525+ * Virtual Server: Shallow Tag Space
22526+ *
927ca606 22527+ * Copyright (C) 2007 Herbert P?tzl
4bf69007
AM
22528+ *
22529+ * V0.01 basic implementation
22530+ *
22531+ */
2ba6f0dd 22532+
4bf69007
AM
22533+#include <linux/sched.h>
22534+#include <linux/vserver/debug.h>
22535+#include <linux/vs_pid.h>
22536+#include <linux/vs_tag.h>
2ba6f0dd 22537+
4bf69007 22538+#include <linux/vserver/tag_cmd.h>
2ba6f0dd 22539+
2ba6f0dd 22540+
61333608 22541+int dx_migrate_task(struct task_struct *p, vtag_t tag)
4bf69007
AM
22542+{
22543+ if (!p)
22544+ BUG();
2ba6f0dd 22545+
4bf69007
AM
22546+ vxdprintk(VXD_CBIT(tag, 5),
22547+ "dx_migrate_task(%p[#%d],#%d)", p, p->tag, tag);
2ba6f0dd 22548+
4bf69007
AM
22549+ task_lock(p);
22550+ p->tag = tag;
22551+ task_unlock(p);
2ba6f0dd 22552+
4bf69007
AM
22553+ vxdprintk(VXD_CBIT(tag, 5),
22554+ "moved task %p into [#%d]", p, tag);
22555+ return 0;
22556+}
2ba6f0dd 22557+
4bf69007 22558+/* vserver syscall commands below here */
2ba6f0dd 22559+
4bf69007 22560+/* taks xid and vx_info functions */
2ba6f0dd 22561+
2ba6f0dd 22562+
4bf69007
AM
22563+int vc_task_tag(uint32_t id)
22564+{
61333608 22565+ vtag_t tag;
2ba6f0dd 22566+
4bf69007
AM
22567+ if (id) {
22568+ struct task_struct *tsk;
22569+ rcu_read_lock();
22570+ tsk = find_task_by_real_pid(id);
22571+ tag = (tsk) ? tsk->tag : -ESRCH;
22572+ rcu_read_unlock();
22573+ } else
22574+ tag = dx_current_tag();
22575+ return tag;
22576+}
2ba6f0dd 22577+
2ba6f0dd 22578+
4bf69007
AM
22579+int vc_tag_migrate(uint32_t tag)
22580+{
22581+ return dx_migrate_task(current, tag & 0xFFFF);
22582+}
2ba6f0dd 22583+
2ba6f0dd 22584+
8de2f54c 22585diff -NurpP --minimal linux-4.4.111/kernel/vserver/vci_config.h linux-4.4.111-vs2.3.9.5/kernel/vserver/vci_config.h
f19bd705 22586--- linux-4.4.111/kernel/vserver/vci_config.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 22587+++ linux-4.4.111-vs2.3.9.5/kernel/vserver/vci_config.h 2018-01-09 16:36:34.000000000 +0000
4bf69007 22588@@ -0,0 +1,80 @@
2ba6f0dd 22589+
4bf69007 22590+/* interface version */
2ba6f0dd 22591+
4bf69007 22592+#define VCI_VERSION 0x00020308
2ba6f0dd 22593+
2ba6f0dd 22594+
4bf69007
AM
22595+enum {
22596+ VCI_KCBIT_NO_DYNAMIC = 0,
2ba6f0dd 22597+
4bf69007
AM
22598+ VCI_KCBIT_PROC_SECURE = 4,
22599+ /* VCI_KCBIT_HARDCPU = 5, */
22600+ /* VCI_KCBIT_IDLELIMIT = 6, */
22601+ /* VCI_KCBIT_IDLETIME = 7, */
2ba6f0dd 22602+
4bf69007
AM
22603+ VCI_KCBIT_COWBL = 8,
22604+ VCI_KCBIT_FULLCOWBL = 9,
22605+ VCI_KCBIT_SPACES = 10,
22606+ VCI_KCBIT_NETV2 = 11,
22607+ VCI_KCBIT_MEMCG = 12,
22608+ VCI_KCBIT_MEMCG_SWAP = 13,
2ba6f0dd 22609+
4bf69007
AM
22610+ VCI_KCBIT_DEBUG = 16,
22611+ VCI_KCBIT_HISTORY = 20,
22612+ VCI_KCBIT_TAGGED = 24,
22613+ VCI_KCBIT_PPTAG = 28,
2ba6f0dd 22614+
4bf69007 22615+ VCI_KCBIT_MORE = 31,
2ba6f0dd
AM
22616+};
22617+
2ba6f0dd 22618+
4bf69007
AM
22619+static inline uint32_t vci_kernel_config(void)
22620+{
22621+ return
22622+ (1 << VCI_KCBIT_NO_DYNAMIC) |
2ba6f0dd 22623+
4bf69007
AM
22624+ /* configured features */
22625+#ifdef CONFIG_VSERVER_PROC_SECURE
22626+ (1 << VCI_KCBIT_PROC_SECURE) |
22627+#endif
22628+#ifdef CONFIG_VSERVER_COWBL
22629+ (1 << VCI_KCBIT_COWBL) |
22630+ (1 << VCI_KCBIT_FULLCOWBL) |
22631+#endif
22632+ (1 << VCI_KCBIT_SPACES) |
22633+ (1 << VCI_KCBIT_NETV2) |
22634+#ifdef CONFIG_MEMCG
22635+ (1 << VCI_KCBIT_MEMCG) |
22636+#endif
22637+#ifdef CONFIG_MEMCG_SWAP
22638+ (1 << VCI_KCBIT_MEMCG_SWAP) |
22639+#endif
2ba6f0dd 22640+
4bf69007
AM
22641+ /* debug options */
22642+#ifdef CONFIG_VSERVER_DEBUG
22643+ (1 << VCI_KCBIT_DEBUG) |
22644+#endif
22645+#ifdef CONFIG_VSERVER_HISTORY
22646+ (1 << VCI_KCBIT_HISTORY) |
22647+#endif
2ba6f0dd 22648+
4bf69007
AM
22649+ /* inode context tagging */
22650+#if defined(CONFIG_TAGGING_NONE)
22651+ (0 << VCI_KCBIT_TAGGED) |
22652+#elif defined(CONFIG_TAGGING_UID16)
22653+ (1 << VCI_KCBIT_TAGGED) |
22654+#elif defined(CONFIG_TAGGING_GID16)
22655+ (2 << VCI_KCBIT_TAGGED) |
22656+#elif defined(CONFIG_TAGGING_ID24)
22657+ (3 << VCI_KCBIT_TAGGED) |
22658+#elif defined(CONFIG_TAGGING_INTERN)
22659+ (4 << VCI_KCBIT_TAGGED) |
22660+#elif defined(CONFIG_TAGGING_RUNTIME)
22661+ (5 << VCI_KCBIT_TAGGED) |
22662+#else
22663+ (7 << VCI_KCBIT_TAGGED) |
22664+#endif
22665+ (1 << VCI_KCBIT_PPTAG) |
22666+ 0;
22667+}
2ba6f0dd 22668+
8de2f54c 22669diff -NurpP --minimal linux-4.4.111/mm/memcontrol.c linux-4.4.111-vs2.3.9.5/mm/memcontrol.c
f19bd705 22670--- linux-4.4.111/mm/memcontrol.c 2018-01-11 07:57:53.000000000 +0000
8de2f54c 22671+++ linux-4.4.111-vs2.3.9.5/mm/memcontrol.c 2018-01-09 16:36:34.000000000 +0000
927ca606
AM
22672@@ -2888,6 +2888,28 @@ static u64 mem_cgroup_read_u64(struct cg
22673 }
4bf69007
AM
22674 }
22675
927ca606 22676+u64 mem_cgroup_mem_usage_pages(struct mem_cgroup *memcg)
4bf69007 22677+{
927ca606 22678+ return mem_cgroup_usage(memcg, false) >> PAGE_SHIFT;
4bf69007 22679+}
2ba6f0dd 22680+
927ca606 22681+u64 mem_cgroup_mem_limit_pages(struct mem_cgroup *memcg)
4bf69007 22682+{
927ca606 22683+ return (u64)memcg->memory.limit;
4bf69007 22684+}
2ba6f0dd 22685+
927ca606 22686+u64 mem_cgroup_memsw_usage_pages(struct mem_cgroup *memcg)
4bf69007 22687+{
927ca606 22688+ return mem_cgroup_usage(memcg, true) >> PAGE_SHIFT;
4bf69007 22689+}
2ba6f0dd 22690+
927ca606 22691+u64 mem_cgroup_memsw_limit_pages(struct mem_cgroup *memcg)
4bf69007 22692+{
927ca606 22693+ return (u64)memcg->memsw.limit;
4bf69007 22694+}
2ba6f0dd
AM
22695+
22696+
927ca606
AM
22697+
22698 #ifdef CONFIG_MEMCG_KMEM
22699 static int memcg_activate_kmem(struct mem_cgroup *memcg,
22700 unsigned long nr_pages)
8de2f54c 22701diff -NurpP --minimal linux-4.4.111/mm/oom_kill.c linux-4.4.111-vs2.3.9.5/mm/oom_kill.c
f19bd705 22702--- linux-4.4.111/mm/oom_kill.c 2016-07-05 04:15:13.000000000 +0000
8de2f54c 22703+++ linux-4.4.111-vs2.3.9.5/mm/oom_kill.c 2018-01-09 16:56:23.000000000 +0000
4bf69007
AM
22704@@ -35,6 +35,8 @@
22705 #include <linux/freezer.h>
22706 #include <linux/ftrace.h>
22707 #include <linux/ratelimit.h>
22708+#include <linux/reboot.h>
22709+#include <linux/vs_context.h>
22710
22711 #define CREATE_TRACE_POINTS
22712 #include <trace/events/oom.h>
927ca606 22713@@ -131,11 +133,18 @@ static inline bool is_sysrq_oom(struct o
4bf69007 22714 static bool oom_unkillable_task(struct task_struct *p,
927ca606 22715 struct mem_cgroup *memcg, const nodemask_t *nodemask)
4bf69007
AM
22716 {
22717- if (is_global_init(p))
22718+ unsigned xid = vx_current_xid();
2ba6f0dd 22719+
4bf69007
AM
22720+ /* skip the init task, global and per guest */
22721+ if (task_is_init(p))
22722 return true;
22723 if (p->flags & PF_KTHREAD)
22724 return true;
22725
22726+ /* skip other guest and host processes if oom in guest */
22727+ if (xid && vx_task_xid(p) != xid)
22728+ return true;
2ba6f0dd 22729+
4bf69007
AM
22730 /* When mem_cgroup_out_of_memory() and p is not member of the group */
22731 if (memcg && !task_in_mem_cgroup(p, memcg))
22732 return true;
927ca606
AM
22733@@ -534,8 +543,8 @@ void oom_kill_process(struct oom_control
22734 if (__ratelimit(&oom_rs))
22735 dump_header(oc, p, memcg);
4bf69007 22736
927ca606 22737- pr_err("%s: Kill process %d (%s) score %u or sacrifice child\n",
4bf69007
AM
22738- message, task_pid_nr(p), p->comm, points);
22739+ pr_err("%s: Kill process %d:#%u (%s) score %d or sacrifice child\n",
22740+ message, task_pid_nr(p), p->xid, p->comm, points);
4bf69007
AM
22741
22742 /*
927ca606
AM
22743 * If any of p's children has a different mm and is eligible for kill,
22744@@ -585,8 +594,8 @@ void oom_kill_process(struct oom_control
22745 */
22746 do_send_sig_info(SIGKILL, SEND_SIG_FORCED, victim, true);
22747 mark_oom_victim(victim);
4bf69007
AM
22748- pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
22749- task_pid_nr(victim), victim->comm, K(victim->mm->total_vm),
927ca606 22750+ pr_err("Killed process %d:%u (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
4bf69007
AM
22751+ task_pid_nr(victim), victim->xid, victim->comm, K(victim->mm->total_vm),
22752 K(get_mm_counter(victim->mm, MM_ANONPAGES)),
22753 K(get_mm_counter(victim->mm, MM_FILEPAGES)));
22754 task_unlock(victim);
927ca606 22755@@ -622,6 +631,8 @@ void oom_kill_process(struct oom_control
4bf69007 22756 }
927ca606 22757 #undef K
4bf69007
AM
22758
22759+long vs_oom_action(unsigned int);
2ba6f0dd 22760+
4bf69007 22761 /*
927ca606
AM
22762 * Determines whether the kernel must panic because of the panic_on_oom sysctl.
22763 */
22764@@ -722,7 +733,12 @@ bool out_of_memory(struct oom_control *o
4bf69007 22765 /* Found nothing?!?! Either we hang forever, or we panic. */
927ca606
AM
22766 if (!p && !is_sysrq_oom(oc)) {
22767 dump_header(oc, NULL, NULL);
4bf69007 22768- panic("Out of memory and no killable processes...\n");
2ba6f0dd 22769+
4bf69007
AM
22770+ /* avoid panic for guest OOM */
22771+ if (vx_current_xid())
22772+ vs_oom_action(LINUX_REBOOT_CMD_OOM);
22773+ else
22774+ panic("Out of memory and no killable processes...\n");
22775 }
927ca606
AM
22776 if (p && p != (void *)-1UL) {
22777 oom_kill_process(oc, p, points, totalpages, NULL,
8de2f54c 22778diff -NurpP --minimal linux-4.4.111/mm/page_alloc.c linux-4.4.111-vs2.3.9.5/mm/page_alloc.c
f19bd705 22779--- linux-4.4.111/mm/page_alloc.c 2018-01-11 07:57:53.000000000 +0000
8de2f54c 22780+++ linux-4.4.111-vs2.3.9.5/mm/page_alloc.c 2018-01-09 16:57:52.000000000 +0000
927ca606 22781@@ -62,6 +62,8 @@
b00e13aa 22782 #include <linux/sched/rt.h>
927ca606
AM
22783 #include <linux/page_owner.h>
22784 #include <linux/kthread.h>
4bf69007
AM
22785+#include <linux/vs_base.h>
22786+#include <linux/vs_limit.h>
22787
c2e5f7c8 22788 #include <asm/sections.h>
4bf69007 22789 #include <asm/tlbflush.h>
927ca606 22790@@ -3661,6 +3663,9 @@ void si_meminfo(struct sysinfo *val)
4bf69007
AM
22791 val->totalhigh = totalhigh_pages;
22792 val->freehigh = nr_free_highpages();
22793 val->mem_unit = PAGE_SIZE;
2ba6f0dd 22794+
4bf69007
AM
22795+ if (vx_flags(VXF_VIRT_MEM, 0))
22796+ vx_vsi_meminfo(val);
22797 }
22798
22799 EXPORT_SYMBOL(si_meminfo);
927ca606 22800@@ -3686,6 +3691,9 @@ void si_meminfo_node(struct sysinfo *val
4bf69007
AM
22801 val->freehigh = 0;
22802 #endif
22803 val->mem_unit = PAGE_SIZE;
2ba6f0dd 22804+
4bf69007
AM
22805+ if (vx_flags(VXF_VIRT_MEM, 0))
22806+ vx_vsi_meminfo(val);
22807 }
22808 #endif
22809
8de2f54c 22810diff -NurpP --minimal linux-4.4.111/mm/pgtable-generic.c linux-4.4.111-vs2.3.9.5/mm/pgtable-generic.c
f19bd705 22811--- linux-4.4.111/mm/pgtable-generic.c 2018-01-11 07:57:53.000000000 +0000
8de2f54c 22812+++ linux-4.4.111-vs2.3.9.5/mm/pgtable-generic.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
22813@@ -6,6 +6,8 @@
22814 * Copyright (C) 2010 Linus Torvalds
22815 */
22816
22817+#include <linux/mm.h>
2ba6f0dd 22818+
4bf69007
AM
22819 #include <linux/pagemap.h>
22820 #include <asm/tlb.h>
22821 #include <asm-generic/pgtable.h>
8de2f54c 22822diff -NurpP --minimal linux-4.4.111/mm/shmem.c linux-4.4.111-vs2.3.9.5/mm/shmem.c
f19bd705 22823--- linux-4.4.111/mm/shmem.c 2018-01-11 07:57:53.000000000 +0000
8de2f54c 22824+++ linux-4.4.111-vs2.3.9.5/mm/shmem.c 2018-01-09 16:36:34.000000000 +0000
927ca606 22825@@ -2198,7 +2198,7 @@ static int shmem_statfs(struct dentry *d
4bf69007
AM
22826 {
22827 struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
22828
22829- buf->f_type = TMPFS_MAGIC;
22830+ buf->f_type = TMPFS_SUPER_MAGIC;
22831 buf->f_bsize = PAGE_CACHE_SIZE;
22832 buf->f_namelen = NAME_MAX;
22833 if (sbinfo->max_blocks) {
927ca606 22834@@ -3044,7 +3044,7 @@ int shmem_fill_super(struct super_block
4bf69007
AM
22835 sb->s_maxbytes = MAX_LFS_FILESIZE;
22836 sb->s_blocksize = PAGE_CACHE_SIZE;
22837 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
22838- sb->s_magic = TMPFS_MAGIC;
22839+ sb->s_magic = TMPFS_SUPER_MAGIC;
22840 sb->s_op = &shmem_ops;
22841 sb->s_time_gran = 1;
22842 #ifdef CONFIG_TMPFS_XATTR
8de2f54c 22843diff -NurpP --minimal linux-4.4.111/mm/slab.c linux-4.4.111-vs2.3.9.5/mm/slab.c
f19bd705 22844--- linux-4.4.111/mm/slab.c 2016-07-05 04:15:13.000000000 +0000
8de2f54c 22845+++ linux-4.4.111-vs2.3.9.5/mm/slab.c 2018-01-09 16:36:34.000000000 +0000
927ca606 22846@@ -337,6 +337,8 @@ static void kmem_cache_node_init(struct
4bf69007
AM
22847 #define STATS_INC_FREEMISS(x) do { } while (0)
22848 #endif
22849
22850+#include "slab_vs.h"
2ba6f0dd 22851+
4bf69007
AM
22852 #if DEBUG
22853
22854 /*
927ca606 22855@@ -3183,6 +3185,7 @@ slab_alloc_node(struct kmem_cache *cache
4bf69007
AM
22856 /* ___cache_alloc_node can fall back to other nodes */
22857 ptr = ____cache_alloc_node(cachep, flags, nodeid);
22858 out:
22859+ vx_slab_alloc(cachep, flags);
22860 local_irq_restore(save_flags);
22861 ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller);
22862 kmemleak_alloc_recursive(ptr, cachep->object_size, 1, cachep->flags,
927ca606 22863@@ -3371,6 +3374,7 @@ static inline void __cache_free(struct k
4bf69007
AM
22864 check_irq_off();
22865 kmemleak_free_recursive(objp, cachep->flags);
22866 objp = cache_free_debugcheck(cachep, objp, caller);
22867+ vx_slab_free(cachep);
22868
22869 kmemcheck_slab_free(cachep, objp, cachep->object_size);
22870
8de2f54c 22871diff -NurpP --minimal linux-4.4.111/mm/slab_vs.h linux-4.4.111-vs2.3.9.5/mm/slab_vs.h
f19bd705 22872--- linux-4.4.111/mm/slab_vs.h 1970-01-01 00:00:00.000000000 +0000
8de2f54c 22873+++ linux-4.4.111-vs2.3.9.5/mm/slab_vs.h 2018-01-09 16:36:34.000000000 +0000
4bf69007 22874@@ -0,0 +1,29 @@
2ba6f0dd 22875+
4bf69007 22876+#include <linux/vserver/context.h>
2ba6f0dd 22877+
4bf69007 22878+#include <linux/vs_context.h>
2ba6f0dd 22879+
4bf69007
AM
22880+static inline
22881+void vx_slab_alloc(struct kmem_cache *cachep, gfp_t flags)
22882+{
22883+ int what = gfp_zone(cachep->allocflags);
22884+ struct vx_info *vxi = current_vx_info();
2ba6f0dd 22885+
4bf69007
AM
22886+ if (!vxi)
22887+ return;
2ba6f0dd 22888+
4bf69007
AM
22889+ atomic_add(cachep->size, &vxi->cacct.slab[what]);
22890+}
2ba6f0dd 22891+
4bf69007
AM
22892+static inline
22893+void vx_slab_free(struct kmem_cache *cachep)
22894+{
22895+ int what = gfp_zone(cachep->allocflags);
22896+ struct vx_info *vxi = current_vx_info();
2ba6f0dd 22897+
4bf69007
AM
22898+ if (!vxi)
22899+ return;
2ba6f0dd 22900+
4bf69007
AM
22901+ atomic_sub(cachep->size, &vxi->cacct.slab[what]);
22902+}
2ba6f0dd 22903+
8de2f54c 22904diff -NurpP --minimal linux-4.4.111/mm/swapfile.c linux-4.4.111-vs2.3.9.5/mm/swapfile.c
f19bd705 22905--- linux-4.4.111/mm/swapfile.c 2018-01-11 07:57:53.000000000 +0000
8de2f54c 22906+++ linux-4.4.111-vs2.3.9.5/mm/swapfile.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
22907@@ -39,6 +39,7 @@
22908 #include <asm/tlbflush.h>
22909 #include <linux/swapops.h>
927ca606 22910 #include <linux/swap_cgroup.h>
4bf69007
AM
22911+#include <linux/vs_base.h>
22912
22913 static bool swap_count_continued(struct swap_info_struct *, pgoff_t,
22914 unsigned char);
927ca606 22915@@ -2070,6 +2071,16 @@ static int swap_show(struct seq_file *sw
4bf69007
AM
22916
22917 if (si == SEQ_START_TOKEN) {
22918 seq_puts(swap,"Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
22919+ if (vx_flags(VXF_VIRT_MEM, 0)) {
927ca606 22920+ struct sysinfo si = { 0 };
2ba6f0dd 22921+
4bf69007
AM
22922+ vx_vsi_swapinfo(&si);
22923+ if (si.totalswap < (1 << 10))
22924+ return 0;
22925+ seq_printf(swap, "%s\t\t\t\t\t%s\t%lu\t%lu\t%d\n",
22926+ "hdv0", "partition", si.totalswap >> 10,
22927+ (si.totalswap - si.freeswap) >> 10, -1);
22928+ }
22929 return 0;
22930 }
22931
927ca606 22932@@ -2609,6 +2620,8 @@ void si_swapinfo(struct sysinfo *val)
b00e13aa 22933 val->freeswap = atomic_long_read(&nr_swap_pages) + nr_to_be_unused;
4bf69007
AM
22934 val->totalswap = total_swap_pages + nr_to_be_unused;
22935 spin_unlock(&swap_lock);
22936+ if (vx_flags(VXF_VIRT_MEM, 0))
22937+ vx_vsi_swapinfo(val);
22938 }
22939
22940 /*
8de2f54c 22941diff -NurpP --minimal linux-4.4.111/net/bridge/br_multicast.c linux-4.4.111-vs2.3.9.5/net/bridge/br_multicast.c
f19bd705 22942--- linux-4.4.111/net/bridge/br_multicast.c 2018-01-11 07:57:54.000000000 +0000
8de2f54c 22943+++ linux-4.4.111-vs2.3.9.5/net/bridge/br_multicast.c 2018-01-09 16:36:34.000000000 +0000
927ca606 22944@@ -462,7 +462,7 @@ static struct sk_buff *br_ip6_multicast_
4bf69007
AM
22945 ip6h->hop_limit = 1;
22946 ipv6_addr_set(&ip6h->daddr, htonl(0xff020000), 0, 0, htonl(1));
22947 if (ipv6_dev_get_saddr(dev_net(br->dev), br->dev, &ip6h->daddr, 0,
22948- &ip6h->saddr)) {
22949+ &ip6h->saddr, NULL)) {
22950 kfree_skb(skb);
927ca606 22951 br->has_ipv6_addr = 0;
4bf69007 22952 return NULL;
8de2f54c 22953diff -NurpP --minimal linux-4.4.111/net/core/dev.c linux-4.4.111-vs2.3.9.5/net/core/dev.c
f19bd705 22954--- linux-4.4.111/net/core/dev.c 2018-01-11 07:57:54.000000000 +0000
8de2f54c 22955+++ linux-4.4.111-vs2.3.9.5/net/core/dev.c 2018-01-09 16:36:34.000000000 +0000
927ca606 22956@@ -124,6 +124,7 @@
4bf69007
AM
22957 #include <linux/in.h>
22958 #include <linux/jhash.h>
22959 #include <linux/random.h>
22960+#include <linux/vs_inet.h>
22961 #include <trace/events/napi.h>
22962 #include <trace/events/net.h>
22963 #include <trace/events/skb.h>
927ca606 22964@@ -726,7 +727,8 @@ struct net_device *__dev_get_by_name(str
4bf69007
AM
22965 struct hlist_head *head = dev_name_hash(net, name);
22966
b00e13aa 22967 hlist_for_each_entry(dev, head, name_hlist)
4bf69007
AM
22968- if (!strncmp(dev->name, name, IFNAMSIZ))
22969+ if (!strncmp(dev->name, name, IFNAMSIZ) &&
22970+ nx_dev_visible(current_nx_info(), dev))
22971 return dev;
22972
22973 return NULL;
927ca606 22974@@ -751,7 +753,8 @@ struct net_device *dev_get_by_name_rcu(s
4bf69007
AM
22975 struct hlist_head *head = dev_name_hash(net, name);
22976
b00e13aa 22977 hlist_for_each_entry_rcu(dev, head, name_hlist)
4bf69007
AM
22978- if (!strncmp(dev->name, name, IFNAMSIZ))
22979+ if (!strncmp(dev->name, name, IFNAMSIZ) &&
22980+ nx_dev_visible(current_nx_info(), dev))
22981 return dev;
22982
22983 return NULL;
927ca606 22984@@ -801,7 +804,8 @@ struct net_device *__dev_get_by_index(st
4bf69007
AM
22985 struct hlist_head *head = dev_index_hash(net, ifindex);
22986
b00e13aa 22987 hlist_for_each_entry(dev, head, index_hlist)
4bf69007
AM
22988- if (dev->ifindex == ifindex)
22989+ if ((dev->ifindex == ifindex) &&
22990+ nx_dev_visible(current_nx_info(), dev))
22991 return dev;
22992
22993 return NULL;
927ca606 22994@@ -819,7 +823,7 @@ EXPORT_SYMBOL(__dev_get_by_index);
4bf69007
AM
22995 * about locking. The caller must hold RCU lock.
22996 */
22997
22998-struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex)
22999+struct net_device *dev_get_by_index_real_rcu(struct net *net, int ifindex)
23000 {
4bf69007 23001 struct net_device *dev;
b00e13aa 23002 struct hlist_head *head = dev_index_hash(net, ifindex);
927ca606 23003@@ -830,6 +834,16 @@ struct net_device *dev_get_by_index_rcu(
4bf69007
AM
23004
23005 return NULL;
23006 }
23007+EXPORT_SYMBOL(dev_get_by_index_real_rcu);
2ba6f0dd 23008+
4bf69007
AM
23009+struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex)
23010+{
23011+ struct net_device *dev = dev_get_by_index_real_rcu(net, ifindex);
2ba6f0dd 23012+
4bf69007
AM
23013+ if (nx_dev_visible(current_nx_info(), dev))
23014+ return dev;
23015+ return NULL;
23016+}
23017 EXPORT_SYMBOL(dev_get_by_index_rcu);
23018
23019
927ca606 23020@@ -912,7 +926,8 @@ struct net_device *dev_getbyhwaddr_rcu(s
4bf69007
AM
23021
23022 for_each_netdev_rcu(net, dev)
23023 if (dev->type == type &&
23024- !memcmp(dev->dev_addr, ha, dev->addr_len))
23025+ !memcmp(dev->dev_addr, ha, dev->addr_len) &&
23026+ nx_dev_visible(current_nx_info(), dev))
23027 return dev;
23028
23029 return NULL;
927ca606 23030@@ -924,9 +939,11 @@ struct net_device *__dev_getfirstbyhwtyp
4bf69007
AM
23031 struct net_device *dev;
23032
23033 ASSERT_RTNL();
23034- for_each_netdev(net, dev)
23035- if (dev->type == type)
23036+ for_each_netdev(net, dev) {
23037+ if ((dev->type == type) &&
23038+ nx_dev_visible(current_nx_info(), dev))
23039 return dev;
23040+ }
23041
23042 return NULL;
23043 }
927ca606 23044@@ -938,7 +955,8 @@ struct net_device *dev_getfirstbyhwtype(
b00e13aa
AM
23045
23046 rcu_read_lock();
23047 for_each_netdev_rcu(net, dev)
23048- if (dev->type == type) {
23049+ if ((dev->type == type) &&
23050+ nx_dev_visible(current_nx_info(), dev)) {
23051 dev_hold(dev);
23052 ret = dev;
23053 break;
927ca606 23054@@ -968,7 +986,8 @@ struct net_device *__dev_get_by_flags(st
b00e13aa
AM
23055
23056 ret = NULL;
bb20add7 23057 for_each_netdev(net, dev) {
b00e13aa
AM
23058- if (((dev->flags ^ if_flags) & mask) == 0) {
23059+ if ((((dev->flags ^ if_flags) & mask) == 0) &&
23060+ nx_dev_visible(current_nx_info(), dev)) {
23061 ret = dev;
23062 break;
23063 }
927ca606 23064@@ -1046,6 +1065,8 @@ static int __dev_alloc_name(struct net *
4bf69007
AM
23065 continue;
23066 if (i < 0 || i >= max_netdevices)
23067 continue;
23068+ if (!nx_dev_visible(current_nx_info(), d))
23069+ continue;
23070
23071 /* avoid cases where sscanf is not exact inverse of printf */
23072 snprintf(buf, IFNAMSIZ, name, i);
8de2f54c 23073diff -NurpP --minimal linux-4.4.111/net/core/net-procfs.c linux-4.4.111-vs2.3.9.5/net/core/net-procfs.c
f19bd705 23074--- linux-4.4.111/net/core/net-procfs.c 2015-04-12 22:12:50.000000000 +0000
8de2f54c 23075+++ linux-4.4.111-vs2.3.9.5/net/core/net-procfs.c 2018-01-09 16:36:34.000000000 +0000
8ce283e1
AM
23076@@ -1,6 +1,7 @@
23077 #include <linux/netdevice.h>
23078 #include <linux/proc_fs.h>
23079 #include <linux/seq_file.h>
23080+#include <linux/vs_inet.h>
23081 #include <net/wext.h>
23082
23083 #define BUCKET_SPACE (32 - NETDEV_HASHBITS - 1)
23084@@ -77,8 +78,13 @@ static void dev_seq_stop(struct seq_file
23085 static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
23086 {
23087 struct rtnl_link_stats64 temp;
23088- const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp);
23089+ const struct rtnl_link_stats64 *stats;
23090+
23091+ /* device visible inside network context? */
23092+ if (!nx_dev_visible(current_nx_info(), dev))
23093+ return;
23094
23095+ stats = dev_get_stats(dev, &temp);
23096 seq_printf(seq, "%6s: %7llu %7llu %4llu %4llu %4llu %5llu %10llu %9llu "
23097 "%8llu %7llu %4llu %4llu %4llu %5llu %7llu %10llu\n",
23098 dev->name, stats->rx_bytes, stats->rx_packets,
8de2f54c 23099diff -NurpP --minimal linux-4.4.111/net/core/rtnetlink.c linux-4.4.111-vs2.3.9.5/net/core/rtnetlink.c
f19bd705 23100--- linux-4.4.111/net/core/rtnetlink.c 2018-01-11 07:57:54.000000000 +0000
8de2f54c 23101+++ linux-4.4.111-vs2.3.9.5/net/core/rtnetlink.c 2018-01-09 16:36:34.000000000 +0000
927ca606
AM
23102@@ -1456,6 +1456,8 @@ static int rtnl_dump_ifinfo(struct sk_bu
23103 hlist_for_each_entry(dev, head, index_hlist) {
4bf69007
AM
23104 if (idx < s_idx)
23105 goto cont;
23106+ if (!nx_dev_visible(skb->sk->sk_nx_info, dev))
23107+ continue;
7ed51edd
JR
23108 err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
23109 NETLINK_CB(cb->skb).portid,
23110 cb->nlh->nlmsg_seq, 0,
927ca606
AM
23111@@ -2559,6 +2561,9 @@ void rtmsg_ifinfo(int type, struct net_d
23112 {
23113 struct sk_buff *skb;
4bf69007
AM
23114
23115+ if (!nx_dev_visible(current_nx_info(), dev))
23116+ return;
2ba6f0dd 23117+
927ca606
AM
23118 if (dev->reg_state != NETREG_REGISTERED)
23119 return;
23120
8de2f54c 23121diff -NurpP --minimal linux-4.4.111/net/core/sock.c linux-4.4.111-vs2.3.9.5/net/core/sock.c
f19bd705 23122--- linux-4.4.111/net/core/sock.c 2018-01-11 07:57:54.000000000 +0000
8de2f54c 23123+++ linux-4.4.111-vs2.3.9.5/net/core/sock.c 2018-01-09 17:15:58.000000000 +0000
927ca606
AM
23124@@ -134,6 +134,10 @@
23125 #include <linux/sock_diag.h>
4bf69007
AM
23126
23127 #include <linux/filter.h>
23128+#include <linux/vs_socket.h>
23129+#include <linux/vs_limit.h>
23130+#include <linux/vs_context.h>
23131+#include <linux/vs_network.h>
23132
23133 #include <trace/events/sock.h>
23134
927ca606 23135@@ -1363,6 +1367,8 @@ static struct sock *sk_prot_alloc(struct
4bf69007
AM
23136 goto out_free_sec;
23137 sk_tx_queue_clear(sk);
23138 }
23139+ sock_vx_init(sk);
23140+ sock_nx_init(sk);
23141
23142 return sk;
23143
927ca606 23144@@ -1469,6 +1475,11 @@ void sk_destruct(struct sock *sk)
4bf69007 23145 put_pid(sk->sk_peer_pid);
927ca606
AM
23146 if (likely(sk->sk_net_refcnt))
23147 put_net(sock_net(sk));
4bf69007
AM
23148+ vx_sock_dec(sk);
23149+ clr_vx_info(&sk->sk_vx_info);
23150+ sk->sk_xid = -1;
23151+ clr_nx_info(&sk->sk_nx_info);
23152+ sk->sk_nid = -1;
23153 sk_prot_free(sk->sk_prot_creator, sk);
23154 }
23155
927ca606 23156@@ -1521,6 +1532,8 @@ struct sock *sk_clone_lock(const struct
4bf69007 23157 /* SANITY */
927ca606
AM
23158 if (likely(newsk->sk_net_refcnt))
23159 get_net(sock_net(newsk));
4bf69007
AM
23160+ sock_vx_init(newsk);
23161+ sock_nx_init(newsk);
23162 sk_node_init(&newsk->sk_node);
23163 sock_lock_init(newsk);
23164 bh_lock_sock(newsk);
927ca606 23165@@ -1586,6 +1599,12 @@ struct sock *sk_clone_lock(const struct
4bf69007
AM
23166 smp_wmb();
23167 atomic_set(&newsk->sk_refcnt, 2);
23168
23169+ set_vx_info(&newsk->sk_vx_info, sk->sk_vx_info);
23170+ newsk->sk_xid = sk->sk_xid;
23171+ vx_sock_inc(newsk);
23172+ set_nx_info(&newsk->sk_nx_info, sk->sk_nx_info);
23173+ newsk->sk_nid = sk->sk_nid;
2ba6f0dd 23174+
4bf69007
AM
23175 /*
23176 * Increment the counter in the same struct proto as the master
23177 * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that
927ca606 23178@@ -2424,6 +2443,12 @@ void sock_init_data(struct socket *sock,
4bf69007
AM
23179
23180 sk->sk_stamp = ktime_set(-1L, 0);
23181
23182+ set_vx_info(&sk->sk_vx_info, current_vx_info());
23183+ sk->sk_xid = vx_current_xid();
23184+ vx_sock_inc(sk);
23185+ set_nx_info(&sk->sk_nx_info, current_nx_info());
23186+ sk->sk_nid = nx_current_nid();
2ba6f0dd 23187+
c2e5f7c8
JR
23188 #ifdef CONFIG_NET_RX_BUSY_POLL
23189 sk->sk_napi_id = 0;
23190 sk->sk_ll_usec = sysctl_net_busy_read;
8de2f54c 23191diff -NurpP --minimal linux-4.4.111/net/ipv4/af_inet.c linux-4.4.111-vs2.3.9.5/net/ipv4/af_inet.c
f19bd705 23192--- linux-4.4.111/net/ipv4/af_inet.c 2018-01-11 07:57:54.000000000 +0000
8de2f54c 23193+++ linux-4.4.111-vs2.3.9.5/net/ipv4/af_inet.c 2018-01-09 17:11:11.000000000 +0000
927ca606 23194@@ -308,10 +308,15 @@ lookup_protocol:
4bf69007
AM
23195 }
23196
23197 err = -EPERM;
23198+ if ((protocol == IPPROTO_ICMP) &&
23199+ nx_capable(CAP_NET_RAW, NXC_RAW_ICMP))
23200+ goto override;
927ca606 23201+
b00e13aa
AM
23202 if (sock->type == SOCK_RAW && !kern &&
23203 !ns_capable(net->user_ns, CAP_NET_RAW))
4bf69007 23204 goto out_rcu_unlock;
927ca606 23205
a4a22af8
AM
23206+override:
23207 sock->ops = answer->ops;
23208 answer_prot = answer->prot;
bb20add7 23209 answer_flags = answer->flags;
927ca606 23210@@ -425,6 +430,7 @@ int inet_bind(struct socket *sock, struc
4bf69007
AM
23211 struct sock *sk = sock->sk;
23212 struct inet_sock *inet = inet_sk(sk);
b00e13aa 23213 struct net *net = sock_net(sk);
927ca606 23214+ struct nx_v4_sock_addr nsa;
4bf69007
AM
23215 unsigned short snum;
23216 int chk_addr_ret;
927ca606
AM
23217 u32 tb_id = RT_TABLE_LOCAL;
23218@@ -450,7 +456,11 @@ int inet_bind(struct socket *sock, struc
4bf69007
AM
23219 }
23220
927ca606
AM
23221 tb_id = l3mdev_fib_table_by_index(net, sk->sk_bound_dev_if) ? : tb_id;
23222- chk_addr_ret = inet_addr_type_table(net, addr->sin_addr.s_addr, tb_id);
4bf69007
AM
23223+ err = v4_map_sock_addr(inet, addr, &nsa);
23224+ if (err)
23225+ goto out;
2ba6f0dd 23226+
927ca606 23227+ chk_addr_ret = inet_addr_type_table(net, nsa.saddr, tb_id);
4bf69007
AM
23228
23229 /* Not specified by any standard per-se, however it breaks too
23230 * many applications when removed. It is unfortunate since
927ca606 23231@@ -462,7 +472,7 @@ int inet_bind(struct socket *sock, struc
4bf69007 23232 err = -EADDRNOTAVAIL;
bb20add7 23233 if (!net->ipv4.sysctl_ip_nonlocal_bind &&
4bf69007
AM
23234 !(inet->freebind || inet->transparent) &&
23235- addr->sin_addr.s_addr != htonl(INADDR_ANY) &&
23236+ nsa.saddr != htonl(INADDR_ANY) &&
23237 chk_addr_ret != RTN_LOCAL &&
23238 chk_addr_ret != RTN_MULTICAST &&
23239 chk_addr_ret != RTN_BROADCAST)
927ca606 23240@@ -488,7 +498,7 @@ int inet_bind(struct socket *sock, struc
4bf69007
AM
23241 if (sk->sk_state != TCP_CLOSE || inet->inet_num)
23242 goto out_release_sock;
23243
23244- inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
23245+ v4_set_sock_addr(inet, &nsa);
23246 if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
23247 inet->inet_saddr = 0; /* Use device */
23248
927ca606 23249@@ -708,11 +718,13 @@ int inet_getname(struct socket *sock, st
4bf69007
AM
23250 peer == 1))
23251 return -ENOTCONN;
23252 sin->sin_port = inet->inet_dport;
23253- sin->sin_addr.s_addr = inet->inet_daddr;
23254+ sin->sin_addr.s_addr =
23255+ nx_map_sock_lback(sk->sk_nx_info, inet->inet_daddr);
23256 } else {
23257 __be32 addr = inet->inet_rcv_saddr;
23258 if (!addr)
23259 addr = inet->inet_saddr;
23260+ addr = nx_map_sock_lback(sk->sk_nx_info, addr);
23261 sin->sin_port = inet->inet_sport;
23262 sin->sin_addr.s_addr = addr;
23263 }
927ca606
AM
23264@@ -896,6 +908,7 @@ static int inet_compat_ioctl(struct sock
23265 return err;
23266 }
23267 #endif
23268+#include <linux/vs_limit.h>
23269
23270 const struct proto_ops inet_stream_ops = {
23271 .family = PF_INET,
8de2f54c 23272diff -NurpP --minimal linux-4.4.111/net/ipv4/arp.c linux-4.4.111-vs2.3.9.5/net/ipv4/arp.c
f19bd705 23273--- linux-4.4.111/net/ipv4/arp.c 2018-01-11 07:57:54.000000000 +0000
8de2f54c 23274+++ linux-4.4.111-vs2.3.9.5/net/ipv4/arp.c 2018-01-09 16:36:34.000000000 +0000
927ca606 23275@@ -1290,6 +1290,7 @@ static void arp_format_neigh_entry(struc
4bf69007
AM
23276 struct net_device *dev = n->dev;
23277 int hatype = dev->type;
23278
23279+ /* FIXME: check for network context */
23280 read_lock(&n->lock);
23281 /* Convert hardware address to XX:XX:XX:XX ... form. */
23282 #if IS_ENABLED(CONFIG_AX25)
927ca606 23283@@ -1321,6 +1322,7 @@ static void arp_format_pneigh_entry(stru
4bf69007
AM
23284 int hatype = dev ? dev->type : 0;
23285 char tbuf[16];
23286
23287+ /* FIXME: check for network context */
23288 sprintf(tbuf, "%pI4", n->key);
23289 seq_printf(seq, "%-16s 0x%-10x0x%-10x%s * %s\n",
23290 tbuf, hatype, ATF_PUBL | ATF_PERM, "00:00:00:00:00:00",
8de2f54c 23291diff -NurpP --minimal linux-4.4.111/net/ipv4/devinet.c linux-4.4.111-vs2.3.9.5/net/ipv4/devinet.c
f19bd705 23292--- linux-4.4.111/net/ipv4/devinet.c 2018-01-11 07:57:54.000000000 +0000
8de2f54c 23293+++ linux-4.4.111-vs2.3.9.5/net/ipv4/devinet.c 2018-01-09 16:36:34.000000000 +0000
927ca606 23294@@ -538,6 +538,7 @@ struct in_device *inetdev_by_index(struc
4bf69007
AM
23295 }
23296 EXPORT_SYMBOL(inetdev_by_index);
23297
2ba6f0dd 23298+
4bf69007
AM
23299 /* Called only from RTNL semaphored context. No locks. */
23300
23301 struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
927ca606 23302@@ -992,6 +993,8 @@ int devinet_ioctl(struct net *net, unsig
4bf69007
AM
23303
23304 in_dev = __in_dev_get_rtnl(dev);
23305 if (in_dev) {
23306+ struct nx_info *nxi = current_nx_info();
2ba6f0dd 23307+
4bf69007
AM
23308 if (tryaddrmatch) {
23309 /* Matthias Andree */
23310 /* compare label and address (4.4BSD style) */
927ca606 23311@@ -1000,6 +1003,8 @@ int devinet_ioctl(struct net *net, unsig
4bf69007
AM
23312 This is checked above. */
23313 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
23314 ifap = &ifa->ifa_next) {
23315+ if (!nx_v4_ifa_visible(nxi, ifa))
23316+ continue;
23317 if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
23318 sin_orig.sin_addr.s_addr ==
23319 ifa->ifa_local) {
927ca606 23320@@ -1012,9 +1017,12 @@ int devinet_ioctl(struct net *net, unsig
4bf69007
AM
23321 comparing just the label */
23322 if (!ifa) {
23323 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
23324- ifap = &ifa->ifa_next)
23325+ ifap = &ifa->ifa_next) {
23326+ if (!nx_v4_ifa_visible(nxi, ifa))
23327+ continue;
23328 if (!strcmp(ifr.ifr_name, ifa->ifa_label))
23329 break;
23330+ }
23331 }
23332 }
23333
927ca606 23334@@ -1168,6 +1176,8 @@ static int inet_gifconf(struct net_devic
4bf69007
AM
23335 goto out;
23336
23337 for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
23338+ if (!nx_v4_ifa_visible(current_nx_info(), ifa))
23339+ continue;
23340 if (!buf) {
23341 done += sizeof(ifr);
23342 continue;
927ca606 23343@@ -1573,6 +1583,7 @@ static int inet_dump_ifaddr(struct sk_bu
4bf69007
AM
23344 struct net_device *dev;
23345 struct in_device *in_dev;
23346 struct in_ifaddr *ifa;
23347+ struct sock *sk = skb->sk;
23348 struct hlist_head *head;
4bf69007 23349
b00e13aa 23350 s_h = cb->args[0];
927ca606 23351@@ -1596,6 +1607,8 @@ static int inet_dump_ifaddr(struct sk_bu
4bf69007
AM
23352
23353 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
23354 ifa = ifa->ifa_next, ip_idx++) {
23355+ if (sk && !nx_v4_ifa_visible(sk->sk_nx_info, ifa))
23356+ continue;
23357 if (ip_idx < s_ip_idx)
23358 continue;
23359 if (inet_fill_ifaddr(skb, ifa,
8de2f54c 23360diff -NurpP --minimal linux-4.4.111/net/ipv4/fib_trie.c linux-4.4.111-vs2.3.9.5/net/ipv4/fib_trie.c
f19bd705 23361--- linux-4.4.111/net/ipv4/fib_trie.c 2018-01-11 07:57:54.000000000 +0000
8de2f54c 23362+++ linux-4.4.111-vs2.3.9.5/net/ipv4/fib_trie.c 2018-01-09 16:36:34.000000000 +0000
927ca606
AM
23363@@ -2591,6 +2591,7 @@ static int fib_route_seq_show(struct seq
23364
23365 seq_setwidth(seq, 127);
23366
23367+ /* FIXME: check for network context? */
23368 if (fi)
23369 seq_printf(seq,
23370 "%s\t%08X\t%08X\t%04X\t%d\t%u\t"
8de2f54c 23371diff -NurpP --minimal linux-4.4.111/net/ipv4/inet_connection_sock.c linux-4.4.111-vs2.3.9.5/net/ipv4/inet_connection_sock.c
f19bd705 23372--- linux-4.4.111/net/ipv4/inet_connection_sock.c 2018-01-11 07:57:54.000000000 +0000
8de2f54c 23373+++ linux-4.4.111-vs2.3.9.5/net/ipv4/inet_connection_sock.c 2018-01-09 16:36:34.000000000 +0000
927ca606 23374@@ -43,6 +43,37 @@ void inet_get_local_port_range(struct ne
4bf69007
AM
23375 }
23376 EXPORT_SYMBOL(inet_get_local_port_range);
23377
23378+int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
23379+{
c2e5f7c8
JR
23380+ __be32 sk1_rcv_saddr = sk1->sk_rcv_saddr,
23381+ sk2_rcv_saddr = sk2->sk_rcv_saddr;
2ba6f0dd 23382+
4bf69007
AM
23383+ if (inet_v6_ipv6only(sk2))
23384+ return 0;
2ba6f0dd 23385+
4bf69007
AM
23386+ if (sk1_rcv_saddr &&
23387+ sk2_rcv_saddr &&
23388+ sk1_rcv_saddr == sk2_rcv_saddr)
23389+ return 1;
2ba6f0dd 23390+
4bf69007
AM
23391+ if (sk1_rcv_saddr &&
23392+ !sk2_rcv_saddr &&
23393+ v4_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr, NXA_MASK_BIND))
23394+ return 1;
2ba6f0dd 23395+
4bf69007
AM
23396+ if (sk2_rcv_saddr &&
23397+ !sk1_rcv_saddr &&
23398+ v4_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr, NXA_MASK_BIND))
23399+ return 1;
2ba6f0dd 23400+
4bf69007
AM
23401+ if (!sk1_rcv_saddr &&
23402+ !sk2_rcv_saddr &&
23403+ nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info))
23404+ return 1;
2ba6f0dd 23405+
4bf69007
AM
23406+ return 0;
23407+}
2ba6f0dd 23408+
4bf69007
AM
23409 int inet_csk_bind_conflict(const struct sock *sk,
23410 const struct inet_bind_bucket *tb, bool relax)
23411 {
927ca606 23412@@ -70,15 +101,13 @@ int inet_csk_bind_conflict(const struct
b00e13aa
AM
23413 (sk2->sk_state != TCP_TIME_WAIT &&
23414 !uid_eq(uid, sock_i_uid(sk2))))) {
c2e5f7c8
JR
23415
23416- if (!sk2->sk_rcv_saddr || !sk->sk_rcv_saddr ||
23417- sk2->sk_rcv_saddr == sk->sk_rcv_saddr)
4bf69007
AM
23418+ if (ipv4_rcv_saddr_equal(sk, sk2))
23419 break;
23420 }
23421 if (!relax && reuse && sk2->sk_reuse &&
b00e13aa 23422 sk2->sk_state != TCP_LISTEN) {
c2e5f7c8
JR
23423
23424- if (!sk2->sk_rcv_saddr || !sk->sk_rcv_saddr ||
23425- sk2->sk_rcv_saddr == sk->sk_rcv_saddr)
b00e13aa
AM
23426+ if (ipv4_rcv_saddr_equal(sk, sk2))
23427 break;
23428 }
23429 }
8de2f54c 23430diff -NurpP --minimal linux-4.4.111/net/ipv4/inet_diag.c linux-4.4.111-vs2.3.9.5/net/ipv4/inet_diag.c
f19bd705 23431--- linux-4.4.111/net/ipv4/inet_diag.c 2016-07-05 04:15:14.000000000 +0000
8de2f54c 23432+++ linux-4.4.111-vs2.3.9.5/net/ipv4/inet_diag.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
23433@@ -31,6 +31,8 @@
23434
23435 #include <linux/inet.h>
23436 #include <linux/stddef.h>
23437+#include <linux/vs_network.h>
23438+#include <linux/vs_inet.h>
23439
23440 #include <linux/inet_diag.h>
23441 #include <linux/sock_diag.h>
927ca606 23442@@ -761,6 +763,8 @@ void inet_diag_dump_icsk(struct inet_has
4bf69007
AM
23443 if (!net_eq(sock_net(sk), net))
23444 continue;
23445
23446+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23447+ continue;
23448 if (num < s_num) {
23449 num++;
23450 continue;
927ca606 23451@@ -822,6 +826,8 @@ skip_listen_ht:
4bf69007
AM
23452
23453 if (!net_eq(sock_net(sk), net))
23454 continue;
23455+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23456+ continue;
23457 if (num < s_num)
23458 goto next_normal;
c2e5f7c8 23459 state = (sk->sk_state == TCP_TIME_WAIT) ?
8de2f54c 23460diff -NurpP --minimal linux-4.4.111/net/ipv4/inet_hashtables.c linux-4.4.111-vs2.3.9.5/net/ipv4/inet_hashtables.c
f19bd705 23461--- linux-4.4.111/net/ipv4/inet_hashtables.c 2016-07-05 04:15:14.000000000 +0000
8de2f54c 23462+++ linux-4.4.111-vs2.3.9.5/net/ipv4/inet_hashtables.c 2018-01-09 16:36:34.000000000 +0000
927ca606 23463@@ -23,6 +23,7 @@
4bf69007
AM
23464 #include <net/inet_connection_sock.h>
23465 #include <net/inet_hashtables.h>
23466 #include <net/secure_seq.h>
23467+#include <net/route.h>
23468 #include <net/ip.h>
23469
927ca606
AM
23470 static u32 inet_ehashfn(const struct net *net, const __be32 laddr,
23471@@ -183,6 +184,11 @@ static inline int compute_score(struct s
4bf69007
AM
23472 if (rcv_saddr != daddr)
23473 return -1;
b00e13aa 23474 score += 4;
4bf69007
AM
23475+ } else {
23476+ /* block non nx_info ips */
23477+ if (!v4_addr_in_nx_info(sk->sk_nx_info,
23478+ daddr, NXA_MASK_BIND))
23479+ return -1;
23480 }
23481 if (sk->sk_bound_dev_if) {
23482 if (sk->sk_bound_dev_if != dif)
927ca606 23483@@ -202,7 +208,6 @@ static inline int compute_score(struct s
4bf69007
AM
23484 * wildcarded during the search since they can never be otherwise.
23485 */
23486
23487-
23488 struct sock *__inet_lookup_listener(struct net *net,
23489 struct inet_hashinfo *hashinfo,
b00e13aa 23490 const __be32 saddr, __be16 sport,
927ca606 23491@@ -238,6 +243,7 @@ begin:
b00e13aa 23492 phash = next_pseudo_random32(phash);
4bf69007
AM
23493 }
23494 }
2ba6f0dd 23495+
4bf69007
AM
23496 /*
23497 * if the nulls value we got at the end of this lookup is
23498 * not the expected one, we must restart lookup.
8de2f54c 23499diff -NurpP --minimal linux-4.4.111/net/ipv4/netfilter.c linux-4.4.111-vs2.3.9.5/net/ipv4/netfilter.c
f19bd705 23500--- linux-4.4.111/net/ipv4/netfilter.c 2016-07-05 04:15:14.000000000 +0000
8de2f54c 23501+++ linux-4.4.111-vs2.3.9.5/net/ipv4/netfilter.c 2018-01-09 16:36:34.000000000 +0000
09be7631 23502@@ -11,7 +11,7 @@
4bf69007
AM
23503 #include <linux/skbuff.h>
23504 #include <linux/gfp.h>
23505 #include <linux/export.h>
23506-#include <net/route.h>
23507+// #include <net/route.h>
23508 #include <net/xfrm.h>
23509 #include <net/ip.h>
23510 #include <net/netfilter/nf_queue.h>
8de2f54c 23511diff -NurpP --minimal linux-4.4.111/net/ipv4/raw.c linux-4.4.111-vs2.3.9.5/net/ipv4/raw.c
f19bd705 23512--- linux-4.4.111/net/ipv4/raw.c 2018-01-11 07:57:55.000000000 +0000
8de2f54c 23513+++ linux-4.4.111-vs2.3.9.5/net/ipv4/raw.c 2018-01-09 17:06:10.000000000 +0000
927ca606 23514@@ -126,7 +126,7 @@ static struct sock *__raw_v4_lookup(stru
4bf69007
AM
23515
23516 if (net_eq(sock_net(sk), net) && inet->inet_num == num &&
23517 !(inet->inet_daddr && inet->inet_daddr != raddr) &&
23518- !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
23519+ v4_sock_addr_match(sk->sk_nx_info, inet, laddr) &&
23520 !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
23521 goto found; /* gotcha */
23522 }
927ca606
AM
23523@@ -416,6 +416,12 @@ static int raw_send_hdrinc(struct sock *
23524 skb_transport_header(skb))->type);
23525 }
4bf69007
AM
23526
23527+ err = -EPERM;
23528+ if (!nx_check(0, VS_ADMIN) && !capable(CAP_NET_RAW) &&
23529+ sk->sk_nx_info &&
23530+ !v4_addr_in_nx_info(sk->sk_nx_info, iph->saddr, NXA_MASK_BIND))
23531+ goto error_free;
2ba6f0dd 23532+
927ca606
AM
23533 err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT,
23534 net, sk, skb, NULL, rt->dst.dev,
23535 dst_output);
23536@@ -626,6 +632,16 @@ static int raw_sendmsg(struct sock *sk,
4bf69007
AM
23537 goto done;
23538 }
23539
23540+ if (sk->sk_nx_info) {
23541+ rt = ip_v4_find_src(sock_net(sk), sk->sk_nx_info, &fl4);
23542+ if (IS_ERR(rt)) {
23543+ err = PTR_ERR(rt);
23544+ rt = NULL;
23545+ goto done;
23546+ }
23547+ ip_rt_put(rt);
23548+ }
2ba6f0dd 23549+
4bf69007 23550 security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
927ca606 23551 rt = ip_route_output_flow(net, &fl4, sk);
4bf69007 23552 if (IS_ERR(rt)) {
927ca606 23553@@ -704,17 +720,19 @@ static int raw_bind(struct sock *sk, str
4bf69007
AM
23554 {
23555 struct inet_sock *inet = inet_sk(sk);
23556 struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
23557+ struct nx_v4_sock_addr nsa = { 0 };
23558 int ret = -EINVAL;
23559 int chk_addr_ret;
23560
23561 if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
23562 goto out;
23563- chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr);
23564+ v4_map_sock_addr(inet, addr, &nsa);
23565+ chk_addr_ret = inet_addr_type(sock_net(sk), nsa.saddr);
23566 ret = -EADDRNOTAVAIL;
23567- if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
23568+ if (nsa.saddr && chk_addr_ret != RTN_LOCAL &&
23569 chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
23570 goto out;
23571- inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
23572+ v4_set_sock_addr(inet, &nsa);
23573 if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
23574 inet->inet_saddr = 0; /* Use device */
23575 sk_dst_reset(sk);
927ca606 23576@@ -763,7 +781,8 @@ static int raw_recvmsg(struct sock *sk,
4bf69007
AM
23577 /* Copy the address. */
23578 if (sin) {
23579 sin->sin_family = AF_INET;
23580- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
23581+ sin->sin_addr.s_addr =
23582+ nx_map_sock_lback(sk->sk_nx_info, ip_hdr(skb)->saddr);
23583 sin->sin_port = 0;
23584 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
c2e5f7c8 23585 *addr_len = sizeof(*sin);
927ca606 23586@@ -959,7 +978,8 @@ static struct sock *raw_get_first(struct
b00e13aa
AM
23587 for (state->bucket = 0; state->bucket < RAW_HTABLE_SIZE;
23588 ++state->bucket) {
23589 sk_for_each(sk, &state->h->ht[state->bucket])
4bf69007
AM
23590- if (sock_net(sk) == seq_file_net(seq))
23591+ if ((sock_net(sk) == seq_file_net(seq)) &&
b00e13aa 23592+ nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
4bf69007
AM
23593 goto found;
23594 }
23595 sk = NULL;
927ca606 23596@@ -975,7 +995,8 @@ static struct sock *raw_get_next(struct
4bf69007
AM
23597 sk = sk_next(sk);
23598 try_again:
23599 ;
23600- } while (sk && sock_net(sk) != seq_file_net(seq));
23601+ } while (sk && ((sock_net(sk) != seq_file_net(seq)) ||
23602+ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
23603
23604 if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
23605 sk = sk_head(&state->h->ht[state->bucket]);
8de2f54c 23606diff -NurpP --minimal linux-4.4.111/net/ipv4/route.c linux-4.4.111-vs2.3.9.5/net/ipv4/route.c
f19bd705 23607--- linux-4.4.111/net/ipv4/route.c 2018-01-11 07:57:55.000000000 +0000
8de2f54c 23608+++ linux-4.4.111-vs2.3.9.5/net/ipv4/route.c 2018-01-09 16:36:34.000000000 +0000
927ca606 23609@@ -2226,7 +2226,7 @@ struct rtable *__ip_route_output_key_has
4bf69007
AM
23610
23611
23612 if (fl4->flowi4_oif) {
23613- dev_out = dev_get_by_index_rcu(net, fl4->flowi4_oif);
23614+ dev_out = dev_get_by_index_real_rcu(net, fl4->flowi4_oif);
23615 rth = ERR_PTR(-ENODEV);
927ca606 23616 if (!dev_out)
4bf69007 23617 goto out;
8de2f54c 23618diff -NurpP --minimal linux-4.4.111/net/ipv4/tcp.c linux-4.4.111-vs2.3.9.5/net/ipv4/tcp.c
f19bd705 23619--- linux-4.4.111/net/ipv4/tcp.c 2018-01-11 07:57:55.000000000 +0000
8de2f54c 23620+++ linux-4.4.111-vs2.3.9.5/net/ipv4/tcp.c 2018-01-09 16:36:34.000000000 +0000
927ca606 23621@@ -269,6 +269,7 @@
4bf69007
AM
23622 #include <linux/crypto.h>
23623 #include <linux/time.h>
23624 #include <linux/slab.h>
23625+#include <linux/in.h>
23626
23627 #include <net/icmp.h>
23628 #include <net/inet_common.h>
8de2f54c 23629diff -NurpP --minimal linux-4.4.111/net/ipv4/tcp_ipv4.c linux-4.4.111-vs2.3.9.5/net/ipv4/tcp_ipv4.c
f19bd705 23630--- linux-4.4.111/net/ipv4/tcp_ipv4.c 2018-01-11 07:57:55.000000000 +0000
8de2f54c 23631+++ linux-4.4.111-vs2.3.9.5/net/ipv4/tcp_ipv4.c 2018-01-09 17:13:45.000000000 +0000
927ca606
AM
23632@@ -1885,6 +1885,10 @@ static void *listening_get_next(struct s
23633 sk = sk_nulls_next(sk);
4bf69007
AM
23634 get_sk:
23635 sk_nulls_for_each_from(sk, node) {
23636+ vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)",
23637+ sk, sk->sk_nid, nx_current_nid());
23638+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23639+ continue;
23640 if (!net_eq(sock_net(sk), net))
23641 continue;
23642 if (sk->sk_family == st->family) {
927ca606 23643@@ -1949,6 +1953,11 @@ static void *established_get_first(struc
4bf69007
AM
23644
23645 spin_lock_bh(lock);
23646 sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
23647+ vxdprintk(VXD_CBIT(net, 6),
23648+ "sk,egf: %p [#%d] (from %d)",
23649+ sk, sk->sk_nid, nx_current_nid());
23650+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23651+ continue;
23652 if (sk->sk_family != st->family ||
23653 !net_eq(sock_net(sk), net)) {
23654 continue;
927ca606 23655@@ -1975,6 +1984,11 @@ static void *established_get_next(struct
c2e5f7c8 23656 sk = sk_nulls_next(sk);
4bf69007
AM
23657
23658 sk_nulls_for_each_from(sk, node) {
23659+ vxdprintk(VXD_CBIT(net, 6),
23660+ "sk,egn: %p [#%d] (from %d)",
23661+ sk, sk->sk_nid, nx_current_nid());
23662+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23663+ continue;
23664 if (sk->sk_family == st->family && net_eq(sock_net(sk), net))
c2e5f7c8 23665 return sk;
4bf69007 23666 }
927ca606 23667@@ -2166,9 +2180,9 @@ static void get_openreq4(const struct re
4bf69007 23668 seq_printf(f, "%4d: %08X:%04X %08X:%04X"
c2e5f7c8 23669 " %02X %08X:%08X %02X:%08lX %08X %5u %8d %u %d %pK",
4bf69007 23670 i,
c2e5f7c8
JR
23671- ireq->ir_loc_addr,
23672+ nx_map_sock_lback(current_nx_info(), ireq->ir_loc_addr),
927ca606 23673 ireq->ir_num,
c2e5f7c8
JR
23674- ireq->ir_rmt_addr,
23675+ nx_map_sock_lback(current_nx_info(), ireq->ir_rmt_addr),
23676 ntohs(ireq->ir_rmt_port),
4bf69007
AM
23677 TCP_SYN_RECV,
23678 0, 0, /* could print option size, but that is af dependent. */
927ca606 23679@@ -2191,8 +2205,8 @@ static void get_tcp4_sock(struct sock *s
4bf69007
AM
23680 const struct inet_connection_sock *icsk = inet_csk(sk);
23681 const struct inet_sock *inet = inet_sk(sk);
927ca606 23682 const struct fastopen_queue *fastopenq = &icsk->icsk_accept_queue.fastopenq;
4bf69007
AM
23683- __be32 dest = inet->inet_daddr;
23684- __be32 src = inet->inet_rcv_saddr;
23685+ __be32 dest = nx_map_sock_lback(current_nx_info(), inet->inet_daddr);
23686+ __be32 src = nx_map_sock_lback(current_nx_info(), inet->inet_rcv_saddr);
23687 __u16 destp = ntohs(inet->inet_dport);
23688 __u16 srcp = ntohs(inet->inet_sport);
23689 int rx_queue;
927ca606
AM
23690@@ -2251,8 +2265,8 @@ static void get_timewait4_sock(const str
23691 __be32 dest, src;
4bf69007 23692 __u16 destp, srcp;
4bf69007
AM
23693
23694- dest = tw->tw_daddr;
23695- src = tw->tw_rcv_saddr;
23696+ dest = nx_map_sock_lback(current_nx_info(), tw->tw_daddr);
23697+ src = nx_map_sock_lback(current_nx_info(), tw->tw_rcv_saddr);
23698 destp = ntohs(tw->tw_dport);
23699 srcp = ntohs(tw->tw_sport);
23700
8de2f54c 23701diff -NurpP --minimal linux-4.4.111/net/ipv4/tcp_minisocks.c linux-4.4.111-vs2.3.9.5/net/ipv4/tcp_minisocks.c
f19bd705 23702--- linux-4.4.111/net/ipv4/tcp_minisocks.c 2018-01-11 07:57:55.000000000 +0000
8de2f54c 23703+++ linux-4.4.111-vs2.3.9.5/net/ipv4/tcp_minisocks.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
23704@@ -23,6 +23,9 @@
23705 #include <linux/slab.h>
23706 #include <linux/sysctl.h>
23707 #include <linux/workqueue.h>
23708+#include <linux/vs_limit.h>
23709+#include <linux/vs_socket.h>
23710+#include <linux/vs_context.h>
23711 #include <net/tcp.h>
23712 #include <net/inet_common.h>
23713 #include <net/xfrm.h>
927ca606 23714@@ -291,6 +294,11 @@ void tcp_time_wait(struct sock *sk, int
b00e13aa 23715 tcptw->tw_ts_offset = tp->tsoffset;
927ca606 23716 tcptw->tw_last_oow_ack_time = 0;
4bf69007
AM
23717
23718+ tw->tw_xid = sk->sk_xid;
23719+ tw->tw_vx_info = NULL;
23720+ tw->tw_nid = sk->sk_nid;
23721+ tw->tw_nx_info = NULL;
2ba6f0dd 23722+
4bf69007
AM
23723 #if IS_ENABLED(CONFIG_IPV6)
23724 if (tw->tw_family == PF_INET6) {
23725 struct ipv6_pinfo *np = inet6_sk(sk);
8de2f54c 23726diff -NurpP --minimal linux-4.4.111/net/ipv4/udp.c linux-4.4.111-vs2.3.9.5/net/ipv4/udp.c
f19bd705 23727--- linux-4.4.111/net/ipv4/udp.c 2018-01-11 07:57:55.000000000 +0000
8de2f54c 23728+++ linux-4.4.111-vs2.3.9.5/net/ipv4/udp.c 2018-01-09 16:36:34.000000000 +0000
bb20add7 23729@@ -309,14 +309,7 @@ fail:
4bf69007
AM
23730 }
23731 EXPORT_SYMBOL(udp_lib_get_port);
23732
23733-static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
23734-{
23735- struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
23736-
23737- return (!ipv6_only_sock(sk2) &&
23738- (!inet1->inet_rcv_saddr || !inet2->inet_rcv_saddr ||
23739- inet1->inet_rcv_saddr == inet2->inet_rcv_saddr));
23740-}
23741+extern int ipv4_rcv_saddr_equal(const struct sock *, const struct sock *);
23742
927ca606
AM
23743 static u32 udp4_portaddr_hash(const struct net *net, __be32 saddr,
23744 unsigned int port)
23745@@ -355,6 +348,11 @@ static inline int compute_score(struct s
23746 if (inet->inet_rcv_saddr != daddr)
23747 return -1;
23748 score += 4;
4bf69007
AM
23749+ } else {
23750+ /* block non nx_info ips */
23751+ if (!v4_addr_in_nx_info(sk->sk_nx_info,
23752+ daddr, NXA_MASK_BIND))
23753+ return -1;
927ca606
AM
23754 }
23755
23756 if (inet->inet_daddr) {
23757@@ -489,6 +487,7 @@ begin:
4bf69007
AM
23758 return result;
23759 }
23760
2ba6f0dd 23761+
4bf69007
AM
23762 /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
23763 * harder than this. -DaveM
23764 */
927ca606 23765@@ -535,6 +534,11 @@ begin:
4bf69007
AM
23766 sk_nulls_for_each_rcu(sk, node, &hslot->head) {
23767 score = compute_score(sk, net, saddr, hnum, sport,
23768 daddr, dport, dif);
23769+ /* FIXME: disabled?
23770+ if (score == 9) {
23771+ result = sk;
23772+ break;
23773+ } else */
23774 if (score > badness) {
23775 result = sk;
23776 badness = score;
927ca606 23777@@ -559,6 +563,7 @@ begin:
4bf69007
AM
23778 if (get_nulls_value(node) != slot)
23779 goto begin;
23780
2ba6f0dd 23781+
4bf69007
AM
23782 if (result) {
23783 if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
23784 result = NULL;
927ca606 23785@@ -568,6 +573,7 @@ begin:
4bf69007
AM
23786 goto begin;
23787 }
23788 }
2ba6f0dd 23789+
4bf69007
AM
23790 rcu_read_unlock();
23791 return result;
23792 }
927ca606 23793@@ -602,7 +608,7 @@ static inline bool __udp_is_mcast_sock(s
c2e5f7c8
JR
23794 udp_sk(sk)->udp_port_hash != hnum ||
23795 (inet->inet_daddr && inet->inet_daddr != rmt_addr) ||
23796 (inet->inet_dport != rmt_port && inet->inet_dport) ||
23797- (inet->inet_rcv_saddr && inet->inet_rcv_saddr != loc_addr) ||
23798+ !v4_sock_addr_match(sk->sk_nx_info, inet, loc_addr) ||
23799 ipv6_only_sock(sk) ||
23800 (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
23801 return false;
927ca606
AM
23802@@ -1033,6 +1039,16 @@ int udp_sendmsg(struct sock *sk, struct
23803 goto out;
23804 }
4bf69007
AM
23805
23806+ if (sk->sk_nx_info) {
23807+ rt = ip_v4_find_src(net, sk->sk_nx_info, fl4);
23808+ if (IS_ERR(rt)) {
23809+ err = PTR_ERR(rt);
23810+ rt = NULL;
23811+ goto out;
23812+ }
23813+ ip_rt_put(rt);
23814+ }
2ba6f0dd 23815+
4bf69007
AM
23816 security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
23817 rt = ip_route_output_flow(net, fl4, sk);
23818 if (IS_ERR(rt)) {
927ca606 23819@@ -1337,7 +1353,8 @@ try_again:
4bf69007
AM
23820 if (sin) {
23821 sin->sin_family = AF_INET;
23822 sin->sin_port = udp_hdr(skb)->source;
23823- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
23824+ sin->sin_addr.s_addr = nx_map_sock_lback(
23825+ skb->sk->sk_nx_info, ip_hdr(skb)->saddr);
23826 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
c2e5f7c8 23827 *addr_len = sizeof(*sin);
4bf69007 23828 }
927ca606 23829@@ -2319,6 +2336,8 @@ static struct sock *udp_get_first(struct
4bf69007
AM
23830 sk_nulls_for_each(sk, node, &hslot->head) {
23831 if (!net_eq(sock_net(sk), net))
23832 continue;
23833+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23834+ continue;
23835 if (sk->sk_family == state->family)
23836 goto found;
23837 }
927ca606 23838@@ -2336,7 +2355,9 @@ static struct sock *udp_get_next(struct
4bf69007
AM
23839
23840 do {
23841 sk = sk_nulls_next(sk);
23842- } while (sk && (!net_eq(sock_net(sk), net) || sk->sk_family != state->family));
23843+ } while (sk && (!net_eq(sock_net(sk), net) ||
23844+ sk->sk_family != state->family ||
23845+ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
23846
23847 if (!sk) {
23848 if (state->bucket <= state->udp_table->mask)
927ca606 23849@@ -2432,8 +2453,8 @@ static void udp4_format_sock(struct sock
c2e5f7c8 23850 int bucket)
4bf69007
AM
23851 {
23852 struct inet_sock *inet = inet_sk(sp);
23853- __be32 dest = inet->inet_daddr;
23854- __be32 src = inet->inet_rcv_saddr;
23855+ __be32 dest = nx_map_sock_lback(current_nx_info(), inet->inet_daddr);
23856+ __be32 src = nx_map_sock_lback(current_nx_info(), inet->inet_rcv_saddr);
23857 __u16 destp = ntohs(inet->inet_dport);
23858 __u16 srcp = ntohs(inet->inet_sport);
23859
8de2f54c 23860diff -NurpP --minimal linux-4.4.111/net/ipv6/addrconf.c linux-4.4.111-vs2.3.9.5/net/ipv6/addrconf.c
f19bd705 23861--- linux-4.4.111/net/ipv6/addrconf.c 2018-01-11 07:57:55.000000000 +0000
8de2f54c 23862+++ linux-4.4.111-vs2.3.9.5/net/ipv6/addrconf.c 2018-01-09 23:41:55.000000000 +0000
927ca606 23863@@ -92,6 +92,8 @@
4bf69007
AM
23864 #include <linux/proc_fs.h>
23865 #include <linux/seq_file.h>
23866 #include <linux/export.h>
23867+#include <linux/vs_network.h>
23868+#include <linux/vs_inet6.h>
23869
23870 /* Set to 3 to get tracing... */
23871 #define ACONF_DEBUG 2
927ca606
AM
23872@@ -1442,7 +1444,8 @@ static int __ipv6_dev_get_saddr(struct n
23873 struct ipv6_saddr_dst *dst,
23874 struct inet6_dev *idev,
23875 struct ipv6_saddr_score *scores,
23876- int hiscore_idx)
23877+ int hiscore_idx,
23878+ struct nx_info *nxi)
23879 {
23880 struct ipv6_saddr_score *score = &scores[1 - hiscore_idx], *hiscore = &scores[hiscore_idx];
23881
23882@@ -1472,6 +1475,8 @@ static int __ipv6_dev_get_saddr(struct n
23883 idev->dev->name);
23884 continue;
23885 }
23886+ if (!v6_addr_in_nx_info(nxi, &score->ifa->addr, -1))
23887+ continue;
23888
23889 score->rule = -1;
23890 bitmap_zero(score->scorebits, IPV6_SADDR_RULE_MAX);
23891@@ -1519,7 +1524,7 @@ out:
4bf69007
AM
23892
23893 int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
23894 const struct in6_addr *daddr, unsigned int prefs,
23895- struct in6_addr *saddr)
23896+ struct in6_addr *saddr, struct nx_info *nxi)
23897 {
927ca606
AM
23898 struct ipv6_saddr_score scores[2], *hiscore;
23899 struct ipv6_saddr_dst dst;
23900@@ -1568,13 +1573,15 @@ int ipv6_dev_get_saddr(struct net *net,
23901
23902 if (use_oif_addr) {
23903 if (idev)
23904- hiscore_idx = __ipv6_dev_get_saddr(net, &dst, idev, scores, hiscore_idx);
23905+ hiscore_idx = __ipv6_dev_get_saddr(net, &dst,
23906+ idev, scores, hiscore_idx, nxi);
23907 } else {
23908 for_each_netdev_rcu(net, dev) {
23909 idev = __in6_dev_get(dev);
23910 if (!idev)
4bf69007 23911 continue;
927ca606
AM
23912- hiscore_idx = __ipv6_dev_get_saddr(net, &dst, idev, scores, hiscore_idx);
23913+ hiscore_idx = __ipv6_dev_get_saddr(net, &dst,
23914+ idev, scores, hiscore_idx, nxi);
23915 }
23916 }
23917 rcu_read_unlock();
23918@@ -3846,7 +3853,10 @@ static void if6_seq_stop(struct seq_file
4bf69007
AM
23919 static int if6_seq_show(struct seq_file *seq, void *v)
23920 {
23921 struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
23922- seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
2ba6f0dd 23923+
4bf69007
AM
23924+ if (nx_check(0, VS_ADMIN|VS_WATCH) ||
23925+ v6_addr_in_nx_info(current_nx_info(), &ifp->addr, -1))
23926+ seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
23927 &ifp->addr,
23928 ifp->idev->dev->ifindex,
23929 ifp->prefix_len,
927ca606 23930@@ -4430,6 +4440,11 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
23931 struct ifacaddr6 *ifaca;
23932 int err = 1;
23933 int ip_idx = *p_ip_idx;
23934+ struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
2ba6f0dd 23935+
4bf69007
AM
23936+ /* disable ipv6 on non v6 guests */
23937+ if (nxi && !nx_info_has_v6(nxi))
23938+ return skb->len;
23939
23940 read_lock_bh(&idev->lock);
23941 switch (type) {
927ca606 23942@@ -4440,6 +4455,8 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
23943 list_for_each_entry(ifa, &idev->addr_list, if_list) {
23944 if (++ip_idx < s_ip_idx)
23945 continue;
927ca606
AM
23946+ if (!v6_addr_in_nx_info(nxi, &ifa->addr, -1))
23947+ continue;
4bf69007
AM
23948 err = inet6_fill_ifaddr(skb, ifa,
23949 NETLINK_CB(cb->skb).portid,
23950 cb->nlh->nlmsg_seq,
927ca606 23951@@ -4457,6 +4474,8 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
23952 ifmca = ifmca->next, ip_idx++) {
23953 if (ip_idx < s_ip_idx)
23954 continue;
927ca606
AM
23955+ if (!v6_addr_in_nx_info(nxi, &ifmca->mca_addr, -1))
23956+ continue;
4bf69007
AM
23957 err = inet6_fill_ifmcaddr(skb, ifmca,
23958 NETLINK_CB(cb->skb).portid,
23959 cb->nlh->nlmsg_seq,
927ca606 23960@@ -4472,6 +4491,8 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
23961 ifaca = ifaca->aca_next, ip_idx++) {
23962 if (ip_idx < s_ip_idx)
23963 continue;
927ca606
AM
23964+ if (!v6_addr_in_nx_info(nxi, &ifaca->aca_addr, -1))
23965+ continue;
4bf69007
AM
23966 err = inet6_fill_ifacaddr(skb, ifaca,
23967 NETLINK_CB(cb->skb).portid,
23968 cb->nlh->nlmsg_seq,
927ca606 23969@@ -4500,6 +4521,10 @@ static int inet6_dump_addr(struct sk_buf
4bf69007
AM
23970 struct inet6_dev *idev;
23971 struct hlist_head *head;
b00e13aa 23972
4bf69007
AM
23973+ /* FIXME: maybe disable ipv6 on non v6 guests?
23974+ if (skb->sk && skb->sk->sk_vx_info)
23975+ return skb->len; */
b00e13aa
AM
23976+
23977 s_h = cb->args[0];
23978 s_idx = idx = cb->args[1];
23979 s_ip_idx = ip_idx = cb->args[2];
927ca606 23980@@ -5008,6 +5033,7 @@ static int inet6_dump_ifinfo(struct sk_b
b00e13aa
AM
23981 struct net_device *dev;
23982 struct inet6_dev *idev;
23983 struct hlist_head *head;
23984+ struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
4bf69007
AM
23985
23986 s_h = cb->args[0];
23987 s_idx = cb->args[1];
927ca606 23988@@ -5019,6 +5045,8 @@ static int inet6_dump_ifinfo(struct sk_b
b00e13aa 23989 hlist_for_each_entry_rcu(dev, head, index_hlist) {
4bf69007
AM
23990 if (idx < s_idx)
23991 goto cont;
23992+ if (!v6_dev_in_nx_info(dev, nxi))
23993+ goto cont;
23994 idev = __in6_dev_get(dev);
23995 if (!idev)
23996 goto cont;
8de2f54c 23997diff -NurpP --minimal linux-4.4.111/net/ipv6/af_inet6.c linux-4.4.111-vs2.3.9.5/net/ipv6/af_inet6.c
f19bd705 23998--- linux-4.4.111/net/ipv6/af_inet6.c 2018-01-11 07:57:55.000000000 +0000
8de2f54c 23999+++ linux-4.4.111-vs2.3.9.5/net/ipv6/af_inet6.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
24000@@ -43,6 +43,8 @@
24001 #include <linux/netdevice.h>
24002 #include <linux/icmpv6.h>
24003 #include <linux/netfilter_ipv6.h>
24004+#include <linux/vs_inet.h>
24005+#include <linux/vs_inet6.h>
24006
24007 #include <net/ip.h>
24008 #include <net/ipv6.h>
927ca606 24009@@ -158,10 +160,13 @@ lookup_protocol:
4bf69007
AM
24010 }
24011
24012 err = -EPERM;
24013+ if ((protocol == IPPROTO_ICMPV6) &&
24014+ nx_capable(CAP_NET_RAW, NXC_RAW_ICMP))
24015+ goto override;
b00e13aa
AM
24016 if (sock->type == SOCK_RAW && !kern &&
24017 !ns_capable(net->user_ns, CAP_NET_RAW))
4bf69007
AM
24018 goto out_rcu_unlock;
24019-
24020+override:
24021 sock->ops = answer->ops;
24022 answer_prot = answer->prot;
bb20add7 24023 answer_flags = answer->flags;
927ca606 24024@@ -259,6 +264,7 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24025 struct inet_sock *inet = inet_sk(sk);
24026 struct ipv6_pinfo *np = inet6_sk(sk);
24027 struct net *net = sock_net(sk);
24028+ struct nx_v6_sock_addr nsa;
24029 __be32 v4addr = 0;
24030 unsigned short snum;
24031 int addr_type = 0;
927ca606 24032@@ -274,6 +280,10 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24033 if (addr->sin6_family != AF_INET6)
24034 return -EAFNOSUPPORT;
24035
24036+ err = v6_map_sock_addr(inet, addr, &nsa);
24037+ if (err)
24038+ return err;
2ba6f0dd 24039+
4bf69007
AM
24040 addr_type = ipv6_addr_type(&addr->sin6_addr);
24041 if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM)
24042 return -EINVAL;
927ca606 24043@@ -314,6 +324,10 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24044 err = -EADDRNOTAVAIL;
24045 goto out;
24046 }
24047+ if (!v4_addr_in_nx_info(sk->sk_nx_info, v4addr, NXA_MASK_BIND)) {
24048+ err = -EADDRNOTAVAIL;
24049+ goto out;
24050+ }
24051 } else {
24052 if (addr_type != IPV6_ADDR_ANY) {
24053 struct net_device *dev = NULL;
927ca606 24054@@ -340,6 +354,11 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24055 }
24056 }
24057
24058+ if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) {
24059+ err = -EADDRNOTAVAIL;
24060+ goto out_unlock;
24061+ }
2ba6f0dd 24062+
4bf69007
AM
24063 /* ipv4 addr of the socket is invalid. Only the
24064 * unspecified and mapped address have a v4 equivalent.
24065 */
927ca606 24066@@ -357,6 +376,9 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24067 }
24068 }
24069
24070+ /* what's that for? */
24071+ v6_set_sock_addr(inet, &nsa);
2ba6f0dd 24072+
4bf69007
AM
24073 inet->inet_rcv_saddr = v4addr;
24074 inet->inet_saddr = v4addr;
24075
927ca606 24076@@ -461,9 +483,11 @@ int inet6_getname(struct socket *sock, s
4bf69007
AM
24077 return -ENOTCONN;
24078 sin->sin6_port = inet->inet_dport;
c2e5f7c8 24079 sin->sin6_addr = sk->sk_v6_daddr;
4bf69007
AM
24080+ /* FIXME: remap lback? */
24081 if (np->sndflow)
24082 sin->sin6_flowinfo = np->flow_label;
24083 } else {
24084+ /* FIXME: remap lback? */
c2e5f7c8 24085 if (ipv6_addr_any(&sk->sk_v6_rcv_saddr))
4bf69007
AM
24086 sin->sin6_addr = np->saddr;
24087 else
8de2f54c 24088diff -NurpP --minimal linux-4.4.111/net/ipv6/datagram.c linux-4.4.111-vs2.3.9.5/net/ipv6/datagram.c
f19bd705 24089--- linux-4.4.111/net/ipv6/datagram.c 2018-01-11 07:57:55.000000000 +0000
8de2f54c 24090+++ linux-4.4.111-vs2.3.9.5/net/ipv6/datagram.c 2018-01-09 16:36:34.000000000 +0000
927ca606 24091@@ -733,7 +733,7 @@ int ip6_datagram_send_ctl(struct net *ne
4bf69007
AM
24092
24093 rcu_read_lock();
24094 if (fl6->flowi6_oif) {
24095- dev = dev_get_by_index_rcu(net, fl6->flowi6_oif);
24096+ dev = dev_get_by_index_real_rcu(net, fl6->flowi6_oif);
24097 if (!dev) {
24098 rcu_read_unlock();
24099 return -ENODEV;
8de2f54c 24100diff -NurpP --minimal linux-4.4.111/net/ipv6/fib6_rules.c linux-4.4.111-vs2.3.9.5/net/ipv6/fib6_rules.c
f19bd705 24101--- linux-4.4.111/net/ipv6/fib6_rules.c 2018-01-11 07:57:55.000000000 +0000
8de2f54c 24102+++ linux-4.4.111-vs2.3.9.5/net/ipv6/fib6_rules.c 2018-01-09 16:36:34.000000000 +0000
c2e5f7c8 24103@@ -97,7 +97,7 @@ static int fib6_rule_action(struct fib_r
4bf69007
AM
24104 ip6_dst_idev(&rt->dst)->dev,
24105 &flp6->daddr,
24106 rt6_flags2srcprefs(flags),
24107- &saddr))
24108+ &saddr, NULL))
24109 goto again;
24110 if (!ipv6_prefix_equal(&saddr, &r->src.addr,
24111 r->src.plen))
8de2f54c 24112diff -NurpP --minimal linux-4.4.111/net/ipv6/inet6_hashtables.c linux-4.4.111-vs2.3.9.5/net/ipv6/inet6_hashtables.c
f19bd705 24113--- linux-4.4.111/net/ipv6/inet6_hashtables.c 2016-07-05 04:15:14.000000000 +0000
8de2f54c 24114+++ linux-4.4.111-vs2.3.9.5/net/ipv6/inet6_hashtables.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
24115@@ -16,6 +16,7 @@
24116
24117 #include <linux/module.h>
24118 #include <linux/random.h>
24119+#include <linux/vs_inet6.h>
24120
24121 #include <net/inet_connection_sock.h>
24122 #include <net/inet_hashtables.h>
927ca606 24123@@ -66,7 +67,6 @@ struct sock *__inet6_lookup_established(
4bf69007
AM
24124 unsigned int slot = hash & hashinfo->ehash_mask;
24125 struct inet_ehash_bucket *head = &hashinfo->ehash[slot];
24126
24127-
24128 rcu_read_lock();
24129 begin:
24130 sk_nulls_for_each_rcu(sk, node, &head->chain) {
927ca606 24131@@ -108,6 +108,9 @@ static inline int compute_score(struct s
c2e5f7c8 24132 if (!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr))
4bf69007
AM
24133 return -1;
24134 score++;
24135+ } else {
24136+ if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1))
24137+ return -1;
24138 }
24139 if (sk->sk_bound_dev_if) {
24140 if (sk->sk_bound_dev_if != dif)
8de2f54c 24141diff -NurpP --minimal linux-4.4.111/net/ipv6/ip6_fib.c linux-4.4.111-vs2.3.9.5/net/ipv6/ip6_fib.c
f19bd705 24142--- linux-4.4.111/net/ipv6/ip6_fib.c 2018-01-11 07:57:55.000000000 +0000
8de2f54c 24143+++ linux-4.4.111-vs2.3.9.5/net/ipv6/ip6_fib.c 2018-01-09 16:36:34.000000000 +0000
927ca606 24144@@ -1968,6 +1968,7 @@ static int ipv6_route_seq_show(struct se
c2e5f7c8
JR
24145 struct rt6_info *rt = v;
24146 struct ipv6_route_iter *iter = seq->private;
24147
24148+ /* FIXME: check for network context? */
24149 seq_printf(seq, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen);
24150
24151 #ifdef CONFIG_IPV6_SUBTREES
8de2f54c 24152diff -NurpP --minimal linux-4.4.111/net/ipv6/ip6_output.c linux-4.4.111-vs2.3.9.5/net/ipv6/ip6_output.c
f19bd705 24153--- linux-4.4.111/net/ipv6/ip6_output.c 2018-01-11 07:57:55.000000000 +0000
8de2f54c 24154+++ linux-4.4.111-vs2.3.9.5/net/ipv6/ip6_output.c 2018-01-09 16:36:34.000000000 +0000
927ca606
AM
24155@@ -941,7 +941,8 @@ static int ip6_dst_lookup_tail(struct ne
24156 rt = (*dst)->error ? NULL : (struct rt6_info *)*dst;
4bf69007
AM
24157 err = ip6_route_get_saddr(net, rt, &fl6->daddr,
24158 sk ? inet6_sk(sk)->srcprefs : 0,
24159- &fl6->saddr);
24160+ &fl6->saddr,
24161+ sk ? sk->sk_nx_info : NULL);
24162 if (err)
24163 goto out_err_release;
927ca606 24164
8de2f54c 24165diff -NurpP --minimal linux-4.4.111/net/ipv6/ndisc.c linux-4.4.111-vs2.3.9.5/net/ipv6/ndisc.c
f19bd705 24166--- linux-4.4.111/net/ipv6/ndisc.c 2016-07-05 04:15:14.000000000 +0000
8de2f54c 24167+++ linux-4.4.111-vs2.3.9.5/net/ipv6/ndisc.c 2018-01-09 16:36:34.000000000 +0000
927ca606 24168@@ -501,7 +501,7 @@ void ndisc_send_na(struct net_device *de
4bf69007
AM
24169 } else {
24170 if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
24171 inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
24172- &tmpaddr))
24173+ &tmpaddr, NULL))
24174 return;
24175 src_addr = &tmpaddr;
24176 }
8de2f54c 24177diff -NurpP --minimal linux-4.4.111/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c linux-4.4.111-vs2.3.9.5/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c
f19bd705 24178--- linux-4.4.111/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c 2016-07-05 04:15:14.000000000 +0000
8de2f54c 24179+++ linux-4.4.111-vs2.3.9.5/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c 2018-01-09 17:04:44.000000000 +0000
bb20add7 24180@@ -35,7 +35,7 @@ nf_nat_masquerade_ipv6(struct sk_buff *s
4bf69007
AM
24181 ctinfo == IP_CT_RELATED_REPLY));
24182
927ca606 24183 if (ipv6_dev_get_saddr(nf_ct_net(ct), out,
4bf69007
AM
24184- &ipv6_hdr(skb)->daddr, 0, &src) < 0)
24185+ &ipv6_hdr(skb)->daddr, 0, &src, NULL) < 0)
24186 return NF_DROP;
24187
bb20add7 24188 nfct_nat(ct)->masq_index = out->ifindex;
8de2f54c 24189diff -NurpP --minimal linux-4.4.111/net/ipv6/raw.c linux-4.4.111-vs2.3.9.5/net/ipv6/raw.c
f19bd705 24190--- linux-4.4.111/net/ipv6/raw.c 2018-01-11 07:57:55.000000000 +0000
8de2f54c 24191+++ linux-4.4.111-vs2.3.9.5/net/ipv6/raw.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
24192@@ -30,6 +30,7 @@
24193 #include <linux/icmpv6.h>
24194 #include <linux/netfilter.h>
24195 #include <linux/netfilter_ipv6.h>
24196+#include <linux/vs_inet6.h>
24197 #include <linux/skbuff.h>
24198 #include <linux/compat.h>
927ca606 24199 #include <linux/uaccess.h>
bb20add7 24200@@ -291,6 +292,13 @@ static int rawv6_bind(struct sock *sk, s
4bf69007
AM
24201 goto out_unlock;
24202 }
24203
24204+ if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) {
24205+ err = -EADDRNOTAVAIL;
24206+ if (dev)
24207+ dev_put(dev);
24208+ goto out;
24209+ }
2ba6f0dd 24210+
4bf69007
AM
24211 /* ipv4 addr of the socket is invalid. Only the
24212 * unspecified and mapped address have a v4 equivalent.
24213 */
8de2f54c 24214diff -NurpP --minimal linux-4.4.111/net/ipv6/route.c linux-4.4.111-vs2.3.9.5/net/ipv6/route.c
f19bd705 24215--- linux-4.4.111/net/ipv6/route.c 2018-01-11 07:57:55.000000000 +0000
8de2f54c 24216+++ linux-4.4.111-vs2.3.9.5/net/ipv6/route.c 2018-01-09 17:03:24.000000000 +0000
927ca606
AM
24217@@ -62,6 +62,7 @@
24218 #include <net/lwtunnel.h>
24219 #include <net/ip_tunnels.h>
24220 #include <net/l3mdev.h>
4bf69007
AM
24221+#include <linux/vs_inet6.h>
24222
24223 #include <asm/uaccess.h>
24224
927ca606 24225@@ -2545,16 +2546,18 @@ int ip6_route_get_saddr(struct net *net,
4bf69007
AM
24226 struct rt6_info *rt,
24227 const struct in6_addr *daddr,
24228 unsigned int prefs,
24229- struct in6_addr *saddr)
24230+ struct in6_addr *saddr,
24231+ struct nx_info *nxi)
24232 {
927ca606
AM
24233 struct inet6_dev *idev =
24234 rt ? ip6_dst_idev((struct dst_entry *)rt) : NULL;
4bf69007 24235 int err = 0;
927ca606
AM
24236- if (rt && rt->rt6i_prefsrc.plen)
24237+ if (rt && rt->rt6i_prefsrc.plen && (!nxi ||
4bf69007
AM
24238+ v6_addr_in_nx_info(nxi, &rt->rt6i_prefsrc.addr, NXA_TYPE_ADDR)))
24239 *saddr = rt->rt6i_prefsrc.addr;
24240 else
24241 err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
24242- daddr, prefs, saddr);
24243+ daddr, prefs, saddr, nxi);
24244 return err;
24245 }
24246
927ca606 24247@@ -3168,7 +3171,8 @@ static int rt6_fill_node(struct net *net
4bf69007
AM
24248 goto nla_put_failure;
24249 } else if (dst) {
24250 struct in6_addr saddr_buf;
24251- if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf) == 0 &&
24252+ if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf,
24253+ (skb->sk ? skb->sk->sk_nx_info : NULL)) == 0 &&
927ca606 24254 nla_put_in6_addr(skb, RTA_PREFSRC, &saddr_buf))
4bf69007
AM
24255 goto nla_put_failure;
24256 }
8de2f54c 24257diff -NurpP --minimal linux-4.4.111/net/ipv6/tcp_ipv6.c linux-4.4.111-vs2.3.9.5/net/ipv6/tcp_ipv6.c
f19bd705 24258--- linux-4.4.111/net/ipv6/tcp_ipv6.c 2018-01-11 07:57:55.000000000 +0000
8de2f54c 24259+++ linux-4.4.111-vs2.3.9.5/net/ipv6/tcp_ipv6.c 2018-01-09 16:36:34.000000000 +0000
bb20add7 24260@@ -69,6 +69,7 @@
4bf69007
AM
24261
24262 #include <linux/crypto.h>
24263 #include <linux/scatterlist.h>
24264+#include <linux/vs_inet6.h>
24265
927ca606
AM
24266 static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb);
24267 static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
24268@@ -150,11 +151,18 @@ static int tcp_v6_connect(struct sock *s
4bf69007
AM
24269 */
24270
927ca606
AM
24271 if (ipv6_addr_any(&usin->sin6_addr)) {
24272- if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr))
24273- ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK),
24274- &usin->sin6_addr);
24275- else
24276- usin->sin6_addr = in6addr_loopback;
4bf69007 24277+ struct nx_info *nxi = sk->sk_nx_info;
2ba6f0dd 24278+
4bf69007
AM
24279+ if (nxi && nx_info_has_v6(nxi))
24280+ /* FIXME: remap lback? */
24281+ usin->sin6_addr = nxi->v6.ip;
927ca606
AM
24282+ else {
24283+ if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr))
24284+ ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK),
24285+ &usin->sin6_addr);
24286+ else
24287+ usin->sin6_addr = in6addr_loopback;
24288+ }
24289 }
4bf69007
AM
24290
24291 addr_type = ipv6_addr_type(&usin->sin6_addr);
8de2f54c 24292diff -NurpP --minimal linux-4.4.111/net/ipv6/udp.c linux-4.4.111-vs2.3.9.5/net/ipv6/udp.c
f19bd705 24293--- linux-4.4.111/net/ipv6/udp.c 2018-01-11 07:57:55.000000000 +0000
8de2f54c 24294+++ linux-4.4.111-vs2.3.9.5/net/ipv6/udp.c 2018-01-09 16:36:34.000000000 +0000
c2e5f7c8 24295@@ -47,6 +47,7 @@
4bf69007 24296 #include <net/xfrm.h>
b00e13aa 24297 #include <net/inet6_hashtables.h>
c2e5f7c8 24298 #include <net/busy_poll.h>
4bf69007
AM
24299+#include <linux/vs_inet6.h>
24300
24301 #include <linux/proc_fs.h>
24302 #include <linux/seq_file.h>
927ca606
AM
24303@@ -76,32 +77,60 @@ static u32 udp6_ehashfn(const struct net
24304 udp_ipv6_hash_secret + net_hash_mix(net));
24305 }
24306
24307-int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
24308+int ipv6_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
24309 {
24310+ const struct in6_addr *sk1_rcv_saddr6 = inet6_rcv_saddr(sk1);
24311 const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
24312+ __be32 sk1_rcv_saddr = sk1->sk_rcv_saddr;
24313+ __be32 sk2_rcv_saddr = sk2->sk_rcv_saddr;
24314 int sk2_ipv6only = inet_v6_ipv6only(sk2);
24315- int addr_type = ipv6_addr_type(&sk->sk_v6_rcv_saddr);
24316+ int addr_type1 = ipv6_addr_type(sk1_rcv_saddr6);
24317 int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED;
24318
24319 /* if both are mapped, treat as IPv4 */
24320- if (addr_type == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED)
24321- return (!sk2_ipv6only &&
24322- (!sk->sk_rcv_saddr || !sk2->sk_rcv_saddr ||
24323- sk->sk_rcv_saddr == sk2->sk_rcv_saddr));
24324+ if (addr_type1 == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED) {
24325+ if (!sk2_ipv6only &&
24326+ (!sk1->sk_rcv_saddr || !sk2->sk_rcv_saddr ||
24327+ sk1->sk_rcv_saddr == sk2->sk_rcv_saddr))
24328+ goto vs_v4;
24329+ else
24330+ return 0;
24331+ }
24332
24333 if (addr_type2 == IPV6_ADDR_ANY &&
24334- !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED))
24335- return 1;
24336+ !(sk2_ipv6only && addr_type1 == IPV6_ADDR_MAPPED))
24337+ goto vs;
24338
24339- if (addr_type == IPV6_ADDR_ANY &&
24340- !(ipv6_only_sock(sk) && addr_type2 == IPV6_ADDR_MAPPED))
24341- return 1;
24342+ if (addr_type1 == IPV6_ADDR_ANY &&
24343+ !(ipv6_only_sock(sk1) && addr_type2 == IPV6_ADDR_MAPPED))
24344+ goto vs;
24345
24346 if (sk2_rcv_saddr6 &&
24347- ipv6_addr_equal(&sk->sk_v6_rcv_saddr, sk2_rcv_saddr6))
24348- return 1;
24349+ ipv6_addr_equal(&sk1->sk_v6_rcv_saddr, sk2_rcv_saddr6))
24350+ goto vs;
24351
24352 return 0;
24353+
24354+vs_v4:
24355+ if (!sk1_rcv_saddr && !sk2_rcv_saddr)
24356+ return nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
24357+ if (!sk2_rcv_saddr)
24358+ return v4_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr, -1);
24359+ if (!sk1_rcv_saddr)
24360+ return v4_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr, -1);
24361+ return 1;
24362+vs:
24363+ if (addr_type2 == IPV6_ADDR_ANY && addr_type1 == IPV6_ADDR_ANY)
24364+ return nx_v6_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
24365+ else if (addr_type2 == IPV6_ADDR_ANY)
24366+ return v6_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr6, -1);
24367+ else if (addr_type1 == IPV6_ADDR_ANY) {
24368+ if (addr_type2 == IPV6_ADDR_MAPPED)
24369+ return nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
24370+ else
24371+ return v6_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr6, -1);
24372+ }
24373+ return 1;
24374 }
24375
24376 static u32 udp6_portaddr_hash(const struct net *net,
24377@@ -162,6 +191,10 @@ static inline int compute_score(struct s
24378 if (inet->inet_dport != sport)
24379 return -1;
24380 score++;
4bf69007
AM
24381+ } else {
24382+ /* block non nx_info ips */
24383+ if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1))
24384+ return -1;
927ca606
AM
24385 }
24386
24387 if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
8de2f54c 24388diff -NurpP --minimal linux-4.4.111/net/ipv6/xfrm6_policy.c linux-4.4.111-vs2.3.9.5/net/ipv6/xfrm6_policy.c
f19bd705 24389--- linux-4.4.111/net/ipv6/xfrm6_policy.c 2016-07-05 04:15:14.000000000 +0000
8de2f54c 24390+++ linux-4.4.111-vs2.3.9.5/net/ipv6/xfrm6_policy.c 2018-01-09 16:36:34.000000000 +0000
927ca606
AM
24391@@ -64,7 +64,8 @@ static int xfrm6_get_saddr(struct net *n
24392 return -EHOSTUNREACH;
24393
4bf69007 24394 dev = ip6_dst_idev(dst)->dev;
927ca606
AM
24395- ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6, 0, &saddr->in6);
24396+ ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6,
24397+ 0, &saddr->in6, NULL);
4bf69007
AM
24398 dst_release(dst);
24399 return 0;
24400 }
8de2f54c 24401diff -NurpP --minimal linux-4.4.111/net/netfilter/ipvs/ip_vs_xmit.c linux-4.4.111-vs2.3.9.5/net/netfilter/ipvs/ip_vs_xmit.c
f19bd705 24402--- linux-4.4.111/net/netfilter/ipvs/ip_vs_xmit.c 2016-07-05 04:15:15.000000000 +0000
8de2f54c 24403+++ linux-4.4.111-vs2.3.9.5/net/netfilter/ipvs/ip_vs_xmit.c 2018-01-09 16:36:34.000000000 +0000
927ca606 24404@@ -381,7 +381,7 @@ __ip_vs_route_output_v6(struct net *net,
4bf69007
AM
24405 return dst;
24406 if (ipv6_addr_any(&fl6.saddr) &&
24407 ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev,
24408- &fl6.daddr, 0, &fl6.saddr) < 0)
24409+ &fl6.daddr, 0, &fl6.saddr, NULL) < 0)
24410 goto out_err;
24411 if (do_xfrm) {
24412 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
8de2f54c 24413diff -NurpP --minimal linux-4.4.111/net/netlink/af_netlink.c linux-4.4.111-vs2.3.9.5/net/netlink/af_netlink.c
f19bd705 24414--- linux-4.4.111/net/netlink/af_netlink.c 2018-01-11 07:57:56.000000000 +0000
8de2f54c 24415+++ linux-4.4.111-vs2.3.9.5/net/netlink/af_netlink.c 2018-01-09 16:36:34.000000000 +0000
927ca606 24416@@ -62,6 +62,8 @@
bb20add7
AM
24417 #include <asm/cacheflush.h>
24418 #include <linux/hash.h>
927ca606 24419 #include <linux/genetlink.h>
4bf69007
AM
24420+#include <linux/vs_context.h>
24421+#include <linux/vs_network.h>
4bf69007
AM
24422
24423 #include <net/net_namespace.h>
bb20add7 24424 #include <net/sock.h>
927ca606
AM
24425@@ -2460,7 +2462,8 @@ static void *__netlink_seq_next(struct s
24426 if (err)
24427 return ERR_PTR(err);
24428 }
24429- } while (sock_net(&nlk->sk) != seq_file_net(seq));
24430+ } while ((sock_net(&nlk->sk) != seq_file_net(seq)) ||
24431+ !nx_check(nlk->sk.sk_nid, VS_WATCH_P | VS_IDENT));
bb20add7 24432
927ca606
AM
24433 return nlk;
24434 }
8de2f54c 24435diff -NurpP --minimal linux-4.4.111/net/socket.c linux-4.4.111-vs2.3.9.5/net/socket.c
f19bd705 24436--- linux-4.4.111/net/socket.c 2018-01-11 07:57:56.000000000 +0000
8de2f54c 24437+++ linux-4.4.111-vs2.3.9.5/net/socket.c 2018-01-09 16:36:34.000000000 +0000
927ca606 24438@@ -99,10 +99,12 @@
4bf69007
AM
24439
24440 #include <net/sock.h>
24441 #include <linux/netfilter.h>
4bf69007
AM
24442+#include <linux/vs_socket.h>
24443+#include <linux/vs_inet.h>
24444+#include <linux/vs_inet6.h>
24445
24446 #include <linux/if_tun.h>
24447 #include <linux/ipv6_route.h>
927ca606
AM
24448-#include <linux/route.h>
24449 #include <linux/sockios.h>
24450 #include <linux/atalk.h>
24451 #include <net/busy_poll.h>
24452@@ -608,8 +610,24 @@ EXPORT_SYMBOL(__sock_tx_timestamp);
4bf69007 24453
927ca606
AM
24454 static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
24455 {
24456- int ret = sock->ops->sendmsg(sock, msg, msg_data_left(msg));
24457- BUG_ON(ret == -EIOCBQUEUED);
24458+ size_t size = msg_data_left(msg);
24459+ int ret = sock->ops->sendmsg(sock, msg, size);
24460+#if 0
4bf69007 24461+ if (sock->sk) {
927ca606 24462+ if (!ret)
4bf69007 24463+ vx_sock_fail(sock->sk, size);
927ca606
AM
24464+ else
24465+ vx_sock_send(sock->sk, size);
4bf69007 24466+ }
927ca606 24467+#endif
4bf69007 24468+ vxdprintk(VXD_CBIT(net, 7),
927ca606 24469+ "sock_sendmsg_nosec: %p[%p,%p,%p;%d/%d]:%zu/%zu",
4bf69007
AM
24470+ sock, sock->sk,
24471+ (sock->sk)?sock->sk->sk_nx_info:0,
24472+ (sock->sk)?sock->sk->sk_vx_info:0,
24473+ (sock->sk)?sock->sk->sk_xid:0,
24474+ (sock->sk)?sock->sk->sk_nid:0,
927ca606
AM
24475+ size, msg_data_left(msg));
24476 return ret;
4bf69007
AM
24477 }
24478
927ca606 24479@@ -1100,6 +1118,13 @@ int __sock_create(struct net *net, int f
4bf69007
AM
24480 if (type < 0 || type >= SOCK_MAX)
24481 return -EINVAL;
24482
24483+ if (!nx_check(0, VS_ADMIN)) {
24484+ if (family == PF_INET && !current_nx_info_has_v4())
24485+ return -EAFNOSUPPORT;
24486+ if (family == PF_INET6 && !current_nx_info_has_v6())
24487+ return -EAFNOSUPPORT;
24488+ }
2ba6f0dd 24489+
4bf69007
AM
24490 /* Compatibility.
24491
24492 This uglymoron is moved from INET layer to here to avoid
927ca606 24493@@ -1234,6 +1259,7 @@ SYSCALL_DEFINE3(socket, int, family, int
4bf69007
AM
24494 if (retval < 0)
24495 goto out;
24496
24497+ set_bit(SOCK_USER_SOCKET, &sock->flags);
24498 retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
24499 if (retval < 0)
24500 goto out_release;
927ca606 24501@@ -1275,10 +1301,12 @@ SYSCALL_DEFINE4(socketpair, int, family,
4bf69007
AM
24502 err = sock_create(family, type, protocol, &sock1);
24503 if (err < 0)
24504 goto out;
24505+ set_bit(SOCK_USER_SOCKET, &sock1->flags);
24506
24507 err = sock_create(family, type, protocol, &sock2);
24508 if (err < 0)
24509 goto out_release_1;
24510+ set_bit(SOCK_USER_SOCKET, &sock2->flags);
24511
24512 err = sock1->ops->socketpair(sock1, sock2);
24513 if (err < 0)
8de2f54c 24514diff -NurpP --minimal linux-4.4.111/net/sunrpc/auth.c linux-4.4.111-vs2.3.9.5/net/sunrpc/auth.c
f19bd705 24515--- linux-4.4.111/net/sunrpc/auth.c 2015-10-29 09:21:46.000000000 +0000
8de2f54c 24516+++ linux-4.4.111-vs2.3.9.5/net/sunrpc/auth.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
24517@@ -15,6 +15,7 @@
24518 #include <linux/sunrpc/clnt.h>
24519 #include <linux/sunrpc/gss_api.h>
24520 #include <linux/spinlock.h>
24521+#include <linux/vs_tag.h>
24522
927ca606 24523 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
4bf69007 24524 # define RPCDBG_FACILITY RPCDBG_AUTH
bb20add7 24525@@ -630,6 +631,7 @@ rpcauth_lookupcred(struct rpc_auth *auth
4bf69007
AM
24526 memset(&acred, 0, sizeof(acred));
24527 acred.uid = cred->fsuid;
24528 acred.gid = cred->fsgid;
a4a22af8 24529+ acred.tag = make_ktag(&init_user_ns, dx_current_tag());
bb20add7 24530 acred.group_info = cred->group_info;
4bf69007 24531 ret = auth->au_ops->lookup_cred(auth, &acred, flags);
bb20add7
AM
24532 return ret;
24533@@ -669,6 +671,7 @@ rpcauth_bind_root_cred(struct rpc_task *
4bf69007 24534 struct auth_cred acred = {
b00e13aa
AM
24535 .uid = GLOBAL_ROOT_UID,
24536 .gid = GLOBAL_ROOT_GID,
a4a22af8 24537+ .tag = KTAGT_INIT(dx_current_tag()),
4bf69007
AM
24538 };
24539
24540 dprintk("RPC: %5u looking up %s cred\n",
8de2f54c 24541diff -NurpP --minimal linux-4.4.111/net/sunrpc/auth_unix.c linux-4.4.111-vs2.3.9.5/net/sunrpc/auth_unix.c
f19bd705 24542--- linux-4.4.111/net/sunrpc/auth_unix.c 2016-07-05 04:12:45.000000000 +0000
8de2f54c 24543+++ linux-4.4.111-vs2.3.9.5/net/sunrpc/auth_unix.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
24544@@ -13,11 +13,13 @@
24545 #include <linux/sunrpc/clnt.h>
24546 #include <linux/sunrpc/auth.h>
24547 #include <linux/user_namespace.h>
24548+#include <linux/vs_tag.h>
24549
24550 #define NFS_NGROUPS 16
24551
24552 struct unx_cred {
24553 struct rpc_cred uc_base;
b00e13aa
AM
24554+ ktag_t uc_tag;
24555 kgid_t uc_gid;
24556 kgid_t uc_gids[NFS_NGROUPS];
4bf69007 24557 };
b00e13aa 24558@@ -80,6 +82,7 @@ unx_create_cred(struct rpc_auth *auth, s
4bf69007
AM
24559 groups = NFS_NGROUPS;
24560
24561 cred->uc_gid = acred->gid;
24562+ cred->uc_tag = acred->tag;
b00e13aa
AM
24563 for (i = 0; i < groups; i++)
24564 cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
24565 if (i < NFS_NGROUPS)
24566@@ -121,7 +124,9 @@ unx_match(struct auth_cred *acred, struc
4bf69007
AM
24567 unsigned int i;
24568
24569
b00e13aa
AM
24570- if (!uid_eq(cred->uc_uid, acred->uid) || !gid_eq(cred->uc_gid, acred->gid))
24571+ if (!uid_eq(cred->uc_uid, acred->uid) ||
24572+ !gid_eq(cred->uc_gid, acred->gid) ||
24573+ !tag_eq(cred->uc_tag, acred->tag))
4bf69007
AM
24574 return 0;
24575
24576 if (acred->group_info != NULL)
b00e13aa 24577@@ -146,7 +151,7 @@ unx_marshal(struct rpc_task *task, __be3
4bf69007
AM
24578 struct rpc_clnt *clnt = task->tk_client;
24579 struct unx_cred *cred = container_of(task->tk_rqstp->rq_cred, struct unx_cred, uc_base);
24580 __be32 *base, *hold;
24581- int i;
24582+ int i, tag;
24583
24584 *p++ = htonl(RPC_AUTH_UNIX);
24585 base = p++;
a4a22af8 24586@@ -157,8 +162,11 @@ unx_marshal(struct rpc_task *task, __be3
4bf69007
AM
24587 */
24588 p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
4bf69007 24589
b00e13aa
AM
24590- *p++ = htonl((u32) from_kuid(&init_user_ns, cred->uc_uid));
24591- *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gid));
24592+ tag = task->tk_client->cl_tag;
a4a22af8
AM
24593+ *p++ = htonl((u32) from_kuid(&init_user_ns,
24594+ TAGINO_KUID(tag, cred->uc_uid, cred->uc_tag)));
24595+ *p++ = htonl((u32) from_kgid(&init_user_ns,
24596+ TAGINO_KGID(tag, cred->uc_gid, cred->uc_tag)));
4bf69007 24597 hold = p++;
b00e13aa
AM
24598 for (i = 0; i < 16 && gid_valid(cred->uc_gids[i]); i++)
24599 *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gids[i]));
8de2f54c 24600diff -NurpP --minimal linux-4.4.111/net/sunrpc/clnt.c linux-4.4.111-vs2.3.9.5/net/sunrpc/clnt.c
f19bd705 24601--- linux-4.4.111/net/sunrpc/clnt.c 2018-01-11 07:57:57.000000000 +0000
8de2f54c 24602+++ linux-4.4.111-vs2.3.9.5/net/sunrpc/clnt.c 2018-01-09 16:36:34.000000000 +0000
4bf69007 24603@@ -31,6 +31,7 @@
c2e5f7c8 24604 #include <linux/in.h>
4bf69007
AM
24605 #include <linux/in6.h>
24606 #include <linux/un.h>
4bf69007
AM
24607+#include <linux/vs_cvirt.h>
24608
24609 #include <linux/sunrpc/clnt.h>
b00e13aa 24610 #include <linux/sunrpc/addr.h>
927ca606 24611@@ -477,6 +478,9 @@ static struct rpc_clnt *rpc_create_xprt(
4bf69007
AM
24612 if (!(args->flags & RPC_CLNT_CREATE_QUIET))
24613 clnt->cl_chatty = 1;
24614
24615+ /* TODO: handle RPC_CLNT_CREATE_TAGGED
24616+ if (args->flags & RPC_CLNT_CREATE_TAGGED)
24617+ clnt->cl_tag = 1; */
24618 return clnt;
24619 }
927ca606 24620
8de2f54c 24621diff -NurpP --minimal linux-4.4.111/net/unix/af_unix.c linux-4.4.111-vs2.3.9.5/net/unix/af_unix.c
f19bd705 24622--- linux-4.4.111/net/unix/af_unix.c 2018-01-11 07:57:57.000000000 +0000
8de2f54c 24623+++ linux-4.4.111-vs2.3.9.5/net/unix/af_unix.c 2018-01-09 16:36:34.000000000 +0000
bb20add7 24624@@ -117,6 +117,8 @@
4bf69007
AM
24625 #include <net/checksum.h>
24626 #include <linux/security.h>
c2e5f7c8 24627 #include <linux/freezer.h>
4bf69007
AM
24628+#include <linux/vs_context.h>
24629+#include <linux/vs_limit.h>
24630
24631 struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
24632 EXPORT_SYMBOL_GPL(unix_socket_table);
927ca606 24633@@ -282,6 +284,8 @@ static struct sock *__unix_find_socket_b
4bf69007
AM
24634 if (!net_eq(sock_net(s), net))
24635 continue;
24636
24637+ if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT))
24638+ continue;
24639 if (u->addr->len == len &&
24640 !memcmp(u->addr->name, sunname, len))
24641 goto found;
927ca606 24642@@ -2741,6 +2745,8 @@ static struct sock *unix_from_bucket(str
4bf69007
AM
24643 for (sk = sk_head(&unix_socket_table[bucket]); sk; sk = sk_next(sk)) {
24644 if (sock_net(sk) != seq_file_net(seq))
24645 continue;
24646+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24647+ continue;
24648 if (++count == offset)
24649 break;
24650 }
927ca606 24651@@ -2758,6 +2764,8 @@ static struct sock *unix_next_socket(str
4bf69007
AM
24652 sk = sk_next(sk);
24653 if (!sk)
24654 goto next_bucket;
24655+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24656+ continue;
24657 if (sock_net(sk) == seq_file_net(seq))
24658 return sk;
24659 }
8de2f54c 24660diff -NurpP --minimal linux-4.4.111/scripts/checksyscalls.sh linux-4.4.111-vs2.3.9.5/scripts/checksyscalls.sh
f19bd705 24661--- linux-4.4.111/scripts/checksyscalls.sh 2015-10-29 09:21:46.000000000 +0000
8de2f54c 24662+++ linux-4.4.111-vs2.3.9.5/scripts/checksyscalls.sh 2018-01-09 16:36:34.000000000 +0000
bb20add7 24663@@ -196,7 +196,6 @@ cat << EOF
4bf69007
AM
24664 #define __IGNORE_afs_syscall
24665 #define __IGNORE_getpmsg
24666 #define __IGNORE_putpmsg
24667-#define __IGNORE_vserver
24668 EOF
24669 }
24670
8de2f54c 24671diff -NurpP --minimal linux-4.4.111/security/commoncap.c linux-4.4.111-vs2.3.9.5/security/commoncap.c
f19bd705 24672--- linux-4.4.111/security/commoncap.c 2018-01-11 07:57:57.000000000 +0000
8de2f54c 24673+++ linux-4.4.111-vs2.3.9.5/security/commoncap.c 2018-01-09 16:36:34.000000000 +0000
927ca606 24674@@ -71,6 +71,7 @@ static void warn_setuid_and_fcaps_mixed(
4bf69007
AM
24675 int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
24676 int cap, int audit)
24677 {
24678+ struct vx_info *vxi = current_vx_info(); /* FIXME: get vxi from cred? */
b00e13aa 24679 struct user_namespace *ns = targ_ns;
4bf69007 24680
b00e13aa 24681 /* See if cred has the capability in the target user namespace
927ca606 24682@@ -79,8 +80,12 @@ int cap_capable(const struct cred *cred,
b00e13aa
AM
24683 */
24684 for (;;) {
4bf69007 24685 /* Do we have the necessary capabilities? */
b00e13aa 24686- if (ns == cred->user_ns)
4bf69007 24687- return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM;
b00e13aa 24688+ if (ns == cred->user_ns) {
4bf69007
AM
24689+ if (vx_info_flags(vxi, VXF_STATE_SETUP, 0) &&
24690+ cap_raised(cred->cap_effective, cap))
24691+ return 0;
24692+ return vx_cap_raised(vxi, cred->cap_effective, cap) ? 0 : -EPERM;
24693+ }
24694
24695 /* Have we tried all of the parent namespaces? */
b00e13aa 24696 if (ns == &init_user_ns)
927ca606 24697@@ -664,7 +669,7 @@ int cap_inode_setxattr(struct dentry *de
4bf69007
AM
24698
24699 if (!strncmp(name, XATTR_SECURITY_PREFIX,
24700 sizeof(XATTR_SECURITY_PREFIX) - 1) &&
24701- !capable(CAP_SYS_ADMIN))
24702+ !vx_capable(CAP_SYS_ADMIN, VXC_FS_SECURITY))
24703 return -EPERM;
24704 return 0;
24705 }
927ca606 24706@@ -690,7 +695,7 @@ int cap_inode_removexattr(struct dentry
4bf69007
AM
24707
24708 if (!strncmp(name, XATTR_SECURITY_PREFIX,
24709 sizeof(XATTR_SECURITY_PREFIX) - 1) &&
24710- !capable(CAP_SYS_ADMIN))
24711+ !vx_capable(CAP_SYS_ADMIN, VXC_FS_SECURITY))
24712 return -EPERM;
24713 return 0;
24714 }
8de2f54c 24715diff -NurpP --minimal linux-4.4.111/security/selinux/hooks.c linux-4.4.111-vs2.3.9.5/security/selinux/hooks.c
f19bd705 24716--- linux-4.4.111/security/selinux/hooks.c 2018-01-11 07:57:57.000000000 +0000
8de2f54c 24717+++ linux-4.4.111-vs2.3.9.5/security/selinux/hooks.c 2018-01-09 16:36:34.000000000 +0000
927ca606 24718@@ -67,7 +67,6 @@
4bf69007
AM
24719 #include <linux/dccp.h>
24720 #include <linux/quota.h>
24721 #include <linux/un.h> /* for Unix socket types */
24722-#include <net/af_unix.h> /* for Unix socket types */
24723 #include <linux/parser.h>
24724 #include <linux/nfs_mount.h>
24725 #include <net/ipv6.h>
This page took 6.634034 seconds and 4 git commands to generate.