fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / kernel / vserver / sysctl.c
1 /*
2  *  kernel/vserver/sysctl.c
3  *
4  *  Virtual Context Support
5  *
6  *  Copyright (C) 2004-2007  Herbert Pƶtzl
7  *
8  *  V0.01  basic structure
9  *
10  */
11
12 #include <linux/errno.h>
13 #include <linux/module.h>
14 #include <linux/types.h>
15 #include <linux/ctype.h>
16 #include <linux/sysctl.h>
17 #include <linux/parser.h>
18 #include <linux/fs.h>
19
20 #include <asm/uaccess.h>
21 #include <asm/unistd.h>
22
23
24 #define CTL_VSERVER     4242    /* unused? */
25
26 enum {
27         CTL_DEBUG_ERROR         = 0,
28         CTL_DEBUG_SWITCH        = 1,
29         CTL_DEBUG_XID,
30         CTL_DEBUG_NID,
31         CTL_DEBUG_TAG,
32         CTL_DEBUG_NET,
33         CTL_DEBUG_LIMIT,
34         CTL_DEBUG_CRES,
35         CTL_DEBUG_DLIM,
36         CTL_DEBUG_QUOTA,
37         CTL_DEBUG_CVIRT,
38         CTL_DEBUG_MISC,
39 };
40
41
42 unsigned int vx_debug_switch    = 0;
43 unsigned int vx_debug_xid       = 0;
44 unsigned int vx_debug_nid       = 0;
45 unsigned int vx_debug_tag       = 0;
46 unsigned int vx_debug_net       = 0;
47 unsigned int vx_debug_limit     = 0;
48 unsigned int vx_debug_cres      = 0;
49 unsigned int vx_debug_dlim      = 0;
50 unsigned int vx_debug_quota     = 0;
51 unsigned int vx_debug_cvirt     = 0;
52 unsigned int vx_debug_misc      = 0;
53
54
55 static struct ctl_table_header *vserver_table_header;
56 static ctl_table vserver_table[];
57
58
59 void vserver_register_sysctl(void)
60 {
61         if (!vserver_table_header) {
62                 vserver_table_header = register_sysctl_table(vserver_table, 1);
63         }
64
65 }
66
67 void vserver_unregister_sysctl(void)
68 {
69         if (vserver_table_header) {
70                 unregister_sysctl_table(vserver_table_header);
71                 vserver_table_header = NULL;
72         }
73 }
74
75
76 static int proc_dodebug(ctl_table *table, int write,
77         struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
78 {
79         char            tmpbuf[20], *p, c;
80         unsigned int    value;
81         size_t          left, len;
82
83         if ((*ppos && !write) || !*lenp) {
84                 *lenp = 0;
85                 return 0;
86         }
87
88         left = *lenp;
89
90         if (write) {
91                 if (!access_ok(VERIFY_READ, buffer, left))
92                         return -EFAULT;
93                 p = (char *) buffer;
94                 while (left && __get_user(c, p) >= 0 && isspace(c))
95                         left--, p++;
96                 if (!left)
97                         goto done;
98
99                 if (left > sizeof(tmpbuf) - 1)
100                         return -EINVAL;
101                 if (copy_from_user(tmpbuf, p, left))
102                         return -EFAULT;
103                 tmpbuf[left] = '\0';
104
105                 for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--)
106                         value = 10 * value + (*p - '0');
107                 if (*p && !isspace(*p))
108                         return -EINVAL;
109                 while (left && isspace(*p))
110                         left--, p++;
111                 *(unsigned int *) table->data = value;
112         } else {
113                 if (!access_ok(VERIFY_WRITE, buffer, left))
114                         return -EFAULT;
115                 len = sprintf(tmpbuf, "%d", *(unsigned int *) table->data);
116                 if (len > left)
117                         len = left;
118                 if (__copy_to_user(buffer, tmpbuf, len))
119                         return -EFAULT;
120                 if ((left -= len) > 0) {
121                         if (put_user('\n', (char *)buffer + len))
122                                 return -EFAULT;
123                         left--;
124                 }
125         }
126
127 done:
128         *lenp -= left;
129         *ppos += *lenp;
130         return 0;
131 }
132
133
134 #define CTL_ENTRY(ctl, name)                            \
135         {                                               \
136                 .ctl_name       = ctl,                  \
137                 .procname       = #name,                \
138                 .data           = &vx_##name,           \
139                 .maxlen         = sizeof(int),          \
140                 .mode           = 0644,                 \
141                 .proc_handler   = &proc_dodebug         \
142         }
143
144 static ctl_table debug_table[] = {
145         CTL_ENTRY (CTL_DEBUG_SWITCH,    debug_switch),
146         CTL_ENTRY (CTL_DEBUG_XID,       debug_xid),
147         CTL_ENTRY (CTL_DEBUG_NID,       debug_nid),
148         CTL_ENTRY (CTL_DEBUG_TAG,       debug_tag),
149         CTL_ENTRY (CTL_DEBUG_NET,       debug_net),
150         CTL_ENTRY (CTL_DEBUG_LIMIT,     debug_limit),
151         CTL_ENTRY (CTL_DEBUG_CRES,      debug_cres),
152         CTL_ENTRY (CTL_DEBUG_DLIM,      debug_dlim),
153         CTL_ENTRY (CTL_DEBUG_QUOTA,     debug_quota),
154         CTL_ENTRY (CTL_DEBUG_CVIRT,     debug_cvirt),
155         CTL_ENTRY (CTL_DEBUG_MISC,      debug_misc),
156         { .ctl_name = 0 }
157 };
158
159 static ctl_table vserver_table[] = {
160         {
161                 .ctl_name       = CTL_VSERVER,
162                 .procname       = "vserver",
163                 .mode           = 0555,
164                 .child          = debug_table
165         },
166         { .ctl_name = 0 }
167 };
168
169
170 static match_table_t tokens = {
171         { CTL_DEBUG_SWITCH,     "switch=%x"     },
172         { CTL_DEBUG_XID,        "xid=%x"        },
173         { CTL_DEBUG_NID,        "nid=%x"        },
174         { CTL_DEBUG_TAG,        "tag=%x"        },
175         { CTL_DEBUG_NET,        "net=%x"        },
176         { CTL_DEBUG_LIMIT,      "limit=%x"      },
177         { CTL_DEBUG_CRES,       "cres=%x"       },
178         { CTL_DEBUG_DLIM,       "dlim=%x"       },
179         { CTL_DEBUG_QUOTA,      "quota=%x"      },
180         { CTL_DEBUG_CVIRT,      "cvirt=%x"      },
181         { CTL_DEBUG_MISC,       "misc=%x"       },
182         { CTL_DEBUG_ERROR,      NULL            }
183 };
184
185 #define HANDLE_CASE(id, name, val)                              \
186         case CTL_DEBUG_ ## id:                                  \
187                 vx_debug_ ## name = val;                        \
188                 printk("vs_debug_" #name "=0x%x\n", val);       \
189                 break
190
191
192 static int __init vs_debug_setup(char *str)
193 {
194         char *p;
195         int token;
196
197         printk("vs_debug_setup(%s)\n", str);
198         while ((p = strsep(&str, ",")) != NULL) {
199                 substring_t args[MAX_OPT_ARGS];
200                 unsigned int value;
201
202                 if (!*p)
203                         continue;
204
205                 token = match_token(p, tokens, args);
206                 value = (token>0)?simple_strtoul(args[0].from, NULL, 0):0;
207
208                 switch (token) {
209                 HANDLE_CASE(SWITCH, switch, value);
210                 HANDLE_CASE(XID,    xid,    value);
211                 HANDLE_CASE(NID,    nid,    value);
212                 HANDLE_CASE(TAG,    tag,    value);
213                 HANDLE_CASE(NET,    net,    value);
214                 HANDLE_CASE(LIMIT,  limit,  value);
215                 HANDLE_CASE(CRES,   cres,   value);
216                 HANDLE_CASE(DLIM,   dlim,   value);
217                 HANDLE_CASE(QUOTA,  quota,  value);
218                 HANDLE_CASE(CVIRT,  cvirt,  value);
219                 HANDLE_CASE(MISC,   misc,   value);
220                 default:
221                         return -EINVAL;
222                         break;
223                 }
224         }
225         return 1;
226 }
227
228 __setup("vsdebug=", vs_debug_setup);
229
230
231
232 EXPORT_SYMBOL_GPL(vx_debug_switch);
233 EXPORT_SYMBOL_GPL(vx_debug_xid);
234 EXPORT_SYMBOL_GPL(vx_debug_nid);
235 EXPORT_SYMBOL_GPL(vx_debug_net);
236 EXPORT_SYMBOL_GPL(vx_debug_limit);
237 EXPORT_SYMBOL_GPL(vx_debug_cres);
238 EXPORT_SYMBOL_GPL(vx_debug_dlim);
239 EXPORT_SYMBOL_GPL(vx_debug_quota);
240 EXPORT_SYMBOL_GPL(vx_debug_cvirt);
241 EXPORT_SYMBOL_GPL(vx_debug_misc);
242