_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