summaryrefslogtreecommitdiff
blob: 7756ec5d9aeb78c08041634a6b1e7ea0a0914e1c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
Index: linux-2.6.18/kernel/vserver/limit.c
===================================================================
--- linux-2.6.18.orig/kernel/vserver/limit.c
+++ linux-2.6.18/kernel/vserver/limit.c
@@ -41,31 +41,53 @@ const char *vlimit_name[NUM_LIMITS] = {
 
 EXPORT_SYMBOL_GPL(vlimit_name);
 
+#define MASK_ENTRY(x)	(1 << (x))
 
-static int is_valid_rlimit(int id)
-{
-	int valid = 0;
-
-	switch (id) {
-	case RLIMIT_RSS:
-	case RLIMIT_NPROC:
-	case RLIMIT_NOFILE:
-	case RLIMIT_MEMLOCK:
-	case RLIMIT_AS:
-	case RLIMIT_LOCKS:
-	case RLIMIT_MSGQUEUE:
-
-	case VLIMIT_NSOCK:
-	case VLIMIT_OPENFD:
-	case VLIMIT_ANON:
-	case VLIMIT_SHMEM:
-	case VLIMIT_DENTRY:
-		valid = 1;
-		break;
-	}
-	return valid;
+const struct vcmd_ctx_rlimit_mask_v0 vlimit_mask = {
+		/* minimum */
+	0
+	,	/* softlimit */
+	MASK_ENTRY( RLIMIT_RSS		) |
+	MASK_ENTRY( VLIMIT_ANON		) |
+	0
+	,       /* maximum */
+	MASK_ENTRY( RLIMIT_RSS		) |
+	MASK_ENTRY( RLIMIT_NPROC	) |
+	MASK_ENTRY( RLIMIT_NOFILE	) |
+	MASK_ENTRY( RLIMIT_MEMLOCK	) |
+	MASK_ENTRY( RLIMIT_AS		) |
+	MASK_ENTRY( RLIMIT_LOCKS	) |
+	MASK_ENTRY( RLIMIT_MSGQUEUE	) |
+
+	MASK_ENTRY( VLIMIT_NSOCK	) |
+	MASK_ENTRY( VLIMIT_OPENFD	) |
+	MASK_ENTRY( VLIMIT_ANON		) |
+	MASK_ENTRY( VLIMIT_SHMEM	) |
+	MASK_ENTRY( VLIMIT_DENTRY	) |
+	0
+};
+		/* accounting only */
+uint32_t account_mask =
+	MASK_ENTRY( VLIMIT_SEMARY	) |
+	MASK_ENTRY( VLIMIT_NSEMS	) |
+	0;
+
+
+static int is_valid_vlimit(int id)
+{
+	uint32_t mask = vlimit_mask.minimum |
+		vlimit_mask.softlimit | vlimit_mask.maximum;
+	return mask & (1 << id);
+}
+
+static int is_accounted_vlimit(int id)
+{
+	if (is_valid_vlimit(id))
+		return 1;
+	return account_mask & (1 << id);
 }
 
+
 static inline uint64_t vc_get_soft(struct vx_info *vxi, int id)
 {
 	rlim_t limit = __rlim_soft(&vxi->limit, id);
@@ -81,7 +103,7 @@ static inline uint64_t vc_get_hard(struc
 static int do_get_rlimit(struct vx_info *vxi, uint32_t id,
 	uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum)
 {
-	if (!is_valid_rlimit(id))
+	if (!is_valid_vlimit(id))
 		return -EINVAL;
 
 	if (minimum)
@@ -114,7 +136,7 @@ int vc_get_rlimit(struct vx_info *vxi, v
 static int do_set_rlimit(struct vx_info *vxi, uint32_t id,
 	uint64_t minimum, uint64_t softlimit, uint64_t maximum)
 {
-	if (!is_valid_rlimit(id))
+	if (!is_valid_vlimit(id))
 		return -EINVAL;
 
 	if (maximum != CRLIM_KEEP)
@@ -176,26 +198,7 @@ int vc_get_rlimit_x32(struct vx_info *vx
 
 int vc_get_rlimit_mask(uint32_t id, void __user *data)
 {
-	static struct vcmd_ctx_rlimit_mask_v0 mask = {
-			/* minimum */
-		0
-		,	/* softlimit */
-		(1 << RLIMIT_RSS) |
-		(1 << VLIMIT_ANON) |
-		0
-		,	/* maximum */
-		(1 << RLIMIT_RSS) |
-		(1 << RLIMIT_NPROC) |
-		(1 << RLIMIT_NOFILE) |
-		(1 << RLIMIT_MEMLOCK) |
-		(1 << RLIMIT_LOCKS) |
-		(1 << RLIMIT_AS) |
-		(1 << VLIMIT_ANON) |
-		(1 << VLIMIT_DENTRY) |
-		0
-		};
-
-	if (copy_to_user(data, &mask, sizeof(mask)))
+	if (copy_to_user(data, &vlimit_mask, sizeof(vlimit_mask)))
 		return -EFAULT;
 	return 0;
 }
@@ -231,7 +234,7 @@ int vc_rlimit_stat(struct vx_info *vxi, 
 		return -EFAULT;
 
 	id = vc_data.id;
-	if (!is_valid_rlimit(id))
+	if (!is_accounted_vlimit(id))
 		return -EINVAL;
 
 	vc_data.hits = atomic_read(&__rlim_lhit(limit, id));