Oops, don't limit slices to 4 processes
[util-vserver.git] / python / vserverimpl.c
1 /* Copyright 2005 Princeton University
2
3 Redistribution and use in source and binary forms, with or without
4 modification, are permitted provided that the following conditions
5 are met: 
6
7     * Redistributions of source code must retain the above copyright
8       notice, this list of conditions and the following disclaimer.
9       
10     * Redistributions in binary form must reproduce the above
11       copyright notice, this list of conditions and the following
12       disclaimer in the documentation and/or other materials provided
13       with the distribution.
14       
15     * Neither the name of the copyright holder nor the names of its
16       contributors may be used to endorse or promote products derived
17       from this software without specific prior written permission.
18       
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PRINCETON
23 UNIVERSITY OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27 AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
29 WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE. 
31
32 */
33
34 #include <Python.h>
35
36 #include <errno.h>
37 #include <stdint.h>
38 #include <unistd.h>
39
40 #include "config.h"
41 #include "pathconfig.h"
42 #include "planetlab.h"
43 #include "virtual.h"
44 #include "vserver.h"
45 #include "vserver-internal.h"
46
47 /*
48  * context create
49  */
50 static PyObject *
51 vserver_chcontext(PyObject *self, PyObject *args)
52 {
53   xid_t  ctx;
54   uint32_t  flags = 0;
55   uint32_t  bcaps = ~vc_get_insecurebcaps();
56   /* XXX - use appropriate resource values here */
57   rspec_t  rspec = { 32, VC_VXF_SCHED_FLAGS, -1, -1 };
58
59   if (!PyArg_ParseTuple(args, "I|K", &ctx, &flags))
60     return NULL;
61
62   if (pl_chcontext(ctx, flags, bcaps, &rspec))
63     PyErr_SetFromErrno(PyExc_OSError);
64
65   return Py_None;
66 }
67
68 static PyObject *
69 vserver_set_rlimit(PyObject *self, PyObject *args) {
70         struct vc_rlimit limits;
71         xid_t xid;
72         int resource;
73         PyObject *ret;
74
75         limits.min = VC_LIM_KEEP;
76         limits.soft = VC_LIM_KEEP;
77         limits.hard = VC_LIM_KEEP;
78
79         if (!PyArg_ParseTuple(args, "IiL", &xid, &resource, &limits.hard))
80                 return NULL;
81
82         ret = Py_None;
83         if (vc_set_rlimit(xid, resource, &limits)) 
84                 ret = PyErr_SetFromErrno(PyExc_OSError);
85         else if (vc_get_rlimit(xid, resource, &limits)==-1)
86                 ret = PyErr_SetFromErrno(PyExc_OSError);
87         else
88                 ret = Py_BuildValue("L",limits.hard);
89
90         return ret;
91 }
92
93 static PyObject *
94 vserver_get_rlimit(PyObject *self, PyObject *args) {
95         struct vc_rlimit limits;
96         xid_t xid;
97         int resource;
98         PyObject *ret;
99
100         limits.min = VC_LIM_KEEP;
101         limits.soft = VC_LIM_KEEP;
102         limits.hard = VC_LIM_KEEP;
103
104         if (!PyArg_ParseTuple(args, "Ii", &xid, &resource))
105                 return NULL;
106
107         ret = Py_None;
108         if (vc_get_rlimit(xid, resource, &limits)==-1)
109                 ret = PyErr_SetFromErrno(PyExc_OSError);
110         else
111                 ret = Py_BuildValue("L",limits.hard);
112
113         return ret;
114 }
115
116 #if 0
117 /*
118  * setsched
119  */
120 static PyObject *
121 vserver_setsched(PyObject *self, PyObject *args)
122 {
123   xid_t  xid;
124   struct vc_set_sched sched;
125   struct vc_ctx_flags flags;
126   unsigned cpuguaranteed = 0;
127
128   sched.set_mask = (VC_VXSM_FILL_RATE | 
129                     VC_VXSM_INTERVAL | 
130                     VC_VXSM_TOKENS_MIN | 
131                     VC_VXSM_TOKENS_MAX);
132
133   if (!PyArg_ParseTuple(args, "I|I|I|I|I|I|I", &xid, 
134                         &sched.fill_rate,
135                         &sched.interval,
136                         &sched.tokens,
137                         &sched.tokens_min,
138                         &sched.tokens_max,
139                         &cpuguaranteed))
140     return NULL;
141
142   flags.flagword = VC_VXF_SCHED_HARD;
143   flags.mask |= VC_VXF_SCHED_HARD;
144 #define VC_VXF_SCHED_SHARE       0x00000800ull
145   if (cpuguaranteed==0) {
146           flags.flagword |= VC_VXF_SCHED_SHARE;
147           flags.mask |= VC_VXF_SCHED_SHARE;
148   }
149
150   if (vc_set_cflags(xid, &flags) == -1)
151           return PyErr_SetFromErrno(PyExc_OSError);
152
153   if (vc_set_sched(xid, &sched) == -1)
154           return PyErr_SetFromErrno(PyExc_OSError);
155
156   return Py_None;
157 }
158
159 /*
160  * setsched
161  */
162 #endif
163
164 static PyObject *
165 vserver_get_dlimit(PyObject *self, PyObject *args)
166 {
167         PyObject *res;
168         char* path;
169         unsigned xid;
170         struct vcmd_ctx_dlimit_v0 data;
171         int r;
172
173         if (!PyArg_ParseTuple(args, "si", &path,&xid))
174                 return NULL;
175
176         memset(&data, 0, sizeof(data));
177         data.name = path;
178         data.flags = 0;
179         r = vserver(VCMD_get_dlimit, xid, &data);
180         if (r>=0) {
181                 res = Py_BuildValue("(i,i,i,i,i)",
182                                     data.space_used,
183                                     data.space_total,
184                                     data.inodes_used,
185                                     data.inodes_total,
186                                     data.reserved);
187         } else {
188                 res = PyErr_SetFromErrno(PyExc_OSError);
189         }
190
191         return res;
192 }
193
194
195 static PyObject *
196 vserver_set_dlimit(PyObject *self, PyObject *args)
197 {
198         char* path;
199         unsigned xid;
200         struct vcmd_ctx_dlimit_base_v0 init;
201         struct vcmd_ctx_dlimit_v0 data;
202
203         memset(&data,0,sizeof(data));
204         if (!PyArg_ParseTuple(args, "siiiiii", &path,
205                               &xid,
206                               &data.space_used,
207                               &data.space_total,
208                               &data.inodes_used,
209                               &data.inodes_total,
210                               &data.reserved))
211                 return NULL;
212
213         data.name = path;
214         data.flags = 0;
215
216         memset(&init, 0, sizeof(init));
217         init.name = path;
218         init.flags = 0;
219
220         if ((vserver(VCMD_add_dlimit, xid, &init) && errno != EEXIST) ||
221             vserver(VCMD_set_dlimit, xid, &data))
222           return PyErr_SetFromErrno(PyExc_OSError);
223
224         return Py_None; 
225 }
226
227 static PyMethodDef  methods[] = {
228   { "chcontext", vserver_chcontext, METH_VARARGS,
229     "chcontext to vserver with provided flags" },
230 #if 0
231   { "setsched", vserver_setsched, METH_VARARGS,
232     "Change vserver scheduling attributes for given vserver context" },
233 #endif
234   { "setdlimit", vserver_set_dlimit, METH_VARARGS,
235     "Set disk limits for given vserver context" },
236   { "getdlimit", vserver_get_dlimit, METH_VARARGS,
237     "Get disk limits for given vserver context" },
238   { "setrlimit", vserver_set_rlimit, METH_VARARGS,
239     "Set resource limits for given resource of a vserver context" },
240   { "getrlimit", vserver_get_rlimit, METH_VARARGS,
241     "Get resource limits for given resource of a vserver context" },
242   { NULL, NULL, 0, NULL }
243 };
244
245 PyMODINIT_FUNC
246 initvserverimpl(void)
247 {
248   PyObject  *mod;
249
250   mod = Py_InitModule("vserverimpl", methods);
251
252   /* export the set of 'safe' capabilities */
253   PyModule_AddIntConstant(mod, "CAP_SAFE", ~vc_get_insecurebcaps());
254
255   /* export the default vserver directory */
256   PyModule_AddStringConstant(mod, "VSERVER_BASEDIR", DEFAULT_VSERVERDIR);
257
258   /* export limit-related constants */
259   PyModule_AddIntConstant(mod, "DLIMIT_KEEP", (int)CDLIM_KEEP);
260   PyModule_AddIntConstant(mod, "DLIMIT_INF", (int)CDLIM_INFINITY);
261 }