9
9
#include <linux/ipc_namespace.h>
10
10
#include <linux/sysctl.h>
11
11
12
- #ifdef CONFIG_PROC_SYSCTL
13
- static void * get_mq (struct ctl_table * table )
14
- {
15
- char * which = table -> data ;
16
- struct ipc_namespace * ipc_ns = current -> nsproxy -> ipc_ns ;
17
- which = (which - (char * )& init_ipc_ns ) + (char * )ipc_ns ;
18
- return which ;
19
- }
20
-
21
- static int proc_mq_dointvec (struct ctl_table * table , int write ,
22
- void * buffer , size_t * lenp , loff_t * ppos )
23
- {
24
- struct ctl_table mq_table ;
25
- memcpy (& mq_table , table , sizeof (mq_table ));
26
- mq_table .data = get_mq (table );
27
-
28
- return proc_dointvec (& mq_table , write , buffer , lenp , ppos );
29
- }
30
-
31
- static int proc_mq_dointvec_minmax (struct ctl_table * table , int write ,
32
- void * buffer , size_t * lenp , loff_t * ppos )
33
- {
34
- struct ctl_table mq_table ;
35
- memcpy (& mq_table , table , sizeof (mq_table ));
36
- mq_table .data = get_mq (table );
37
-
38
- return proc_dointvec_minmax (& mq_table , write , buffer ,
39
- lenp , ppos );
40
- }
41
- #else
42
- #define proc_mq_dointvec NULL
43
- #define proc_mq_dointvec_minmax NULL
44
- #endif
12
+ #include <linux/stat.h>
13
+ #include <linux/capability.h>
14
+ #include <linux/slab.h>
45
15
46
16
static int msg_max_limit_min = MIN_MSGMAX ;
47
17
static int msg_max_limit_max = HARD_MSGMAX ;
@@ -55,14 +25,14 @@ static struct ctl_table mq_sysctls[] = {
55
25
.data = & init_ipc_ns .mq_queues_max ,
56
26
.maxlen = sizeof (int ),
57
27
.mode = 0644 ,
58
- .proc_handler = proc_mq_dointvec ,
28
+ .proc_handler = proc_dointvec ,
59
29
},
60
30
{
61
31
.procname = "msg_max" ,
62
32
.data = & init_ipc_ns .mq_msg_max ,
63
33
.maxlen = sizeof (int ),
64
34
.mode = 0644 ,
65
- .proc_handler = proc_mq_dointvec_minmax ,
35
+ .proc_handler = proc_dointvec_minmax ,
66
36
.extra1 = & msg_max_limit_min ,
67
37
.extra2 = & msg_max_limit_max ,
68
38
},
@@ -71,7 +41,7 @@ static struct ctl_table mq_sysctls[] = {
71
41
.data = & init_ipc_ns .mq_msgsize_max ,
72
42
.maxlen = sizeof (int ),
73
43
.mode = 0644 ,
74
- .proc_handler = proc_mq_dointvec_minmax ,
44
+ .proc_handler = proc_dointvec_minmax ,
75
45
.extra1 = & msg_maxsize_limit_min ,
76
46
.extra2 = & msg_maxsize_limit_max ,
77
47
},
@@ -80,7 +50,7 @@ static struct ctl_table mq_sysctls[] = {
80
50
.data = & init_ipc_ns .mq_msg_default ,
81
51
.maxlen = sizeof (int ),
82
52
.mode = 0644 ,
83
- .proc_handler = proc_mq_dointvec_minmax ,
53
+ .proc_handler = proc_dointvec_minmax ,
84
54
.extra1 = & msg_max_limit_min ,
85
55
.extra2 = & msg_max_limit_max ,
86
56
},
@@ -89,32 +59,73 @@ static struct ctl_table mq_sysctls[] = {
89
59
.data = & init_ipc_ns .mq_msgsize_default ,
90
60
.maxlen = sizeof (int ),
91
61
.mode = 0644 ,
92
- .proc_handler = proc_mq_dointvec_minmax ,
62
+ .proc_handler = proc_dointvec_minmax ,
93
63
.extra1 = & msg_maxsize_limit_min ,
94
64
.extra2 = & msg_maxsize_limit_max ,
95
65
},
96
66
{}
97
67
};
98
68
99
- static struct ctl_table mq_sysctl_dir [] = {
100
- {
101
- .procname = "mqueue" ,
102
- .mode = 0555 ,
103
- .child = mq_sysctls ,
104
- },
105
- {}
106
- };
69
+ static struct ctl_table_set * set_lookup (struct ctl_table_root * root )
70
+ {
71
+ return & current -> nsproxy -> ipc_ns -> mq_set ;
72
+ }
107
73
108
- static struct ctl_table mq_sysctl_root [] = {
109
- {
110
- . procname = "fs" ,
111
- . mode = 0555 ,
112
- . child = mq_sysctl_dir ,
113
- },
114
- {}
74
+ static int set_is_seen ( struct ctl_table_set * set )
75
+ {
76
+ return & current -> nsproxy -> ipc_ns -> mq_set == set ;
77
+ }
78
+
79
+ static struct ctl_table_root set_root = {
80
+ . lookup = set_lookup ,
115
81
};
116
82
117
- struct ctl_table_header * mq_register_sysctl_table ( void )
83
+ bool setup_mq_sysctls ( struct ipc_namespace * ns )
118
84
{
119
- return register_sysctl_table (mq_sysctl_root );
85
+ struct ctl_table * tbl ;
86
+
87
+ setup_sysctl_set (& ns -> mq_set , & set_root , set_is_seen );
88
+
89
+ tbl = kmemdup (mq_sysctls , sizeof (mq_sysctls ), GFP_KERNEL );
90
+ if (tbl ) {
91
+ int i ;
92
+
93
+ for (i = 0 ; i < ARRAY_SIZE (mq_sysctls ); i ++ ) {
94
+ if (tbl [i ].data == & init_ipc_ns .mq_queues_max )
95
+ tbl [i ].data = & ns -> mq_queues_max ;
96
+
97
+ else if (tbl [i ].data == & init_ipc_ns .mq_msg_max )
98
+ tbl [i ].data = & ns -> mq_msg_max ;
99
+
100
+ else if (tbl [i ].data == & init_ipc_ns .mq_msgsize_max )
101
+ tbl [i ].data = & ns -> mq_msgsize_max ;
102
+
103
+ else if (tbl [i ].data == & init_ipc_ns .mq_msg_default )
104
+ tbl [i ].data = & ns -> mq_msg_default ;
105
+
106
+ else if (tbl [i ].data == & init_ipc_ns .mq_msgsize_default )
107
+ tbl [i ].data = & ns -> mq_msgsize_default ;
108
+ else
109
+ tbl [i ].data = NULL ;
110
+ }
111
+
112
+ ns -> mq_sysctls = __register_sysctl_table (& ns -> mq_set , "fs/mqueue" , tbl );
113
+ }
114
+ if (!ns -> mq_sysctls ) {
115
+ kfree (tbl );
116
+ retire_sysctl_set (& ns -> mq_set );
117
+ return false;
118
+ }
119
+
120
+ return true;
121
+ }
122
+
123
+ void retire_mq_sysctls (struct ipc_namespace * ns )
124
+ {
125
+ struct ctl_table * tbl ;
126
+
127
+ tbl = ns -> mq_sysctls -> ctl_table_arg ;
128
+ unregister_sysctl_table (ns -> mq_sysctls );
129
+ retire_sysctl_set (& ns -> mq_set );
130
+ kfree (tbl );
120
131
}
0 commit comments