Now exporting the vserver rlimit interface directly, which can be used to
[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 "config.h"
37 #include "compat.h"
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <errno.h>
42 #include <string.h>
43 #include <sys/ioctl.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <fcntl.h>
47 #include <unistd.h>
48 #include <stdint.h>
49
50 #include "vserver.h"
51 #include "vserver-internal.h"
52 #include "sched_cmd.h"
53 #include "virtual.h"
54
55 /*
56  * chcontext
57  */
58 static PyObject *
59 vserver_chcontext(PyObject *self, PyObject *args)
60 {
61   unsigned  xid;
62   unsigned  caps_remove = 0;
63
64   if (!PyArg_ParseTuple(args, "I|I", &xid, &caps_remove))
65     return NULL;
66
67   if (vc_new_s_context(xid, caps_remove, 0) < 0)
68     return PyErr_SetFromErrno(PyExc_OSError);
69
70   return Py_None;
71 }
72
73 static PyObject *
74 vserver_set_rlimit(PyObject *self, PyObject *args) {
75         struct vc_rlimit limits;
76         int xid, resource;
77         PyObject *ret;
78
79         limits.min = VC_LIM_KEEP;
80         limits.soft = VC_LIM_KEEP;
81         limits.hard = VC_LIM_KEEP;
82
83         if (!PyArg_ParseTuple(args, "iiL", &xid, &resource, &limits.hard))
84                 return NULL;
85
86         ret = Py_None;
87         if (vc_set_rlimit(xid, resource, &limits)) 
88                 ret = PyErr_SetFromErrno(PyExc_OSError);
89         else if (vc_get_rlimit(xid, resource, &limits)==-1)
90                 ret = PyErr_SetFromErrno(PyExc_OSError);
91         else
92                 ret = Py_BuildValue("L",limits.hard);
93
94         return ret;
95 }
96
97 static PyObject *
98 vserver_get_rlimit(PyObject *self, PyObject *args) {
99         struct vc_rlimit limits;
100         int xid, resource;
101         PyObject *ret;
102
103         limits.min = VC_LIM_KEEP;
104         limits.soft = VC_LIM_KEEP;
105         limits.hard = VC_LIM_KEEP;
106
107         if (!PyArg_ParseTuple(args, "ii", &xid, &resource))
108                 return NULL;
109
110         ret = Py_None;
111         if (vc_get_rlimit(xid, resource, &limits)==-1)
112                 ret = PyErr_SetFromErrno(PyExc_OSError);
113         else
114                 ret = Py_BuildValue("L",limits.hard);
115
116         return ret;
117 }
118
119 /*
120  * setsched
121  */
122 static PyObject *
123 vserver_setsched(PyObject *self, PyObject *args)
124 {
125   unsigned  xid;
126   struct vc_set_sched sched;
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", &xid, 
134                         &sched.fill_rate,
135                         &sched.interval,
136                         &sched.tokens_min,
137                         &sched.tokens_max))
138     return NULL;
139
140   if (vc_set_sched(xid, &sched) == -1)
141     return PyErr_SetFromErrno(PyExc_OSError);
142
143   return Py_None;
144 }
145
146 /*
147  * setsched
148  */
149
150 /*  inode vserver commands */
151 #define VCMD_add_dlimit         VC_CMD(DLIMIT, 1, 0)
152 #define VCMD_rem_dlimit         VC_CMD(DLIMIT, 2, 0)
153 #define VCMD_set_dlimit         VC_CMD(DLIMIT, 5, 0)
154 #define VCMD_get_dlimit         VC_CMD(DLIMIT, 6, 0)
155
156 struct  vcmd_ctx_dlimit_base_v0 {
157         char *name;
158         uint32_t flags;
159 };
160
161 struct  vcmd_ctx_dlimit_v0 {
162         char *name;
163         uint32_t space_used;                    /* used space in kbytes */
164         uint32_t space_total;                   /* maximum space in kbytes */
165         uint32_t inodes_used;                   /* used inodes */
166         uint32_t inodes_total;                  /* maximum inodes */
167         uint32_t reserved;                      /* reserved for root in % */
168         uint32_t flags;
169 };
170
171 #define CDLIM_UNSET             (0ULL)
172 #define CDLIM_INFINITY          (~0ULL)
173 #define CDLIM_KEEP              (~1ULL)
174
175 static PyObject *
176 vserver_get_dlimit(PyObject *self, PyObject *args)
177 {
178         PyObject *res;
179         char* path;
180         unsigned xid;
181         struct vcmd_ctx_dlimit_v0 data;
182         int r;
183
184         if (!PyArg_ParseTuple(args, "si", &path,&xid))
185                 return NULL;
186
187         memset(&data, 0, sizeof(data));
188         data.name = path;
189         data.flags = 0;
190         r = vserver(VCMD_get_dlimit, xid, &data);
191         if (r>=0) {
192                 res = Py_BuildValue("(i,i,i,i,i)",
193                                     data.space_used,
194                                     data.space_total,
195                                     data.inodes_used,
196                                     data.inodes_total,
197                                     data.reserved);
198         } else {
199                 res = PyErr_SetFromErrno(PyExc_OSError);
200         }
201
202         return res;
203 }
204
205
206 static PyObject *
207 vserver_set_dlimit(PyObject *self, PyObject *args)
208 {
209         char* path;
210         unsigned xid;
211         struct vcmd_ctx_dlimit_base_v0 init;
212         struct vcmd_ctx_dlimit_v0 data;
213         int r;
214
215         memset(&data,0,sizeof(data));
216         if (!PyArg_ParseTuple(args, "siiiiii", &path,
217                               &xid,
218                               &data.space_used,
219                               &data.space_total,
220                               &data.inodes_used,
221                               &data.inodes_total,
222                               &data.reserved))
223                 return NULL;
224
225         data.name = path;
226         data.flags = 0;
227
228         memset(&init, 0, sizeof(init));
229         init.name = path;
230         init.flags = 0;
231
232         r = vserver(VCMD_rem_dlimit, xid, &init);
233         if (r<0){}
234         r = vserver(VCMD_add_dlimit, xid, &init);
235         if (r<0){}
236         r = vserver(VCMD_set_dlimit, xid, &data);
237         if (r<0){}
238         return Py_None; 
239 }
240
241 static PyMethodDef  methods[] = {
242   { "chcontext", vserver_chcontext, METH_VARARGS,
243     "Change to the given vserver context" },
244   { "setsched", vserver_setsched, METH_VARARGS,
245     "Change vserver scheduling attributes for given vserver context" },
246   { "setdlimit", vserver_set_dlimit, METH_VARARGS,
247     "Set disk limits for given vserver context" },
248   { "getdlimit", vserver_get_dlimit, METH_VARARGS,
249     "Get disk limits for given vserver context" },
250   { "setrlimit", vserver_set_rlimit, METH_VARARGS,
251     "Set resource limits for given resource of a vserver context" },
252   { "getrlimit", vserver_get_rlimit, METH_VARARGS,
253     "Get resource limits for given resource of a vserver context" },
254   { NULL, NULL, 0, NULL }
255 };
256
257 PyMODINIT_FUNC
258 initvserverimpl(void)
259 {
260   Py_InitModule("vserverimpl", methods);
261 }