vshost-util-vserver

Build script and sources for util-vserver.
git clone https://ccx.te2000.cz/git/vshost-util-vserver
Log | Files | Refs

_libvserver.c (30552B)


      1 /* $Id$
      2  * Copyright (C) 2008 Daniel Hokka Zakrisson
      3  * 
      4  * This program is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU General Public License
      6  * as published by the Free Software Foundation; either version 2
      7  * of the License, or (at your option) any later version.
      8  * 
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12  * GNU General Public License for more details.
     13  * 
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program; if not, write to the Free Software
     16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     17  * 
     18  * vim:set ts=2 sw=2 expandtab:
     19  */
     20 
     21 #include <stdint.h>
     22 #include <stdlib.h>
     23 #include <unistd.h>
     24 #include <sys/types.h>
     25 #include <sys/socket.h>
     26 #include <arpa/inet.h>
     27 #include <Python.h>
     28 
     29 #ifdef HAVE_CONFIG_H
     30 #include "config.h"
     31 #endif
     32 #include "compat.h"
     33 #include "vserver.h"
     34 
     35 static inline PyObject *NONE(void)
     36 {
     37   Py_INCREF(Py_None);
     38   return Py_None;
     39 }
     40 
     41 static PyObject *
     42 pyvserver_get_version(PyObject UNUSED *self, PyObject UNUSED *args)
     43 {
     44   int ver = vc_get_version();
     45   if (ver == -1)
     46     return PyErr_SetFromErrno(PyExc_OSError);
     47 
     48   return Py_BuildValue("i", ver);
     49 }
     50 
     51 static PyObject *
     52 pyvserver_get_vci(PyObject UNUSED *self, PyObject UNUSED *args)
     53 {
     54   vc_vci_t vci = vc_get_vci();
     55   if (vci == (vc_vci_t)-1)
     56     return PyErr_SetFromErrno(PyExc_OSError);
     57 
     58   return Py_BuildValue("K", vci);
     59 }
     60 
     61 static PyObject *
     62 pyvserver_ctx_create(PyObject UNUSED *self, PyObject *args)
     63 {
     64   xid_t xid, ret;
     65   struct vc_ctx_flags flags = { .mask = 0 };
     66 
     67   if (!PyArg_ParseTuple(args, "I|KK", &xid, &flags.flagword, &flags.mask))
     68     return NULL;
     69 
     70   if (flags.flagword && !flags.mask)
     71     flags.mask = flags.flagword;
     72 
     73   ret = vc_ctx_create(xid, &flags);
     74   if (ret == VC_NOXID)
     75     return PyErr_SetFromErrno(PyExc_OSError);
     76 
     77   return Py_BuildValue("I", ret);
     78 }
     79 
     80 static PyObject *
     81 pyvserver_ctx_migrate(PyObject UNUSED *self, PyObject *args)
     82 {
     83   xid_t xid;
     84   uint_least64_t flags;
     85 
     86   if (!PyArg_ParseTuple(args, "IK", &xid, &flags))
     87     return NULL;
     88 
     89   if (vc_ctx_migrate(xid, flags) == -1)
     90     return PyErr_SetFromErrno(PyExc_OSError);
     91 
     92   return NONE();
     93 }
     94 
     95 static PyObject *
     96 pyvserver_ctx_stat(PyObject UNUSED *self, PyObject *args)
     97 {
     98   xid_t xid;
     99   struct vc_ctx_stat stats;
    100 
    101   if (!PyArg_ParseTuple(args, "I", &xid))
    102     return NULL;
    103 
    104   if (vc_ctx_stat(xid, &stats) == -1)
    105     return PyErr_SetFromErrno(PyExc_OSError);
    106 
    107   return Py_BuildValue("(II)", stats.usecnt, stats.tasks);
    108 }
    109 
    110 static PyObject *
    111 pyvserver_virt_stat(PyObject UNUSED *self, PyObject *args)
    112 {
    113   xid_t xid;
    114   struct vc_virt_stat stats;
    115 
    116   if (!PyArg_ParseTuple(args, "I", &xid))
    117     return NULL;
    118 
    119   if (vc_virt_stat(xid, &stats) == -1)
    120     return PyErr_SetFromErrno(PyExc_OSError);
    121 
    122   return Py_BuildValue("(KKIIIIIIII)", stats.offset, stats.uptime,
    123                        stats.nr_threads, stats.nr_running,
    124                        stats.nr_uninterruptible, stats.nr_onhold,
    125                        stats.nr_forks, stats.load[0], stats.load[1],
    126                        stats.load[2]);
    127 }
    128 
    129 static PyObject *
    130 pyvserver_ctx_kill(PyObject UNUSED *self, PyObject *args)
    131 {
    132   xid_t xid;
    133   pid_t pid;
    134   int signal;
    135 
    136   if (!PyArg_ParseTuple(args, "Iii", &xid, &pid, &signal))
    137     return NULL;
    138 
    139   if (vc_ctx_kill(xid, pid, signal) == -1)
    140     return PyErr_SetFromErrno(PyExc_OSError);
    141 
    142   return NONE();
    143 }
    144 
    145 static PyObject *
    146 pyvserver_get_cflags(PyObject UNUSED *self, PyObject *args)
    147 {
    148   xid_t xid;
    149   struct vc_ctx_flags flags;
    150 
    151   if (!PyArg_ParseTuple(args, "I", &xid))
    152     return NULL;
    153 
    154   if (vc_get_cflags(xid, &flags) == -1)
    155     return PyErr_SetFromErrno(PyExc_OSError);
    156 
    157   return Py_BuildValue("(KK)", flags.flagword, flags.mask);
    158 }
    159 
    160 static PyObject *
    161 pyvserver_set_cflags(PyObject UNUSED *self, PyObject *args)
    162 {
    163   xid_t xid;
    164   struct vc_ctx_flags flags;
    165 
    166   if (!PyArg_ParseTuple(args, "I(KK)", &xid, &flags.flagword, &flags.mask))
    167     return NULL;
    168 
    169   if (vc_set_cflags(xid, &flags) == -1)
    170     return PyErr_SetFromErrno(PyExc_OSError);
    171 
    172   return NONE();
    173 }
    174 
    175 static PyObject *
    176 pyvserver_get_ccaps(PyObject UNUSED *self, PyObject *args)
    177 {
    178   xid_t xid;
    179   struct vc_ctx_caps caps;
    180 
    181   if (!PyArg_ParseTuple(args, "I", &xid))
    182     return NULL;
    183 
    184   if (vc_get_ccaps(xid, &caps) == -1)
    185     return PyErr_SetFromErrno(PyExc_OSError);
    186 
    187   return Py_BuildValue("(KKKK)", caps.bcaps, caps.bmask, caps.ccaps,
    188                        caps.cmask);
    189 }
    190 
    191 static PyObject *
    192 pyvserver_set_ccaps(PyObject UNUSED *self, PyObject *args)
    193 {
    194   xid_t xid;
    195   struct vc_ctx_caps caps;
    196 
    197   if (!PyArg_ParseTuple(args, "I(KKKK)", &xid, &caps.bcaps, &caps.bmask,
    198                         &caps.ccaps, &caps.cmask))
    199     return NULL;
    200 
    201   if (vc_set_ccaps(xid, &caps) == -1)
    202     return PyErr_SetFromErrno(PyExc_OSError);
    203 
    204   return NONE();
    205 }
    206 
    207 static PyObject *
    208 pyvserver_get_vx_info(PyObject UNUSED *self, PyObject *args)
    209 {
    210   xid_t xid;
    211   struct vc_vx_info info;
    212 
    213   if (!PyArg_ParseTuple(args, "I", &xid))
    214     return NULL;
    215 
    216   if (vc_get_vx_info(xid, &info) == -1)
    217     return PyErr_SetFromErrno(PyExc_OSError);
    218 
    219   return Py_BuildValue("(Ii)", info.xid, info.initpid);
    220 }
    221 
    222 static PyObject *
    223 pyvserver_get_task_xid(PyObject UNUSED *self, PyObject *args)
    224 {
    225   pid_t pid;
    226   xid_t xid;
    227 
    228   if (!PyArg_ParseTuple(args, "i", &pid))
    229     return NULL;
    230 
    231   xid = vc_get_task_xid(pid);
    232   if (xid == VC_NOXID)
    233     return PyErr_SetFromErrno(PyExc_OSError);
    234 
    235   return Py_BuildValue("I", xid);
    236 }
    237 
    238 static PyObject *
    239 pyvserver_wait_exit(PyObject UNUSED *self, PyObject *args)
    240 {
    241   xid_t xid;
    242 
    243   if (!PyArg_ParseTuple(args, "I", &xid))
    244     return NULL;
    245 
    246   if (vc_wait_exit(xid) == -1)
    247     Py_RETURN_FALSE;
    248   else
    249     Py_RETURN_TRUE;
    250 }
    251 
    252 static PyObject *
    253 pyvserver_get_rlimit_mask(PyObject UNUSED *self, PyObject *args)
    254 {
    255   xid_t xid;
    256   struct vc_rlimit_mask mask;
    257 
    258   if (!PyArg_ParseTuple(args, "I", &xid))
    259     return NULL;
    260 
    261   if (vc_get_rlimit_mask(xid, &mask) == -1)
    262     return PyErr_SetFromErrno(PyExc_OSError);
    263 
    264   return Py_BuildValue("(III)", mask.min, mask.soft, mask.hard);
    265 }
    266 
    267 static PyObject *
    268 pyvserver_get_rlimit(PyObject UNUSED *self, PyObject *args)
    269 {
    270   xid_t xid;
    271   int resource;
    272   struct vc_rlimit limit = { .min = 0 };
    273 
    274   if (!PyArg_ParseTuple(args, "Ii", &xid, &resource))
    275     return NULL;
    276 
    277   if (vc_get_rlimit(xid, resource, &limit) == -1)
    278     return PyErr_SetFromErrno(PyExc_OSError);
    279 
    280   return Py_BuildValue("(LLL)", limit.min, limit.soft, limit.hard);
    281 }
    282 
    283 static PyObject *
    284 pyvserver_set_rlimit(PyObject UNUSED *self, PyObject *args)
    285 {
    286   xid_t xid;
    287   int resource;
    288   struct vc_rlimit limit = {
    289     .min = VC_LIM_KEEP,
    290     .soft = VC_LIM_KEEP,
    291     .hard = VC_LIM_KEEP
    292   };
    293 
    294   if (!PyArg_ParseTuple(args, "Ii(KKK)", &xid, &resource, &limit.min,
    295                         &limit.soft, &limit.hard))
    296     return NULL;
    297 
    298   if (vc_set_rlimit(xid, resource, &limit) == -1)
    299     return PyErr_SetFromErrno(PyExc_OSError);
    300 
    301   return NONE();
    302 }
    303 
    304 static PyObject *
    305 pyvserver_rlimit_stat(PyObject UNUSED *self, PyObject *args)
    306 {
    307   xid_t xid;
    308   int resource;
    309   struct vc_rlimit_stat stats;
    310 
    311   if (!PyArg_ParseTuple(args, "Ii", &xid, &resource))
    312     return NULL;
    313 
    314   if (vc_rlimit_stat(xid, resource, &stats) == -1)
    315     return PyErr_SetFromErrno(PyExc_OSError);
    316 
    317   return Py_BuildValue("(IKKK)", stats.hits, stats.value, stats.minimum,
    318                        stats.maximum);
    319 }
    320 
    321 static PyObject *
    322 pyvserver_reset_minmax(PyObject UNUSED *self, PyObject *args)
    323 {
    324   xid_t xid;
    325 
    326   if (!PyArg_ParseTuple(args, "I", &xid))
    327     return NULL;
    328 
    329   if (vc_reset_minmax(xid) == -1)
    330     return PyErr_SetFromErrno(PyExc_OSError);
    331 
    332   return NONE();
    333 }
    334 
    335 static PyObject *
    336 pyvserver_get_task_nid(PyObject UNUSED *self, PyObject *args)
    337 {
    338   pid_t pid;
    339   nid_t nid;
    340 
    341   if (!PyArg_ParseTuple(args, "i", &pid))
    342     return NULL;
    343 
    344   nid = vc_get_task_nid(pid);
    345   if (nid == VC_NONID)
    346     return PyErr_SetFromErrno(PyExc_OSError);
    347 
    348   return Py_BuildValue("I", nid);
    349 }
    350 
    351 static PyObject *
    352 pyvserver_get_nx_info(PyObject UNUSED *self, PyObject *args)
    353 {
    354   nid_t nid;
    355   struct vc_nx_info info;
    356 
    357   if (!PyArg_ParseTuple(args, "I", &nid))
    358     return NULL;
    359 
    360   if (vc_get_nx_info(nid, &info) == -1)
    361     return PyErr_SetFromErrno(PyExc_OSError);
    362 
    363   return Py_BuildValue("(I)", info.nid);
    364 }
    365 
    366 static PyObject *
    367 pyvserver_net_create(PyObject UNUSED *self, PyObject *args)
    368 {
    369   nid_t nid, ret;
    370 
    371   if (!PyArg_ParseTuple(args, "I", &nid))
    372     return NULL;
    373 
    374   ret = vc_net_create(nid);
    375   if (ret == VC_NONID)
    376     return PyErr_SetFromErrno(PyExc_OSError);
    377 
    378   return Py_BuildValue("I", ret);
    379 }
    380 
    381 static PyObject *
    382 pyvserver_net_migrate(PyObject UNUSED *self, PyObject *args)
    383 {
    384   nid_t nid;
    385 
    386   if (!PyArg_ParseTuple(args, "I", &nid))
    387     return NULL;
    388 
    389   if (vc_net_migrate(nid) == -1)
    390     return PyErr_SetFromErrno(PyExc_OSError);
    391 
    392   return NONE();
    393 }
    394 
    395 static PyObject *
    396 pyvserver_net_handle(PyObject UNUSED *self, PyObject *args,
    397                       int (*func)(nid_t nid, struct vc_net_addr const *addr))
    398 {
    399   nid_t nid;
    400   struct vc_net_addr addr;
    401   char *ip1, *ip2, *mask;
    402 
    403   if (!PyArg_ParseTuple(args, "I(HHHHsss)", &nid, &addr.vna_type,
    404                         &addr.vna_flags, &addr.vna_prefix, &addr.vna_parent,
    405                         &ip1, &ip2, &mask))
    406     return NULL;
    407 
    408   if (addr.vna_type & VC_NXA_TYPE_IPV6) {
    409     if (inet_pton(AF_INET6, ip1, &addr.vna_v6_ip) <= 0 ||
    410         inet_pton(AF_INET6, ip2, &addr.vna_v6_ip2) <= 0 ||
    411         inet_pton(AF_INET6, mask, &addr.vna_v6_mask) <= 0) {
    412       PyErr_SetString(PyExc_ValueError, "invalid IPv6 addresses");
    413       return NULL;
    414     }
    415   }
    416   else if (addr.vna_type & VC_NXA_TYPE_IPV4) {
    417     if (inet_pton(AF_INET, ip1, &addr.vna_v4_ip) <= 0 ||
    418         inet_pton(AF_INET, ip2, &addr.vna_v4_ip2) <= 0 ||
    419         inet_pton(AF_INET, mask, &addr.vna_v4_mask) <= 0) {
    420       PyErr_SetString(PyExc_ValueError, "invalid IPv4 addresses");
    421       return NULL;
    422     }
    423   }
    424   else if (addr.vna_type != VC_NXA_TYPE_ANY) {
    425     PyErr_SetString(PyExc_ValueError, "type");
    426     return NULL;
    427   }
    428 
    429   if (func(nid, &addr) == -1)
    430     return PyErr_SetFromErrno(PyExc_OSError);
    431 
    432   return NONE();
    433 }
    434 
    435 static PyObject *
    436 pyvserver_net_add(PyObject UNUSED *self, PyObject *args)
    437 {
    438   return pyvserver_net_handle(self, args, vc_net_add);
    439 }
    440 
    441 static PyObject *
    442 pyvserver_net_remove(PyObject UNUSED *self, PyObject *args)
    443 {
    444   return pyvserver_net_handle(self, args, vc_net_remove);
    445 }
    446 
    447 static PyObject *
    448 pyvserver_get_nflags(PyObject UNUSED *self, PyObject *args)
    449 {
    450   nid_t nid;
    451   struct vc_net_flags flags;
    452 
    453   if (!PyArg_ParseTuple(args, "I", &nid))
    454     return NULL;
    455 
    456   if (vc_get_nflags(nid, &flags) == -1)
    457     return PyErr_SetFromErrno(PyExc_OSError);
    458 
    459   return Py_BuildValue("(KK)", flags.flagword, flags.mask);
    460 }
    461 
    462 static PyObject *
    463 pyvserver_set_nflags(PyObject UNUSED *self, PyObject *args)
    464 {
    465   nid_t nid;
    466   struct vc_net_flags flags;
    467 
    468   if (!PyArg_ParseTuple(args, "I(KK)", &nid, &flags.flagword, &flags.mask))
    469     return NULL;
    470 
    471   if (vc_set_nflags(nid, &flags) == -1)
    472     return PyErr_SetFromErrno(PyExc_OSError);
    473 
    474   return NONE();
    475 }
    476 
    477 static PyObject *
    478 pyvserver_get_ncaps(PyObject UNUSED *self, PyObject *args)
    479 {
    480   nid_t nid;
    481   struct vc_net_caps caps;
    482 
    483   if (!PyArg_ParseTuple(args, "I", &nid))
    484     return NULL;
    485 
    486   if (vc_get_ncaps(nid, &caps) == -1)
    487     return PyErr_SetFromErrno(PyExc_OSError);
    488 
    489   return Py_BuildValue("(KK)", caps.ncaps, caps.cmask);
    490 }
    491 
    492 static PyObject *
    493 pyvserver_set_ncaps(PyObject UNUSED *self, PyObject *args)
    494 {
    495   nid_t nid;
    496   struct vc_net_caps caps;
    497 
    498   if (!PyArg_ParseTuple(args, "I(KK)", &nid, &caps.ncaps, &caps.cmask))
    499     return NULL;
    500 
    501   if (vc_set_ncaps(nid, &caps) == -1)
    502     return PyErr_SetFromErrno(PyExc_OSError);
    503 
    504   return NONE();
    505 }
    506 
    507 static PyObject *
    508 pyvserver_set_iattr(PyObject UNUSED *self, PyObject *args)
    509 {
    510   char const *filename;
    511   tag_t tag;
    512   uint_least32_t flags, mask;
    513 
    514   if (!PyArg_ParseTuple(args, "sIII", &filename, &tag, &flags, &mask))
    515     return NULL;
    516 
    517   if (vc_set_iattr(filename, tag, flags, mask) == -1)
    518     return PyErr_SetFromErrno(PyExc_OSError);
    519 
    520   return NONE();
    521 }
    522 
    523 static PyObject *
    524 pyvserver_fset_iattr(PyObject UNUSED *self, PyObject *args)
    525 {
    526   int fd;
    527   tag_t tag;
    528   uint_least32_t flags, mask;
    529 
    530   if (!PyArg_ParseTuple(args, "iIII", &fd, &tag, &flags, &mask))
    531     return NULL;
    532 
    533   if (vc_fset_iattr(fd, tag, flags, mask) == -1)
    534     return PyErr_SetFromErrno(PyExc_OSError);
    535 
    536   return NONE();
    537 }
    538 
    539 static PyObject *
    540 pyvserver_get_iattr(PyObject UNUSED *self, PyObject *args)
    541 {
    542   char const *filename;
    543   tag_t tag;
    544   uint_least32_t flags, mask;
    545 
    546   if (!PyArg_ParseTuple(args, "sI", &filename, &mask))
    547     return NULL;
    548 
    549   if (vc_get_iattr(filename, &tag, &flags, &mask) == -1)
    550     return PyErr_SetFromErrno(PyExc_OSError);
    551 
    552   return Py_BuildValue("(III)", tag, flags, mask);
    553 }
    554 
    555 static PyObject *
    556 pyvserver_fget_iattr(PyObject UNUSED *self, PyObject *args)
    557 {
    558   int fd;
    559   tag_t tag;
    560   uint_least32_t flags, mask;
    561 
    562   if (!PyArg_ParseTuple(args, "iI", &fd, &mask))
    563     return NULL;
    564 
    565   if (vc_fget_iattr(fd, &tag, &flags, &mask) == -1)
    566     return PyErr_SetFromErrno(PyExc_OSError);
    567 
    568   return Py_BuildValue("(III)", tag, flags, mask);
    569 }
    570 
    571 static PyObject *
    572 pyvserver_set_vhi_name(PyObject UNUSED *self, PyObject *args)
    573 {
    574   xid_t xid;
    575   vc_uts_type type;
    576   char const *val;
    577   int len;
    578 
    579   if (!PyArg_ParseTuple(args, "Iis#", &xid, &type, &val, &len))
    580     return NULL;
    581 
    582   if (vc_set_vhi_name(xid, type, val, len) == -1)
    583     return PyErr_SetFromErrno(PyExc_OSError);
    584 
    585   return NONE();
    586 }
    587 
    588 static PyObject *
    589 pyvserver_get_vhi_name(PyObject UNUSED *self, PyObject *args)
    590 {
    591   xid_t xid;
    592   vc_uts_type type;
    593   char val[65];
    594   int i;
    595 
    596   if (!PyArg_ParseTuple(args, "Ii", &xid, &type))
    597     return NULL;
    598 
    599   if (vc_get_vhi_name(xid, type, val, sizeof(val)) == -1)
    600     return PyErr_SetFromErrno(PyExc_OSError);
    601 
    602   for (i = sizeof(val); i > 0 && val[i - 1] == '\0'; i--)
    603     ;
    604 
    605   return Py_BuildValue("s#", val, i);
    606 }
    607 
    608 static PyObject *
    609 pyvserver_enter_namespace(PyObject UNUSED *self, PyObject *args)
    610 {
    611   xid_t xid;
    612   uint_least64_t mask;
    613   uint32_t index;
    614 
    615   if (!PyArg_ParseTuple(args, "IKI", &xid, &mask, &index))
    616     return NULL;
    617 
    618   if (vc_enter_namespace(xid, mask, index) == -1)
    619     return PyErr_SetFromErrno(PyExc_OSError);
    620 
    621   return NONE();
    622 }
    623 
    624 static PyObject *
    625 pyvserver_set_namespace(PyObject UNUSED *self, PyObject *args)
    626 {
    627   xid_t xid;
    628   uint_least64_t mask;
    629   uint32_t index;
    630 
    631   if (!PyArg_ParseTuple(args, "IKI", &xid, &mask, &index))
    632     return NULL;
    633 
    634   if (vc_set_namespace(xid, mask, index) == -1)
    635     return PyErr_SetFromErrno(PyExc_OSError);
    636 
    637   return NONE();
    638 }
    639 
    640 static PyObject *
    641 pyvserver_get_space_mask(PyObject UNUSED *self, PyObject UNUSED *args)
    642 {
    643   uint_least64_t mask = vc_get_space_mask();
    644   return Py_BuildValue("K", mask);
    645 }
    646 
    647 static PyObject *
    648 pyvserver_get_space_default(PyObject UNUSED *self, PyObject UNUSED *args)
    649 {
    650   uint_least64_t mask = vc_get_space_default();
    651   return Py_BuildValue("K", mask);
    652 }
    653 
    654 static PyObject *
    655 pyvserver_add_dlimit(PyObject UNUSED *self, PyObject *args)
    656 {
    657   char const *filename;
    658   tag_t tag;
    659   uint_least32_t flags;
    660 
    661   if (!PyArg_ParseTuple(args, "sII", &filename, &tag, &flags))
    662     return NULL;
    663 
    664   if (vc_add_dlimit(filename, tag, flags) == -1)
    665     return PyErr_SetFromErrno(PyExc_OSError);
    666 
    667   return NONE();
    668 }
    669 
    670 static PyObject *
    671 pyvserver_rem_dlimit(PyObject UNUSED *self, PyObject *args)
    672 {
    673   char const *filename;
    674   tag_t tag;
    675   uint_least32_t flags;
    676 
    677   if (!PyArg_ParseTuple(args, "sII", &filename, &tag, &flags))
    678     return NULL;
    679 
    680   if (vc_rem_dlimit(filename, tag, flags) == -1)
    681     return PyErr_SetFromErrno(PyExc_OSError);
    682 
    683   return NONE();
    684 }
    685 
    686 static PyObject *
    687 pyvserver_set_dlimit(PyObject UNUSED *self, PyObject *args)
    688 {
    689   char const *filename;
    690   tag_t tag;
    691   uint_least32_t flags;
    692   struct vc_ctx_dlimit limit;
    693 
    694   if (!PyArg_ParseTuple(args, "sII(IIIII)", &filename, &tag, &flags,
    695                         &limit.space_used, &limit.space_total,
    696                         &limit.inodes_used, &limit.inodes_total,
    697                         &limit.reserved))
    698     return NULL;
    699 
    700   if (vc_set_dlimit(filename, tag, flags, &limit) == -1)
    701     return PyErr_SetFromErrno(PyExc_OSError);
    702 
    703   return NONE();
    704 }
    705 
    706 static PyObject *
    707 pyvserver_get_dlimit(PyObject UNUSED *self, PyObject *args)
    708 {
    709   char const *filename;
    710   tag_t tag;
    711   uint_least32_t flags;
    712   struct vc_ctx_dlimit limit;
    713 
    714   if (!PyArg_ParseTuple(args, "sII", &filename, &tag, &flags))
    715     return NULL;
    716 
    717   if (vc_get_dlimit(filename, tag, flags, &limit) == -1)
    718     return PyErr_SetFromErrno(PyExc_OSError);
    719 
    720   return Py_BuildValue("(IIIII)", limit.space_used, limit.space_total,
    721                        limit.inodes_used, limit.inodes_total, limit.reserved);
    722 }
    723 
    724 static PyObject *
    725 pyvserver_get_task_tag(PyObject UNUSED *self, PyObject *args)
    726 {
    727   pid_t pid;
    728   tag_t tag;
    729 
    730   if (!PyArg_ParseTuple(args, "i", &pid))
    731     return NULL;
    732 
    733   tag = vc_get_task_tag(pid);
    734   if (tag == (tag_t) -1)
    735     return PyErr_SetFromErrno(PyExc_OSError);
    736 
    737   return Py_BuildValue("I", tag);
    738 }
    739 
    740 static PyObject *
    741 pyvserver_tag_create(PyObject UNUSED *self, PyObject *args)
    742 {
    743   tag_t tag;
    744 
    745   if (!PyArg_ParseTuple(args, "I", &tag))
    746     return NULL;
    747 
    748   if (vc_tag_create(tag) == -1)
    749     return PyErr_SetFromErrno(PyExc_OSError);
    750 
    751   return NONE();
    752 }
    753 
    754 static PyObject *
    755 pyvserver_tag_migrate(PyObject UNUSED *self, PyObject *args)
    756 {
    757   tag_t tag;
    758 
    759   if (!PyArg_ParseTuple(args, "I", &tag))
    760     return NULL;
    761 
    762   if (vc_tag_migrate(tag) == -1)
    763     return PyErr_SetFromErrno(PyExc_OSError);
    764 
    765   return NONE();
    766 }
    767 
    768 static PyObject *
    769 pyvserver_set_sched(PyObject UNUSED *self, PyObject *args)
    770 {
    771   xid_t xid;
    772   struct vc_set_sched sched;
    773 
    774   if (!PyArg_ParseTuple(args, "I(Iiiiiiiiiii)", &xid, &sched.set_mask,
    775                         &sched.fill_rate, &sched.interval, &sched.fill_rate2,
    776                         &sched.interval2, &sched.tokens, &sched.tokens_min,
    777                         &sched.tokens_max, &sched.priority_bias, &sched.cpu_id,
    778                         &sched.bucket_id))
    779     return NULL;
    780 
    781   if (vc_set_sched(xid, &sched) == -1)
    782     return PyErr_SetFromErrno(PyExc_OSError);
    783 
    784   return NONE();
    785 }
    786 
    787 static PyObject *
    788 pyvserver_get_sched(PyObject UNUSED *self, PyObject *args)
    789 {
    790   xid_t xid;
    791   struct vc_set_sched sched;
    792 
    793   if (!PyArg_ParseTuple(args, "Iii", &xid, &sched.cpu_id, &sched.bucket_id))
    794     return NULL;
    795 
    796   if (vc_get_sched(xid, &sched) == -1)
    797     return PyErr_SetFromErrno(PyExc_OSError);
    798 
    799   return Py_BuildValue("(Iiiiiiiiiii)", sched.set_mask, sched.fill_rate,
    800                        sched.interval, sched.fill_rate2, sched.interval2,
    801                        sched.tokens, sched.tokens_min, sched.tokens_max,
    802                        sched.priority_bias, sched.cpu_id, sched.bucket_id);
    803 }
    804 
    805 static PyObject *
    806 pyvserver_sched_info(PyObject UNUSED *self, PyObject *args)
    807 {
    808   xid_t xid;
    809   struct vc_sched_info info;
    810 
    811   if (!PyArg_ParseTuple(args, "Iii", &xid, &info.cpu_id, &info.bucket_id))
    812     return NULL;
    813 
    814   if (vc_sched_info(xid, &info) == -1)
    815     return PyErr_SetFromErrno(PyExc_OSError);
    816 
    817   return Py_BuildValue("(iiKKKIi)", info.cpu_id, info.bucket_id,
    818                        info.user_msec, info.sys_msec, info.hold_msec,
    819                        info.token_usec, info.vavavoom);
    820 }
    821 
    822 static PyObject *
    823 pyvserver_set_mapping(PyObject UNUSED *self, PyObject *args)
    824 {
    825   xid_t xid;
    826   const char *device, *target;
    827   uint32_t flags;
    828 
    829   if (!PyArg_ParseTuple(args, "IssI", &xid, &device, &target, &flags))
    830     return NULL;
    831 
    832   if (vc_set_mapping(xid, device, target, flags) == -1)
    833     return PyErr_SetFromErrno(PyExc_OSError);
    834 
    835   return NONE();
    836 }
    837 
    838 static PyObject *
    839 pyvserver_unset_mapping(PyObject UNUSED *self, PyObject *args)
    840 {
    841   xid_t xid;
    842   const char *device, *target;
    843   uint32_t flags;
    844 
    845   if (!PyArg_ParseTuple(args, "IssI", &xid, &device, &target, &flags))
    846     return NULL;
    847 
    848   if (vc_unset_mapping(xid, device, target, flags) == -1)
    849     return PyErr_SetFromErrno(PyExc_OSError);
    850 
    851   return NONE();
    852 }
    853 
    854 static PyObject *
    855 pyvserver_get_badness(PyObject UNUSED *self, PyObject *args)
    856 {
    857   xid_t xid;
    858   int64_t badness;
    859 
    860   if (!PyArg_ParseTuple(args, "I", &xid))
    861     return NULL;
    862 
    863   if (vc_get_badness(xid, &badness) == -1)
    864     return PyErr_SetFromErrno(PyExc_OSError);
    865 
    866   return Py_BuildValue("L", badness);
    867 }
    868 
    869 static PyObject *
    870 pyvserver_set_badness(PyObject UNUSED *self, PyObject *args)
    871 {
    872   xid_t xid;
    873   int64_t badness;
    874 
    875   if (!PyArg_ParseTuple(args, "IL", &xid, &badness))
    876     return NULL;
    877 
    878   if (vc_set_badness(xid, badness) == -1)
    879     return PyErr_SetFromErrno(PyExc_OSError);
    880 
    881   return NONE();
    882 }
    883 
    884 static PyObject *
    885 pyvserver_get_insecurebcaps(PyObject UNUSED *self, PyObject UNUSED *args)
    886 {
    887   uint_least64_t bcaps = vc_get_insecurebcaps();
    888   return Py_BuildValue("K", bcaps);
    889 }
    890 
    891 static PyObject *
    892 pyvserver_get_insecureccaps(PyObject UNUSED *self, PyObject UNUSED *args)
    893 {
    894   uint_least64_t ccaps = vc_get_insecureccaps();
    895   return Py_BuildValue("K", ccaps);
    896 }
    897 
    898 static PyObject *
    899 pyvserver_isSupported(PyObject UNUSED *self, PyObject *args)
    900 {
    901   int feature;
    902 
    903   if (!PyArg_ParseTuple(args, "i", &feature))
    904     return NULL;
    905 
    906   if (vc_isSupported(feature))
    907     Py_RETURN_TRUE;
    908   else
    909     Py_RETURN_FALSE;
    910 }
    911 
    912 static PyObject *
    913 pyvserver_isSupportedString(PyObject UNUSED *self, PyObject *args)
    914 {
    915   char const *feature;
    916 
    917   if (!PyArg_ParseTuple(args, "s", &feature))
    918     return NULL;
    919 
    920   if (vc_isSupportedString(feature))
    921     Py_RETURN_TRUE;
    922   else
    923     Py_RETURN_FALSE;
    924 }
    925 
    926 static PyObject *
    927 pyvserver_getXIDType(PyObject UNUSED *self, PyObject *args)
    928 {
    929   xid_t xid;
    930 
    931   if (!PyArg_ParseTuple(args, "I", &xid))
    932     return NULL;
    933 
    934   return Py_BuildValue("i", vc_getXIDType(xid));
    935 }
    936 
    937 static PyObject *
    938 pyvserver_xidopt2xid(PyObject UNUSED *self, PyObject *args)
    939 {
    940   char const *xidopt;
    941   PyObject *honor_static;
    942   xid_t xid;
    943   char const *err_info;
    944 
    945   if (!PyArg_ParseTuple(args, "sO", &xidopt, &honor_static))
    946     return NULL;
    947 
    948   xid = vc_xidopt2xid(xidopt, honor_static != Py_False, &err_info);
    949   if (xid == VC_NOXID) {
    950     PyErr_SetString(PyExc_OSError, err_info);
    951     return NULL;
    952   }
    953 
    954   return Py_BuildValue("I", xid);
    955 }
    956 
    957 static PyObject *
    958 pyvserver_nidopt2nid(PyObject UNUSED *self, PyObject *args)
    959 {
    960   char const *nidopt;
    961   PyObject *honor_static;
    962   nid_t nid;
    963   char const *err_info;
    964 
    965   if (!PyArg_ParseTuple(args, "sO", &nidopt, &honor_static))
    966     return NULL;
    967 
    968   nid = vc_nidopt2nid(nidopt, honor_static != Py_False, &err_info);
    969   if (nid == VC_NONID) {
    970     PyErr_SetString(PyExc_OSError, err_info);
    971     return NULL;
    972   }
    973 
    974   return Py_BuildValue("I", nid);
    975 }
    976 
    977 static PyObject *
    978 pyvserver_tagopt2tag(PyObject UNUSED *self, PyObject *args)
    979 {
    980   char const *tagopt;
    981   PyObject *honor_static;
    982   tag_t tag;
    983   char const *err_info;
    984 
    985   if (!PyArg_ParseTuple(args, "sO", &tagopt, &honor_static))
    986     return NULL;
    987 
    988   tag = vc_tagopt2tag(tagopt, honor_static != Py_False, &err_info);
    989   if (tag == (tag_t) -1) {
    990     PyErr_SetString(PyExc_OSError, err_info);
    991     return NULL;
    992   }
    993 
    994   return Py_BuildValue("I", tag);
    995 }
    996 
    997 #define pyvserver_handle_list(name, list_type, flag_member, mask_member) \
    998 static PyObject *  \
    999 pyvserver_text2 ## name(PyObject UNUSED *self, PyObject *args) \
   1000 { \
   1001   char const *str; \
   1002   int len; \
   1003   uint_least64_t val; \
   1004 \
   1005   if (!PyArg_ParseTuple(args, "s#", &str, &len)) \
   1006     return NULL; \
   1007 \
   1008   val = vc_text2 ## name(str, len); \
   1009   return Py_BuildValue("K", val); \
   1010 } \
   1011 \
   1012 static PyObject * \
   1013 pyvserver_lo ## name ## 2text(PyObject UNUSED *self, PyObject *args) \
   1014 { \
   1015   uint_least64_t val; \
   1016   char const *ret; \
   1017 \
   1018   if (!PyArg_ParseTuple(args, "K", &val)) \
   1019     return NULL; \
   1020 \
   1021   ret = vc_lo ## name ## 2text(&val); \
   1022   return Py_BuildValue("(Kz)", val, ret); \
   1023 } \
   1024 \
   1025 static PyObject * \
   1026 pyvserver_list2 ## name(PyObject UNUSED *self, PyObject *args) \
   1027 { \
   1028   char const *str; \
   1029   int len; \
   1030   struct vc_err_listparser err; \
   1031   list_type val = { .mask_member = 0 }; \
   1032 \
   1033   if (!PyArg_ParseTuple(args, "s#", &str, &len)) \
   1034     return NULL; \
   1035 \
   1036   if (vc_list2 ## name(str, len, &err, &val) == -1) { \
   1037     char *error; \
   1038     if (asprintf(&error, "unknown value '%.*s'", (int)err.len, err.ptr) == -1) \
   1039       return PyErr_SetFromErrno(PyExc_MemoryError); \
   1040     PyErr_SetString(PyExc_ValueError, error); \
   1041     free(error); \
   1042     return NULL; \
   1043   } \
   1044 \
   1045   return Py_BuildValue("(KK)", val.flag_member, val.mask_member); \
   1046 }
   1047 
   1048 pyvserver_handle_list(bcap, struct vc_ctx_caps, bcaps, bmask)
   1049 pyvserver_handle_list(ccap, struct vc_ctx_caps, ccaps, cmask)
   1050 pyvserver_handle_list(cflag, struct vc_ctx_flags, flagword, mask)
   1051 pyvserver_handle_list(nflag, struct vc_net_flags, flagword, mask)
   1052 pyvserver_handle_list(ncap, struct vc_net_caps, ncaps, cmask)
   1053 
   1054 static PyMethodDef methods[] = {
   1055   { "vc_get_version", pyvserver_get_version, METH_NOARGS, "FIXME" },
   1056   { "vc_get_vci", pyvserver_get_vci, METH_NOARGS, "FIXME" },
   1057   { "vc_ctx_create", pyvserver_ctx_create, METH_VARARGS, "FIXME" },
   1058   { "vc_ctx_migrate", pyvserver_ctx_migrate, METH_VARARGS, "FIXME" },
   1059   { "vc_ctx_stat", pyvserver_ctx_stat, METH_VARARGS, "FIXME" },
   1060   { "vc_virt_stat", pyvserver_virt_stat, METH_VARARGS, "FIXME" },
   1061   { "vc_ctx_kill", pyvserver_ctx_kill, METH_VARARGS, "FIXME" },
   1062   { "vc_get_cflags", pyvserver_get_cflags, METH_VARARGS, "FIXME" },
   1063   { "vc_set_cflags", pyvserver_set_cflags, METH_VARARGS, "FIXME" },
   1064   { "vc_get_ccaps", pyvserver_get_ccaps, METH_VARARGS, "FIXME" },
   1065   { "vc_set_ccaps", pyvserver_set_ccaps, METH_VARARGS, "FIXME" },
   1066   { "vc_get_vx_info", pyvserver_get_vx_info, METH_VARARGS, "FIXME" },
   1067   { "vc_get_task_xid", pyvserver_get_task_xid, METH_VARARGS, "FIXME" },
   1068   { "vc_wait_exit", pyvserver_wait_exit, METH_VARARGS, "FIXME" },
   1069   { "vc_get_rlimit_mask", pyvserver_get_rlimit_mask, METH_VARARGS, "FIXME" },
   1070   { "vc_get_rlimit", pyvserver_get_rlimit, METH_VARARGS, "FIXME" },
   1071   { "vc_set_rlimit", pyvserver_set_rlimit, METH_VARARGS, "FIXME" },
   1072   { "vc_rlimit_stat", pyvserver_rlimit_stat, METH_VARARGS, "FIXME" },
   1073   { "vc_reset_minmax", pyvserver_reset_minmax, METH_VARARGS, "FIXME" },
   1074   { "vc_get_task_nid", pyvserver_get_task_nid, METH_VARARGS, "FIXME" },
   1075   { "vc_get_nx_info", pyvserver_get_nx_info, METH_VARARGS, "FIXME" },
   1076   { "vc_net_create", pyvserver_net_create, METH_VARARGS, "FIXME" },
   1077   { "vc_net_migrate", pyvserver_net_migrate, METH_VARARGS, "FIXME" },
   1078   { "vc_net_add", pyvserver_net_add, METH_VARARGS, "FIXME" },
   1079   { "vc_net_remove", pyvserver_net_remove, METH_VARARGS, "FIXME" },
   1080   { "vc_get_nflags", pyvserver_get_nflags, METH_VARARGS, "FIXME" },
   1081   { "vc_set_nflags", pyvserver_set_nflags, METH_VARARGS, "FIXME" },
   1082   { "vc_get_ncaps", pyvserver_get_ncaps, METH_VARARGS, "FIXME" },
   1083   { "vc_set_ncaps", pyvserver_set_ncaps, METH_VARARGS, "FIXME" },
   1084   { "vc_set_iattr", pyvserver_set_iattr, METH_VARARGS, "FIXME" },
   1085   { "vc_fset_iattr", pyvserver_fset_iattr, METH_VARARGS, "FIXME" },
   1086   { "vc_get_iattr", pyvserver_get_iattr, METH_VARARGS, "FIXME" },
   1087   { "vc_fget_iattr", pyvserver_fget_iattr, METH_VARARGS, "FIXME" },
   1088   { "vc_set_vhi_name", pyvserver_set_vhi_name, METH_VARARGS, "FIXME" },
   1089   { "vc_get_vhi_name", pyvserver_get_vhi_name, METH_VARARGS, "FIXME" },
   1090   { "vc_enter_namespace", pyvserver_enter_namespace, METH_VARARGS, "FIXME" },
   1091   { "vc_set_namespace", pyvserver_set_namespace, METH_VARARGS, "FIXME" },
   1092   { "vc_get_space_mask", pyvserver_get_space_mask, METH_NOARGS, "FIXME" },
   1093   { "vc_get_space_default", pyvserver_get_space_default, METH_NOARGS, "FIXME" },
   1094   { "vc_add_dlimit", pyvserver_add_dlimit, METH_VARARGS, "FIXME" },
   1095   { "vc_rem_dlimit", pyvserver_rem_dlimit, METH_VARARGS, "FIXME" },
   1096   { "vc_set_dlimit", pyvserver_set_dlimit, METH_VARARGS, "FIXME" },
   1097   { "vc_get_dlimit", pyvserver_get_dlimit, METH_VARARGS, "FIXME" },
   1098   { "vc_get_task_tag", pyvserver_get_task_tag, METH_VARARGS, "FIXME" },
   1099   { "vc_tag_create", pyvserver_tag_create, METH_VARARGS, "FIXME" },
   1100   { "vc_tag_migrate", pyvserver_tag_migrate, METH_VARARGS, "FIXME" },
   1101   { "vc_set_sched", pyvserver_set_sched, METH_VARARGS, "FIXME" },
   1102   { "vc_get_sched", pyvserver_get_sched, METH_VARARGS, "FIXME" },
   1103   { "vc_sched_info", pyvserver_sched_info, METH_VARARGS, "FIXME" },
   1104   { "vc_set_mapping", pyvserver_set_mapping, METH_VARARGS, "FIXME" },
   1105   { "vc_unset_mapping", pyvserver_unset_mapping, METH_VARARGS, "FIXME" },
   1106   { "vc_get_badness", pyvserver_get_badness, METH_VARARGS, "FIXME" },
   1107   { "vc_set_badness", pyvserver_set_badness, METH_VARARGS, "FIXME" },
   1108   { "vc_get_insecurebcaps", pyvserver_get_insecurebcaps, METH_NOARGS, "FIXME" },
   1109   { "vc_get_insecureccaps", pyvserver_get_insecureccaps, METH_NOARGS, "FIXME" },
   1110   { "vc_isSupported", pyvserver_isSupported, METH_VARARGS, "FIXME" },
   1111   { "vc_isSupportedString", pyvserver_isSupportedString, METH_VARARGS, "FIXME" },
   1112   { "vc_getXIDType", pyvserver_getXIDType, METH_VARARGS, "FIXME" },
   1113   { "vc_xidopt2xid", pyvserver_xidopt2xid, METH_VARARGS, "FIXME" },
   1114   { "vc_nidopt2nid", pyvserver_nidopt2nid, METH_VARARGS, "FIXME" },
   1115   { "vc_tagopt2tag", pyvserver_tagopt2tag, METH_VARARGS, "FIXME" },
   1116   { "vc_text2bcap", pyvserver_text2bcap, METH_VARARGS, "FIXME" },
   1117   { "vc_lobcap2text", pyvserver_lobcap2text, METH_VARARGS, "FIXME" },
   1118   { "vc_list2bcap", pyvserver_list2bcap, METH_VARARGS, "FIXME" },
   1119   { "vc_text2ccap", pyvserver_text2ccap, METH_VARARGS, "FIXME" },
   1120   { "vc_loccap2text", pyvserver_loccap2text, METH_VARARGS, "FIXME" },
   1121   { "vc_list2ccap", pyvserver_list2ccap, METH_VARARGS, "FIXME" },
   1122   { "vc_text2cflag", pyvserver_text2cflag, METH_VARARGS, "FIXME" },
   1123   { "vc_locflag2text", pyvserver_locflag2text, METH_VARARGS, "FIXME" },
   1124   { "vc_list2cflag", pyvserver_list2cflag, METH_VARARGS, "FIXME" },
   1125   { "vc_text2nflag", pyvserver_text2nflag, METH_VARARGS, "FIXME" },
   1126   { "vc_lonflag2text", pyvserver_lonflag2text, METH_VARARGS, "FIXME" },
   1127   { "vc_list2nflag", pyvserver_list2nflag, METH_VARARGS, "FIXME" },
   1128   { "vc_text2ncap", pyvserver_text2ncap, METH_VARARGS, "FIXME" },
   1129   { "vc_loncap2text", pyvserver_loncap2text, METH_VARARGS, "FIXME" },
   1130   { "vc_list2ncap", pyvserver_list2ncap, METH_VARARGS, "FIXME" },
   1131   { NULL, NULL, 0, NULL }
   1132 };
   1133 
   1134 static void
   1135 PyModule_AddLongLongConstant(PyObject *mod, const char *str, long long val)
   1136 {
   1137 	PyObject *o = PyLong_FromLongLong(val);
   1138 	if (!o || PyModule_AddObject(mod, str, o) == -1)
   1139 		/* This ought to be reported somehow... */
   1140 		return;
   1141 }
   1142 
   1143 #if PY_MAJOR_VERSION == 2
   1144 PyMODINIT_FUNC init_libvserver(void)
   1145 {
   1146   PyObject *mod;
   1147 
   1148   mod = Py_InitModule("_libvserver", methods);
   1149 #include "_libvserver-constants.c"
   1150   return mod;
   1151 }
   1152 #else
   1153 PyMODINIT_FUNC
   1154 PyInit__libvserver(void)
   1155 {
   1156   static struct PyModuleDef lvmodule = {
   1157     PyModuleDef_HEAD_INIT,
   1158     "_libvserver",
   1159     NULL,
   1160     -1,
   1161     methods
   1162   };
   1163   PyObject *mod = PyModule_Create(&lvmodule);
   1164 #include "_libvserver-constants.c"
   1165   return mod;
   1166 }
   1167 #endif