ia64/xen-unstable

view tools/python/xen/lowlevel/xc/xc.c @ 19639:205b1badbcfd

Add support for superpages (hugepages) in PV domain

This patch adds the option "superpages" to the domain configuration
file. If it is set, the domain is populated using 2M pages.

This code does not support fallback to small pages. If the domain can
not be created with 2M pages, the create will fail.

The patch also includes support for saving and restoring domains with
the superpage flag set. However, if a domain has freed small pages
within its physical page array and then extended the array, the
restore will fill in those freed pages. It will then attempt to
allocate more than its memory limit and will fail. This is
significant because apparently Linux does this during boot, thus a
freshly booted Linux image can not be saved and restored successfully.

Signed-off-by: Dave McCracken <dcm@mccr.org>
author Keir Fraser <keir.fraser@citrix.com>
date Tue May 26 09:58:38 2009 +0100 (2009-05-26)
parents 8c894687c2a5
children f210a633571c
line source
1 /******************************************************************************
2 * Xc.c
3 *
4 * Copyright (c) 2003-2004, K A Fraser (University of Cambridge)
5 */
7 #include <Python.h>
8 #include <xenctrl.h>
9 #include <xenguest.h>
10 #include <zlib.h>
11 #include <fcntl.h>
12 #include <netinet/in.h>
13 #include <netinet/tcp.h>
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <sys/mman.h>
17 #include <netdb.h>
18 #include <arpa/inet.h>
20 #include "xenctrl.h"
21 #include <xen/elfnote.h>
22 #include "xc_dom.h"
23 #include <xen/hvm/hvm_info_table.h>
24 #include <xen/hvm/params.h>
26 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
28 /* Needed for Python versions earlier than 2.3. */
29 #ifndef PyMODINIT_FUNC
30 #define PyMODINIT_FUNC DL_EXPORT(void)
31 #endif
33 #define PKG "xen.lowlevel.xc"
34 #define CLS "xc"
36 static PyObject *xc_error_obj, *zero;
38 typedef struct {
39 PyObject_HEAD;
40 int xc_handle;
41 } XcObject;
44 static PyObject *dom_op(XcObject *self, PyObject *args,
45 int (*fn)(int, uint32_t));
47 static PyObject *pyxc_error_to_exception(void)
48 {
49 PyObject *pyerr;
50 const xc_error *err = xc_get_last_error();
51 const char *desc = xc_error_code_to_desc(err->code);
53 if ( err->code == XC_ERROR_NONE )
54 return PyErr_SetFromErrno(xc_error_obj);
56 if ( err->message[0] != '\0' )
57 pyerr = Py_BuildValue("(iss)", err->code, desc, err->message);
58 else
59 pyerr = Py_BuildValue("(is)", err->code, desc);
61 xc_clear_last_error();
63 if ( pyerr != NULL )
64 {
65 PyErr_SetObject(xc_error_obj, pyerr);
66 Py_DECREF(pyerr);
67 }
69 return NULL;
70 }
72 static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
73 {
74 uint32_t dom;
75 char *corefile;
77 if ( !PyArg_ParseTuple(args, "is", &dom, &corefile) )
78 return NULL;
80 if ( (corefile == NULL) || (corefile[0] == '\0') )
81 return NULL;
83 if ( xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0 )
84 return pyxc_error_to_exception();
86 Py_INCREF(zero);
87 return zero;
88 }
90 static PyObject *pyxc_handle(XcObject *self)
91 {
92 return PyInt_FromLong(self->xc_handle);
93 }
95 static PyObject *pyxc_domain_create(XcObject *self,
96 PyObject *args,
97 PyObject *kwds)
98 {
99 uint32_t dom = 0, ssidref = 0, flags = 0, target = 0;
100 int ret, i;
101 PyObject *pyhandle = NULL;
102 xen_domain_handle_t handle = {
103 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
104 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef };
106 static char *kwd_list[] = { "domid", "ssidref", "handle", "flags", "target", NULL };
108 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOii", kwd_list,
109 &dom, &ssidref, &pyhandle, &flags, &target))
110 return NULL;
111 if ( pyhandle != NULL )
112 {
113 if ( !PyList_Check(pyhandle) ||
114 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
115 goto out_exception;
117 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
118 {
119 PyObject *p = PyList_GetItem(pyhandle, i);
120 if ( !PyInt_Check(p) )
121 goto out_exception;
122 handle[i] = (uint8_t)PyInt_AsLong(p);
123 }
124 }
126 if ( (ret = xc_domain_create(self->xc_handle, ssidref,
127 handle, flags, &dom)) < 0 )
128 return pyxc_error_to_exception();
130 if ( target )
131 if ( (ret = xc_domain_set_target(self->xc_handle, dom, target)) < 0 )
132 return pyxc_error_to_exception();
135 return PyInt_FromLong(dom);
137 out_exception:
138 errno = EINVAL;
139 PyErr_SetFromErrno(xc_error_obj);
140 return NULL;
141 }
143 static PyObject *pyxc_domain_max_vcpus(XcObject *self, PyObject *args)
144 {
145 uint32_t dom, max;
147 if (!PyArg_ParseTuple(args, "ii", &dom, &max))
148 return NULL;
150 if (xc_domain_max_vcpus(self->xc_handle, dom, max) != 0)
151 return pyxc_error_to_exception();
153 Py_INCREF(zero);
154 return zero;
155 }
157 static PyObject *pyxc_domain_pause(XcObject *self, PyObject *args)
158 {
159 return dom_op(self, args, xc_domain_pause);
160 }
162 static PyObject *pyxc_domain_unpause(XcObject *self, PyObject *args)
163 {
164 return dom_op(self, args, xc_domain_unpause);
165 }
167 static PyObject *pyxc_domain_destroy_hook(XcObject *self, PyObject *args)
168 {
169 #ifdef __ia64__
170 dom_op(self, args, xc_ia64_save_to_nvram);
171 #endif
173 Py_INCREF(zero);
174 return zero;
175 }
177 static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args)
178 {
179 return dom_op(self, args, xc_domain_destroy);
180 }
182 static PyObject *pyxc_domain_shutdown(XcObject *self, PyObject *args)
183 {
184 uint32_t dom, reason;
186 if ( !PyArg_ParseTuple(args, "ii", &dom, &reason) )
187 return NULL;
189 if ( xc_domain_shutdown(self->xc_handle, dom, reason) != 0 )
190 return pyxc_error_to_exception();
192 Py_INCREF(zero);
193 return zero;
194 }
196 static PyObject *pyxc_domain_resume(XcObject *self, PyObject *args)
197 {
198 uint32_t dom;
199 int fast;
201 if ( !PyArg_ParseTuple(args, "ii", &dom, &fast) )
202 return NULL;
204 if ( xc_domain_resume(self->xc_handle, dom, fast) != 0 )
205 return pyxc_error_to_exception();
207 Py_INCREF(zero);
208 return zero;
209 }
211 static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
212 PyObject *args,
213 PyObject *kwds)
214 {
215 uint32_t dom;
216 int vcpu = 0, i;
217 uint64_t cpumap = ~0ULL;
218 PyObject *cpulist = NULL;
220 static char *kwd_list[] = { "domid", "vcpu", "cpumap", NULL };
222 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|iO", kwd_list,
223 &dom, &vcpu, &cpulist) )
224 return NULL;
226 if ( (cpulist != NULL) && PyList_Check(cpulist) )
227 {
228 cpumap = 0ULL;
229 for ( i = 0; i < PyList_Size(cpulist); i++ )
230 {
231 long cpu = PyInt_AsLong(PyList_GetItem(cpulist, i));
232 if ( cpu >= 64 )
233 {
234 errno = EINVAL;
235 PyErr_SetFromErrno(xc_error_obj);
236 return NULL;
237 }
238 cpumap |= (uint64_t)1 << cpu;
239 }
240 }
242 if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
243 return pyxc_error_to_exception();
245 Py_INCREF(zero);
246 return zero;
247 }
249 static PyObject *pyxc_domain_sethandle(XcObject *self, PyObject *args)
250 {
251 int i;
252 uint32_t dom;
253 PyObject *pyhandle;
254 xen_domain_handle_t handle;
256 if (!PyArg_ParseTuple(args, "iO", &dom, &pyhandle))
257 return NULL;
259 if ( !PyList_Check(pyhandle) ||
260 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
261 {
262 goto out_exception;
263 }
265 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
266 {
267 PyObject *p = PyList_GetItem(pyhandle, i);
268 if ( !PyInt_Check(p) )
269 goto out_exception;
270 handle[i] = (uint8_t)PyInt_AsLong(p);
271 }
273 if (xc_domain_sethandle(self->xc_handle, dom, handle) < 0)
274 return pyxc_error_to_exception();
276 Py_INCREF(zero);
277 return zero;
279 out_exception:
280 PyErr_SetFromErrno(xc_error_obj);
281 return NULL;
282 }
285 static PyObject *pyxc_domain_getinfo(XcObject *self,
286 PyObject *args,
287 PyObject *kwds)
288 {
289 PyObject *list, *info_dict, *pyhandle;
291 uint32_t first_dom = 0;
292 int max_doms = 1024, nr_doms, i, j;
293 xc_dominfo_t *info;
295 static char *kwd_list[] = { "first_dom", "max_doms", NULL };
297 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
298 &first_dom, &max_doms) )
299 return NULL;
301 info = calloc(max_doms, sizeof(xc_dominfo_t));
302 if (info == NULL)
303 return PyErr_NoMemory();
305 nr_doms = xc_domain_getinfo(self->xc_handle, first_dom, max_doms, info);
307 if (nr_doms < 0)
308 {
309 free(info);
310 return pyxc_error_to_exception();
311 }
313 list = PyList_New(nr_doms);
314 for ( i = 0 ; i < nr_doms; i++ )
315 {
316 info_dict = Py_BuildValue(
317 "{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
318 ",s:L,s:L,s:L,s:i,s:i}",
319 "domid", (int)info[i].domid,
320 "online_vcpus", info[i].nr_online_vcpus,
321 "max_vcpu_id", info[i].max_vcpu_id,
322 "hvm", info[i].hvm,
323 "dying", info[i].dying,
324 "crashed", info[i].crashed,
325 "shutdown", info[i].shutdown,
326 "paused", info[i].paused,
327 "blocked", info[i].blocked,
328 "running", info[i].running,
329 "mem_kb", (long long)info[i].nr_pages*(XC_PAGE_SIZE/1024),
330 "cpu_time", (long long)info[i].cpu_time,
331 "maxmem_kb", (long long)info[i].max_memkb,
332 "ssidref", (int)info[i].ssidref,
333 "shutdown_reason", info[i].shutdown_reason);
334 pyhandle = PyList_New(sizeof(xen_domain_handle_t));
335 if ( (pyhandle == NULL) || (info_dict == NULL) )
336 {
337 Py_DECREF(list);
338 if ( pyhandle != NULL ) { Py_DECREF(pyhandle); }
339 if ( info_dict != NULL ) { Py_DECREF(info_dict); }
340 free(info);
341 return NULL;
342 }
343 for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
344 PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
345 PyDict_SetItemString(info_dict, "handle", pyhandle);
346 Py_DECREF(pyhandle);
347 PyList_SetItem(list, i, info_dict);
348 }
350 free(info);
352 return list;
353 }
355 static PyObject *pyxc_vcpu_getinfo(XcObject *self,
356 PyObject *args,
357 PyObject *kwds)
358 {
359 PyObject *info_dict, *cpulist;
361 uint32_t dom, vcpu = 0;
362 xc_vcpuinfo_t info;
363 int rc, i;
364 uint64_t cpumap;
366 static char *kwd_list[] = { "domid", "vcpu", NULL };
368 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
369 &dom, &vcpu) )
370 return NULL;
372 rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
373 if ( rc < 0 )
374 return pyxc_error_to_exception();
375 rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, &cpumap);
376 if ( rc < 0 )
377 return pyxc_error_to_exception();
379 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}",
380 "online", info.online,
381 "blocked", info.blocked,
382 "running", info.running,
383 "cpu_time", info.cpu_time,
384 "cpu", info.cpu);
386 cpulist = PyList_New(0);
387 for ( i = 0; cpumap != 0; i++ )
388 {
389 if ( cpumap & 1 )
390 PyList_Append(cpulist, PyInt_FromLong(i));
391 cpumap >>= 1;
392 }
393 PyDict_SetItemString(info_dict, "cpumap", cpulist);
394 Py_DECREF(cpulist);
395 return info_dict;
396 }
398 static PyObject *pyxc_linux_build(XcObject *self,
399 PyObject *args,
400 PyObject *kwds)
401 {
402 uint32_t domid;
403 struct xc_dom_image *dom;
404 char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
405 int flags = 0;
406 int store_evtchn, console_evtchn;
407 int vhpt = 0;
408 int superpages = 0;
409 unsigned int mem_mb;
410 unsigned long store_mfn = 0;
411 unsigned long console_mfn = 0;
412 PyObject* elfnote_dict;
413 PyObject* elfnote = NULL;
414 PyObject* ret;
415 int i;
417 static char *kwd_list[] = { "domid", "store_evtchn", "memsize",
418 "console_evtchn", "image",
419 /* optional */
420 "ramdisk", "cmdline", "flags",
421 "features", "vhpt", "superpages", NULL };
423 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssisii", kwd_list,
424 &domid, &store_evtchn, &mem_mb,
425 &console_evtchn, &image,
426 /* optional */
427 &ramdisk, &cmdline, &flags,
428 &features, &vhpt, &superpages) )
429 return NULL;
431 xc_dom_loginit();
432 if (!(dom = xc_dom_allocate(cmdline, features)))
433 return pyxc_error_to_exception();
435 /* for IA64 */
436 dom->vhpt_size_log2 = vhpt;
438 if ( xc_dom_linux_build(self->xc_handle, dom, domid, mem_mb, image,
439 ramdisk, flags, store_evtchn, &store_mfn,
440 console_evtchn, &console_mfn, superpages) != 0 ) {
441 goto out;
442 }
444 if ( !(elfnote_dict = PyDict_New()) )
445 goto out;
447 for ( i = 0; i < ARRAY_SIZE(dom->parms.elf_notes); i++ )
448 {
449 switch ( dom->parms.elf_notes[i].type )
450 {
451 case XEN_ENT_NONE:
452 continue;
453 case XEN_ENT_LONG:
454 elfnote = Py_BuildValue("k", dom->parms.elf_notes[i].data.num);
455 break;
456 case XEN_ENT_STR:
457 elfnote = Py_BuildValue("s", dom->parms.elf_notes[i].data.str);
458 break;
459 }
460 PyDict_SetItemString(elfnote_dict,
461 dom->parms.elf_notes[i].name,
462 elfnote);
463 Py_DECREF(elfnote);
464 }
466 ret = Py_BuildValue("{s:i,s:i,s:N}",
467 "store_mfn", store_mfn,
468 "console_mfn", console_mfn,
469 "notes", elfnote_dict);
471 if ( dom->arch_hooks->native_protocol )
472 {
473 PyObject *native_protocol =
474 Py_BuildValue("s", dom->arch_hooks->native_protocol);
475 PyDict_SetItemString(ret, "native_protocol", native_protocol);
476 Py_DECREF(native_protocol);
477 }
479 xc_dom_release(dom);
481 return ret;
483 out:
484 xc_dom_release(dom);
485 return pyxc_error_to_exception();
486 }
488 static PyObject *pyxc_get_hvm_param(XcObject *self,
489 PyObject *args,
490 PyObject *kwds)
491 {
492 uint32_t dom;
493 int param;
494 unsigned long value;
496 static char *kwd_list[] = { "domid", "param", NULL };
497 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
498 &dom, &param) )
499 return NULL;
501 if ( xc_get_hvm_param(self->xc_handle, dom, param, &value) != 0 )
502 return pyxc_error_to_exception();
504 return PyLong_FromUnsignedLong(value);
506 }
508 static PyObject *pyxc_set_hvm_param(XcObject *self,
509 PyObject *args,
510 PyObject *kwds)
511 {
512 uint32_t dom;
513 int param;
514 uint64_t value;
516 static char *kwd_list[] = { "domid", "param", "value", NULL };
517 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiL", kwd_list,
518 &dom, &param, &value) )
519 return NULL;
521 if ( xc_set_hvm_param(self->xc_handle, dom, param, value) != 0 )
522 return pyxc_error_to_exception();
524 Py_INCREF(zero);
525 return zero;
526 }
528 static int token_value(char *token)
529 {
530 token = strchr(token, 'x') + 1;
531 return strtol(token, NULL, 16);
532 }
534 static int next_bdf(char **str, int *seg, int *bus, int *dev, int *func)
535 {
536 char *token;
538 if ( !(*str) || !strchr(*str, ',') )
539 return 0;
541 token = *str;
542 *seg = token_value(token);
543 token = strchr(token, ',') + 1;
544 *bus = token_value(token);
545 token = strchr(token, ',') + 1;
546 *dev = token_value(token);
547 token = strchr(token, ',') + 1;
548 *func = token_value(token);
549 token = strchr(token, ',');
550 *str = token ? token + 1 : NULL;
552 return 1;
553 }
555 static PyObject *pyxc_test_assign_device(XcObject *self,
556 PyObject *args,
557 PyObject *kwds)
558 {
559 uint32_t dom;
560 char *pci_str;
561 int32_t bdf = 0;
562 int seg, bus, dev, func;
564 static char *kwd_list[] = { "domid", "pci", NULL };
565 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is", kwd_list,
566 &dom, &pci_str) )
567 return NULL;
569 while ( next_bdf(&pci_str, &seg, &bus, &dev, &func) )
570 {
571 bdf |= (bus & 0xff) << 16;
572 bdf |= (dev & 0x1f) << 11;
573 bdf |= (func & 0x7) << 8;
575 if ( xc_test_assign_device(self->xc_handle, dom, bdf) != 0 )
576 {
577 if (errno == ENOSYS)
578 bdf = -1;
579 break;
580 }
581 bdf = 0;
582 }
584 return Py_BuildValue("i", bdf);
585 }
587 static PyObject *pyxc_assign_device(XcObject *self,
588 PyObject *args,
589 PyObject *kwds)
590 {
591 uint32_t dom;
592 char *pci_str;
593 int32_t bdf = 0;
594 int seg, bus, dev, func;
596 static char *kwd_list[] = { "domid", "pci", NULL };
597 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is", kwd_list,
598 &dom, &pci_str) )
599 return NULL;
601 while ( next_bdf(&pci_str, &seg, &bus, &dev, &func) )
602 {
603 bdf |= (bus & 0xff) << 16;
604 bdf |= (dev & 0x1f) << 11;
605 bdf |= (func & 0x7) << 8;
607 if ( xc_assign_device(self->xc_handle, dom, bdf) != 0 )
608 {
609 if (errno == ENOSYS)
610 bdf = -1;
611 break;
612 }
613 bdf = 0;
614 }
616 return Py_BuildValue("i", bdf);
617 }
619 static PyObject *pyxc_deassign_device(XcObject *self,
620 PyObject *args,
621 PyObject *kwds)
622 {
623 uint32_t dom;
624 char *pci_str;
625 int32_t bdf = 0;
626 int seg, bus, dev, func;
628 static char *kwd_list[] = { "domid", "pci", NULL };
629 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is", kwd_list,
630 &dom, &pci_str) )
631 return NULL;
633 while ( next_bdf(&pci_str, &seg, &bus, &dev, &func) )
634 {
635 bdf |= (bus & 0xff) << 16;
636 bdf |= (dev & 0x1f) << 11;
637 bdf |= (func & 0x7) << 8;
639 if ( xc_deassign_device(self->xc_handle, dom, bdf) != 0 )
640 {
641 if (errno == ENOSYS)
642 bdf = -1;
643 break;
644 }
645 bdf = 0;
646 }
648 return Py_BuildValue("i", bdf);
649 }
651 static PyObject *pyxc_get_device_group(XcObject *self,
652 PyObject *args)
653 {
654 domid_t domid;
655 uint32_t bdf = 0;
656 uint32_t max_sdevs, num_sdevs;
657 int seg, bus, dev, func, rc, i;
658 PyObject *Pystr;
659 char *group_str;
660 char dev_str[9];
661 uint32_t *sdev_array;
663 if ( !PyArg_ParseTuple(args, "iiiii", &domid, &seg, &bus, &dev, &func) )
664 return NULL;
666 /* Maximum allowed siblings device number per group */
667 max_sdevs = 1024;
669 sdev_array = calloc(max_sdevs, sizeof(*sdev_array));
670 if (sdev_array == NULL)
671 return PyErr_NoMemory();
673 bdf |= (bus & 0xff) << 16;
674 bdf |= (dev & 0x1f) << 11;
675 bdf |= (func & 0x7) << 8;
677 rc = xc_get_device_group(self->xc_handle,
678 domid, bdf, max_sdevs, &num_sdevs, sdev_array);
680 if ( rc < 0 )
681 {
682 free(sdev_array);
683 return pyxc_error_to_exception();
684 }
686 if ( !num_sdevs )
687 {
688 free(sdev_array);
689 return Py_BuildValue("s", "");
690 }
692 group_str = calloc(num_sdevs, sizeof(dev_str));
693 if (group_str == NULL)
694 {
695 free(sdev_array);
696 return PyErr_NoMemory();
697 }
699 for ( i = 0; i < num_sdevs; i++ )
700 {
701 bus = (sdev_array[i] >> 16) & 0xff;
702 dev = (sdev_array[i] >> 11) & 0x1f;
703 func = (sdev_array[i] >> 8) & 0x7;
704 snprintf(dev_str, sizeof(dev_str), "%02x:%02x.%x,", bus, dev, func);
705 strcat(group_str, dev_str);
706 }
708 Pystr = Py_BuildValue("s", group_str);
710 free(sdev_array);
711 free(group_str);
713 return Pystr;
714 }
716 #ifdef __ia64__
717 static PyObject *pyxc_nvram_init(XcObject *self,
718 PyObject *args)
719 {
720 char *dom_name;
721 uint32_t dom;
723 if ( !PyArg_ParseTuple(args, "si", &dom_name, &dom) )
724 return NULL;
726 xc_ia64_nvram_init(self->xc_handle, dom_name, dom);
728 Py_INCREF(zero);
729 return zero;
730 }
732 static PyObject *pyxc_set_os_type(XcObject *self,
733 PyObject *args)
734 {
735 char *os_type;
736 uint32_t dom;
738 if ( !PyArg_ParseTuple(args, "si", &os_type, &dom) )
739 return NULL;
741 xc_ia64_set_os_type(self->xc_handle, os_type, dom);
743 Py_INCREF(zero);
744 return zero;
745 }
746 #endif /* __ia64__ */
749 #if defined(__i386__) || defined(__x86_64__)
750 static void pyxc_dom_extract_cpuid(PyObject *config,
751 char **regs)
752 {
753 const char *regs_extract[4] = { "eax", "ebx", "ecx", "edx" };
754 PyObject *obj;
755 int i;
757 memset(regs, 0, 4*sizeof(*regs));
759 if ( !PyDict_Check(config) )
760 return;
762 for ( i = 0; i < 4; i++ )
763 if ( (obj = PyDict_GetItemString(config, regs_extract[i])) != NULL )
764 regs[i] = PyString_AS_STRING(obj);
765 }
767 static PyObject *pyxc_create_cpuid_dict(char **regs)
768 {
769 const char *regs_extract[4] = { "eax", "ebx", "ecx", "edx" };
770 PyObject *dict;
771 int i;
773 dict = PyDict_New();
774 for ( i = 0; i < 4; i++ )
775 {
776 if ( regs[i] == NULL )
777 continue;
778 PyDict_SetItemString(dict, regs_extract[i],
779 PyString_FromString(regs[i]));
780 free(regs[i]);
781 regs[i] = NULL;
782 }
783 return dict;
784 }
786 static PyObject *pyxc_dom_check_cpuid(XcObject *self,
787 PyObject *args)
788 {
789 PyObject *sub_input, *config;
790 unsigned int input[2];
791 char *regs[4], *regs_transform[4];
793 if ( !PyArg_ParseTuple(args, "iOO", &input[0], &sub_input, &config) )
794 return NULL;
796 pyxc_dom_extract_cpuid(config, regs);
798 input[1] = XEN_CPUID_INPUT_UNUSED;
799 if ( PyLong_Check(sub_input) )
800 input[1] = PyLong_AsUnsignedLong(sub_input);
802 if ( xc_cpuid_check(self->xc_handle, input,
803 (const char **)regs, regs_transform) )
804 return pyxc_error_to_exception();
806 return pyxc_create_cpuid_dict(regs_transform);
807 }
809 static PyObject *pyxc_dom_set_policy_cpuid(XcObject *self,
810 PyObject *args)
811 {
812 domid_t domid;
814 if ( !PyArg_ParseTuple(args, "i", &domid) )
815 return NULL;
817 if ( xc_cpuid_apply_policy(self->xc_handle, domid) )
818 return pyxc_error_to_exception();
820 Py_INCREF(zero);
821 return zero;
822 }
825 static PyObject *pyxc_dom_set_cpuid(XcObject *self,
826 PyObject *args)
827 {
828 domid_t domid;
829 PyObject *sub_input, *config;
830 unsigned int input[2];
831 char *regs[4], *regs_transform[4];
833 if ( !PyArg_ParseTuple(args, "IIOO", &domid,
834 &input[0], &sub_input, &config) )
835 return NULL;
837 pyxc_dom_extract_cpuid(config, regs);
839 input[1] = XEN_CPUID_INPUT_UNUSED;
840 if ( PyLong_Check(sub_input) )
841 input[1] = PyLong_AsUnsignedLong(sub_input);
843 if ( xc_cpuid_set(self->xc_handle, domid, input, (const char **)regs,
844 regs_transform) )
845 return pyxc_error_to_exception();
847 return pyxc_create_cpuid_dict(regs_transform);
848 }
850 static PyObject *pyxc_dom_set_machine_address_size(XcObject *self,
851 PyObject *args,
852 PyObject *kwds)
853 {
854 uint32_t dom, width;
856 if (!PyArg_ParseTuple(args, "ii", &dom, &width))
857 return NULL;
859 if (xc_domain_set_machine_address_size(self->xc_handle, dom, width) != 0)
860 return pyxc_error_to_exception();
862 Py_INCREF(zero);
863 return zero;
864 }
866 static PyObject *pyxc_dom_suppress_spurious_page_faults(XcObject *self,
867 PyObject *args,
868 PyObject *kwds)
869 {
870 uint32_t dom;
872 if (!PyArg_ParseTuple(args, "i", &dom))
873 return NULL;
875 if (xc_domain_suppress_spurious_page_faults(self->xc_handle, dom) != 0)
876 return pyxc_error_to_exception();
878 Py_INCREF(zero);
879 return zero;
880 }
881 #endif /* __i386__ || __x86_64__ */
883 static PyObject *pyxc_hvm_build(XcObject *self,
884 PyObject *args,
885 PyObject *kwds)
886 {
887 uint32_t dom;
888 #if !defined(__ia64__)
889 struct hvm_info_table *va_hvm;
890 uint8_t *va_map, sum;
891 int i;
892 #endif
893 char *image;
894 int memsize, target=-1, vcpus = 1, acpi = 0, apic = 1;
896 static char *kwd_list[] = { "domid",
897 "memsize", "image", "target", "vcpus", "acpi",
898 "apic", NULL };
899 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iiii", kwd_list,
900 &dom, &memsize, &image, &target, &vcpus,
901 &acpi, &apic) )
902 return NULL;
904 if ( target == -1 )
905 target = memsize;
907 if ( xc_hvm_build_target_mem(self->xc_handle, dom, memsize,
908 target, image) != 0 )
909 return pyxc_error_to_exception();
911 #if !defined(__ia64__)
912 /* Fix up the HVM info table. */
913 va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
914 PROT_READ | PROT_WRITE,
915 HVM_INFO_PFN);
916 if ( va_map == NULL )
917 return PyErr_SetFromErrno(xc_error_obj);
918 va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
919 va_hvm->acpi_enabled = acpi;
920 va_hvm->apic_mode = apic;
921 va_hvm->nr_vcpus = vcpus;
922 for ( i = 0, sum = 0; i < va_hvm->length; i++ )
923 sum += ((uint8_t *)va_hvm)[i];
924 va_hvm->checksum -= sum;
925 munmap(va_map, XC_PAGE_SIZE);
926 #endif
928 return Py_BuildValue("{}");
929 }
931 static PyObject *pyxc_evtchn_alloc_unbound(XcObject *self,
932 PyObject *args,
933 PyObject *kwds)
934 {
935 uint32_t dom, remote_dom;
936 int port;
938 static char *kwd_list[] = { "domid", "remote_dom", NULL };
940 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
941 &dom, &remote_dom) )
942 return NULL;
944 if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) < 0 )
945 return pyxc_error_to_exception();
947 return PyInt_FromLong(port);
948 }
950 static PyObject *pyxc_evtchn_reset(XcObject *self,
951 PyObject *args,
952 PyObject *kwds)
953 {
954 uint32_t dom;
956 static char *kwd_list[] = { "dom", NULL };
958 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
959 return NULL;
961 if ( xc_evtchn_reset(self->xc_handle, dom) < 0 )
962 return pyxc_error_to_exception();
964 Py_INCREF(zero);
965 return zero;
966 }
968 static PyObject *pyxc_physdev_map_pirq(PyObject *self,
969 PyObject *args,
970 PyObject *kwds)
971 {
972 XcObject *xc = (XcObject *)self;
973 uint32_t dom;
974 int index, pirq, ret;
976 static char *kwd_list[] = {"domid", "index", "pirq", NULL};
978 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list,
979 &dom, &index, &pirq) )
980 return NULL;
981 ret = xc_physdev_map_pirq(xc->xc_handle, dom, index, &pirq);
982 if ( ret != 0 )
983 return pyxc_error_to_exception();
984 return PyLong_FromUnsignedLong(pirq);
985 }
987 static PyObject *pyxc_physdev_pci_access_modify(XcObject *self,
988 PyObject *args,
989 PyObject *kwds)
990 {
991 uint32_t dom;
992 int bus, dev, func, enable, ret;
994 static char *kwd_list[] = { "domid", "bus", "dev", "func", "enable", NULL };
996 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list,
997 &dom, &bus, &dev, &func, &enable) )
998 return NULL;
1000 ret = xc_physdev_pci_access_modify(
1001 self->xc_handle, dom, bus, dev, func, enable);
1002 if ( ret != 0 )
1003 return pyxc_error_to_exception();
1005 Py_INCREF(zero);
1006 return zero;
1009 static PyObject *pyxc_readconsolering(XcObject *self,
1010 PyObject *args,
1011 PyObject *kwds)
1013 unsigned int clear = 0, index = 0, incremental = 0;
1014 char _str[32768], *str = _str;
1015 unsigned int count = 32768;
1016 int ret;
1018 static char *kwd_list[] = { "clear", "index", "incremental", NULL };
1020 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iii", kwd_list,
1021 &clear, &index, &incremental) )
1022 return NULL;
1024 ret = xc_readconsolering(self->xc_handle, &str, &count, clear,
1025 incremental, &index);
1026 if ( ret < 0 )
1027 return pyxc_error_to_exception();
1029 return PyString_FromStringAndSize(str, count);
1033 static unsigned long pages_to_kib(unsigned long pages)
1035 return pages * (XC_PAGE_SIZE / 1024);
1039 static PyObject *pyxc_pages_to_kib(XcObject *self, PyObject *args)
1041 unsigned long pages;
1043 if (!PyArg_ParseTuple(args, "l", &pages))
1044 return NULL;
1046 return PyLong_FromUnsignedLong(pages_to_kib(pages));
1050 static PyObject *pyxc_physinfo(XcObject *self)
1052 #define MAX_CPU_ID 255
1053 xc_physinfo_t info;
1054 char cpu_cap[128], virt_caps[128], *p;
1055 int i, j, max_cpu_id;
1056 uint64_t free_heap;
1057 PyObject *ret_obj, *node_to_cpu_obj, *node_to_memory_obj;
1058 xc_cpu_to_node_t map[MAX_CPU_ID + 1];
1059 const char *virtcap_names[] = { "hvm", "hvm_directio" };
1061 set_xen_guest_handle(info.cpu_to_node, map);
1062 info.max_cpu_id = MAX_CPU_ID;
1064 if ( xc_physinfo(self->xc_handle, &info) != 0 )
1065 return pyxc_error_to_exception();
1067 p = cpu_cap;
1068 *p = '\0';
1069 for ( i = 0; i < sizeof(info.hw_cap)/4; i++ )
1070 p += sprintf(p, "%08x:", info.hw_cap[i]);
1071 *(p-1) = 0;
1073 p = virt_caps;
1074 *p = '\0';
1075 for ( i = 0; i < 2; i++ )
1076 if ( (info.capabilities >> i) & 1 )
1077 p += sprintf(p, "%s ", virtcap_names[i]);
1078 if ( p != virt_caps )
1079 *(p-1) = '\0';
1081 ret_obj = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s:s:s}",
1082 "nr_nodes", info.nr_nodes,
1083 "max_cpu_id", info.max_cpu_id,
1084 "threads_per_core", info.threads_per_core,
1085 "cores_per_socket", info.cores_per_socket,
1086 "nr_cpus", info.nr_cpus,
1087 "total_memory", pages_to_kib(info.total_pages),
1088 "free_memory", pages_to_kib(info.free_pages),
1089 "scrub_memory", pages_to_kib(info.scrub_pages),
1090 "cpu_khz", info.cpu_khz,
1091 "hw_caps", cpu_cap,
1092 "virt_caps", virt_caps);
1094 max_cpu_id = info.max_cpu_id;
1095 if ( max_cpu_id > MAX_CPU_ID )
1096 max_cpu_id = MAX_CPU_ID;
1098 /* Construct node-to-cpu lists. */
1099 node_to_cpu_obj = PyList_New(0);
1101 /* Make a list for each node. */
1102 for ( i = 0; i < info.nr_nodes; i++ )
1104 PyObject *cpus = PyList_New(0);
1105 for ( j = 0; j <= max_cpu_id; j++ )
1106 if ( i == map[j])
1107 PyList_Append(cpus, PyInt_FromLong(j));
1108 PyList_Append(node_to_cpu_obj, cpus);
1111 node_to_memory_obj = PyList_New(0);
1113 for ( i = 0; i < info.nr_nodes; i++ )
1115 xc_availheap(self->xc_handle, 0, 0, i, &free_heap);
1116 PyList_Append(node_to_memory_obj,
1117 PyInt_FromLong(free_heap / 1024));
1120 PyDict_SetItemString(ret_obj, "node_to_cpu", node_to_cpu_obj);
1121 PyDict_SetItemString(ret_obj, "node_to_memory", node_to_memory_obj);
1123 return ret_obj;
1124 #undef MAX_CPU_ID
1127 static PyObject *pyxc_xeninfo(XcObject *self)
1129 xen_extraversion_t xen_extra;
1130 xen_compile_info_t xen_cc;
1131 xen_changeset_info_t xen_chgset;
1132 xen_capabilities_info_t xen_caps;
1133 xen_platform_parameters_t p_parms;
1134 long xen_version;
1135 long xen_pagesize;
1136 char str[128];
1138 xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
1140 if ( xc_version(self->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
1141 return pyxc_error_to_exception();
1143 if ( xc_version(self->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
1144 return pyxc_error_to_exception();
1146 if ( xc_version(self->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
1147 return pyxc_error_to_exception();
1149 if ( xc_version(self->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
1150 return pyxc_error_to_exception();
1152 if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) != 0 )
1153 return pyxc_error_to_exception();
1155 snprintf(str, sizeof(str), "virt_start=0x%lx", p_parms.virt_start);
1157 xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
1158 if (xen_pagesize < 0 )
1159 return pyxc_error_to_exception();
1161 return Py_BuildValue("{s:i,s:i,s:s,s:s,s:i,s:s,s:s,s:s,s:s,s:s,s:s}",
1162 "xen_major", xen_version >> 16,
1163 "xen_minor", (xen_version & 0xffff),
1164 "xen_extra", xen_extra,
1165 "xen_caps", xen_caps,
1166 "xen_pagesize", xen_pagesize,
1167 "platform_params", str,
1168 "xen_changeset", xen_chgset,
1169 "cc_compiler", xen_cc.compiler,
1170 "cc_compile_by", xen_cc.compile_by,
1171 "cc_compile_domain", xen_cc.compile_domain,
1172 "cc_compile_date", xen_cc.compile_date);
1176 static PyObject *pyxc_sedf_domain_set(XcObject *self,
1177 PyObject *args,
1178 PyObject *kwds)
1180 uint32_t domid;
1181 uint64_t period, slice, latency;
1182 uint16_t extratime, weight;
1183 static char *kwd_list[] = { "domid", "period", "slice",
1184 "latency", "extratime", "weight",NULL };
1186 if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLhh", kwd_list,
1187 &domid, &period, &slice,
1188 &latency, &extratime, &weight) )
1189 return NULL;
1190 if ( xc_sedf_domain_set(self->xc_handle, domid, period,
1191 slice, latency, extratime,weight) != 0 )
1192 return pyxc_error_to_exception();
1194 Py_INCREF(zero);
1195 return zero;
1198 static PyObject *pyxc_sedf_domain_get(XcObject *self, PyObject *args)
1200 uint32_t domid;
1201 uint64_t period, slice,latency;
1202 uint16_t weight, extratime;
1204 if(!PyArg_ParseTuple(args, "i", &domid))
1205 return NULL;
1207 if (xc_sedf_domain_get(self->xc_handle, domid, &period,
1208 &slice,&latency,&extratime,&weight))
1209 return pyxc_error_to_exception();
1211 return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
1212 "domid", domid,
1213 "period", period,
1214 "slice", slice,
1215 "latency", latency,
1216 "extratime", extratime,
1217 "weight", weight);
1220 static PyObject *pyxc_shadow_control(PyObject *self,
1221 PyObject *args,
1222 PyObject *kwds)
1224 XcObject *xc = (XcObject *)self;
1226 uint32_t dom;
1227 int op=0;
1229 static char *kwd_list[] = { "dom", "op", NULL };
1231 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
1232 &dom, &op) )
1233 return NULL;
1235 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL, 0, NULL)
1236 < 0 )
1237 return pyxc_error_to_exception();
1239 Py_INCREF(zero);
1240 return zero;
1243 static PyObject *pyxc_shadow_mem_control(PyObject *self,
1244 PyObject *args,
1245 PyObject *kwds)
1247 XcObject *xc = (XcObject *)self;
1248 int op;
1249 uint32_t dom;
1250 int mbarg = -1;
1251 unsigned long mb;
1253 static char *kwd_list[] = { "dom", "mb", NULL };
1255 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
1256 &dom, &mbarg) )
1257 return NULL;
1259 if ( mbarg < 0 )
1260 op = XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION;
1261 else
1263 mb = mbarg;
1264 op = XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION;
1266 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, &mb, 0, NULL) < 0 )
1267 return pyxc_error_to_exception();
1269 mbarg = mb;
1270 return Py_BuildValue("i", mbarg);
1273 static PyObject *pyxc_sched_id_get(XcObject *self) {
1275 int sched_id;
1276 if (xc_sched_id(self->xc_handle, &sched_id) != 0)
1277 return PyErr_SetFromErrno(xc_error_obj);
1279 return Py_BuildValue("i", sched_id);
1282 static PyObject *pyxc_sched_credit_domain_set(XcObject *self,
1283 PyObject *args,
1284 PyObject *kwds)
1286 uint32_t domid;
1287 uint16_t weight;
1288 uint16_t cap;
1289 static char *kwd_list[] = { "domid", "weight", "cap", NULL };
1290 static char kwd_type[] = "I|HH";
1291 struct xen_domctl_sched_credit sdom;
1293 weight = 0;
1294 cap = (uint16_t)~0U;
1295 if( !PyArg_ParseTupleAndKeywords(args, kwds, kwd_type, kwd_list,
1296 &domid, &weight, &cap) )
1297 return NULL;
1299 sdom.weight = weight;
1300 sdom.cap = cap;
1302 if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 )
1303 return pyxc_error_to_exception();
1305 Py_INCREF(zero);
1306 return zero;
1309 static PyObject *pyxc_sched_credit_domain_get(XcObject *self, PyObject *args)
1311 uint32_t domid;
1312 struct xen_domctl_sched_credit sdom;
1314 if( !PyArg_ParseTuple(args, "I", &domid) )
1315 return NULL;
1317 if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 )
1318 return pyxc_error_to_exception();
1320 return Py_BuildValue("{s:H,s:H}",
1321 "weight", sdom.weight,
1322 "cap", sdom.cap);
1325 static PyObject *pyxc_domain_setmaxmem(XcObject *self, PyObject *args)
1327 uint32_t dom;
1328 unsigned int maxmem_kb;
1330 if (!PyArg_ParseTuple(args, "ii", &dom, &maxmem_kb))
1331 return NULL;
1333 if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0)
1334 return pyxc_error_to_exception();
1336 Py_INCREF(zero);
1337 return zero;
1340 static PyObject *pyxc_domain_set_target_mem(XcObject *self, PyObject *args)
1342 uint32_t dom;
1343 unsigned int mem_kb, mem_pages;
1345 if (!PyArg_ParseTuple(args, "ii", &dom, &mem_kb))
1346 return NULL;
1348 mem_pages = mem_kb / 4;
1350 if (xc_domain_memory_set_pod_target(self->xc_handle, dom, mem_pages,
1351 NULL, NULL, NULL) != 0)
1352 return pyxc_error_to_exception();
1354 Py_INCREF(zero);
1355 return zero;
1358 static PyObject *pyxc_domain_set_memmap_limit(XcObject *self, PyObject *args)
1360 uint32_t dom;
1361 unsigned int maplimit_kb;
1363 if ( !PyArg_ParseTuple(args, "ii", &dom, &maplimit_kb) )
1364 return NULL;
1366 if ( xc_domain_set_memmap_limit(self->xc_handle, dom, maplimit_kb) != 0 )
1367 return pyxc_error_to_exception();
1369 Py_INCREF(zero);
1370 return zero;
1373 static PyObject *pyxc_domain_ioport_permission(XcObject *self,
1374 PyObject *args,
1375 PyObject *kwds)
1377 uint32_t dom;
1378 int first_port, nr_ports, allow_access, ret;
1380 static char *kwd_list[] = { "domid", "first_port", "nr_ports", "allow_access", NULL };
1382 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiii", kwd_list,
1383 &dom, &first_port, &nr_ports, &allow_access) )
1384 return NULL;
1386 ret = xc_domain_ioport_permission(
1387 self->xc_handle, dom, first_port, nr_ports, allow_access);
1388 if ( ret != 0 )
1389 return pyxc_error_to_exception();
1391 Py_INCREF(zero);
1392 return zero;
1395 static PyObject *pyxc_domain_irq_permission(PyObject *self,
1396 PyObject *args,
1397 PyObject *kwds)
1399 XcObject *xc = (XcObject *)self;
1400 uint32_t dom;
1401 int pirq, allow_access, ret;
1403 static char *kwd_list[] = { "domid", "pirq", "allow_access", NULL };
1405 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list,
1406 &dom, &pirq, &allow_access) )
1407 return NULL;
1409 ret = xc_domain_irq_permission(
1410 xc->xc_handle, dom, pirq, allow_access);
1411 if ( ret != 0 )
1412 return pyxc_error_to_exception();
1414 Py_INCREF(zero);
1415 return zero;
1418 static PyObject *pyxc_domain_iomem_permission(PyObject *self,
1419 PyObject *args,
1420 PyObject *kwds)
1422 XcObject *xc = (XcObject *)self;
1423 uint32_t dom;
1424 unsigned long first_pfn, nr_pfns, allow_access, ret;
1426 static char *kwd_list[] = { "domid", "first_pfn", "nr_pfns", "allow_access", NULL };
1428 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illi", kwd_list,
1429 &dom, &first_pfn, &nr_pfns, &allow_access) )
1430 return NULL;
1432 ret = xc_domain_iomem_permission(
1433 xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
1434 if ( ret != 0 )
1435 return pyxc_error_to_exception();
1437 Py_INCREF(zero);
1438 return zero;
1441 static PyObject *pyxc_domain_set_time_offset(XcObject *self, PyObject *args)
1443 uint32_t dom;
1444 int32_t offset;
1446 if (!PyArg_ParseTuple(args, "ii", &dom, &offset))
1447 return NULL;
1449 if (xc_domain_set_time_offset(self->xc_handle, dom, offset) != 0)
1450 return pyxc_error_to_exception();
1452 Py_INCREF(zero);
1453 return zero;
1456 static PyObject *pyxc_domain_send_trigger(XcObject *self,
1457 PyObject *args,
1458 PyObject *kwds)
1460 uint32_t dom;
1461 int trigger, vcpu = 0;
1463 static char *kwd_list[] = { "domid", "trigger", "vcpu", NULL };
1465 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii|i", kwd_list,
1466 &dom, &trigger, &vcpu) )
1467 return NULL;
1469 if (xc_domain_send_trigger(self->xc_handle, dom, trigger, vcpu) != 0)
1470 return pyxc_error_to_exception();
1472 Py_INCREF(zero);
1473 return zero;
1476 static PyObject *pyxc_send_debug_keys(XcObject *self,
1477 PyObject *args,
1478 PyObject *kwds)
1480 char *keys;
1482 static char *kwd_list[] = { "keys", NULL };
1484 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list, &keys) )
1485 return NULL;
1487 if ( xc_send_debug_keys(self->xc_handle, keys) != 0 )
1488 return pyxc_error_to_exception();
1490 Py_INCREF(zero);
1491 return zero;
1494 static PyObject *dom_op(XcObject *self, PyObject *args,
1495 int (*fn)(int, uint32_t))
1497 uint32_t dom;
1499 if (!PyArg_ParseTuple(args, "i", &dom))
1500 return NULL;
1502 if (fn(self->xc_handle, dom) != 0)
1503 return pyxc_error_to_exception();
1505 Py_INCREF(zero);
1506 return zero;
1509 static PyMethodDef pyxc_methods[] = {
1510 { "handle",
1511 (PyCFunction)pyxc_handle,
1512 METH_NOARGS, "\n"
1513 "Query the xc control interface file descriptor.\n\n"
1514 "Returns: [int] file descriptor\n" },
1516 { "domain_create",
1517 (PyCFunction)pyxc_domain_create,
1518 METH_VARARGS | METH_KEYWORDS, "\n"
1519 "Create a new domain.\n"
1520 " dom [int, 0]: Domain identifier to use (allocated if zero).\n"
1521 "Returns: [int] new domain identifier; -1 on error.\n" },
1523 { "domain_max_vcpus",
1524 (PyCFunction)pyxc_domain_max_vcpus,
1525 METH_VARARGS, "\n"
1526 "Set the maximum number of VCPUs a domain may create.\n"
1527 " dom [int, 0]: Domain identifier to use.\n"
1528 " max [int, 0]: New maximum number of VCPUs in domain.\n"
1529 "Returns: [int] 0 on success; -1 on error.\n" },
1531 { "domain_dumpcore",
1532 (PyCFunction)pyxc_domain_dumpcore,
1533 METH_VARARGS, "\n"
1534 "Dump core of a domain.\n"
1535 " dom [int]: Identifier of domain to dump core of.\n"
1536 " corefile [string]: Name of corefile to be created.\n\n"
1537 "Returns: [int] 0 on success; -1 on error.\n" },
1539 { "domain_pause",
1540 (PyCFunction)pyxc_domain_pause,
1541 METH_VARARGS, "\n"
1542 "Temporarily pause execution of a domain.\n"
1543 " dom [int]: Identifier of domain to be paused.\n\n"
1544 "Returns: [int] 0 on success; -1 on error.\n" },
1546 { "domain_unpause",
1547 (PyCFunction)pyxc_domain_unpause,
1548 METH_VARARGS, "\n"
1549 "(Re)start execution of a domain.\n"
1550 " dom [int]: Identifier of domain to be unpaused.\n\n"
1551 "Returns: [int] 0 on success; -1 on error.\n" },
1553 { "domain_destroy",
1554 (PyCFunction)pyxc_domain_destroy,
1555 METH_VARARGS, "\n"
1556 "Destroy a domain.\n"
1557 " dom [int]: Identifier of domain to be destroyed.\n\n"
1558 "Returns: [int] 0 on success; -1 on error.\n" },
1560 { "domain_destroy_hook",
1561 (PyCFunction)pyxc_domain_destroy_hook,
1562 METH_VARARGS, "\n"
1563 "Add a hook for arch stuff before destroy a domain.\n"
1564 " dom [int]: Identifier of domain to be destroyed.\n\n"
1565 "Returns: [int] 0 on success; -1 on error.\n" },
1567 { "domain_resume",
1568 (PyCFunction)pyxc_domain_resume,
1569 METH_VARARGS, "\n"
1570 "Resume execution of a suspended domain.\n"
1571 " dom [int]: Identifier of domain to be resumed.\n"
1572 " fast [int]: Use cooperative resume.\n\n"
1573 "Returns: [int] 0 on success; -1 on error.\n" },
1575 { "domain_shutdown",
1576 (PyCFunction)pyxc_domain_shutdown,
1577 METH_VARARGS, "\n"
1578 "Shutdown a domain.\n"
1579 " dom [int, 0]: Domain identifier to use.\n"
1580 " reason [int, 0]: Reason for shutdown.\n"
1581 "Returns: [int] 0 on success; -1 on error.\n" },
1583 { "vcpu_setaffinity",
1584 (PyCFunction)pyxc_vcpu_setaffinity,
1585 METH_VARARGS | METH_KEYWORDS, "\n"
1586 "Pin a VCPU to a specified set CPUs.\n"
1587 " dom [int]: Identifier of domain to which VCPU belongs.\n"
1588 " vcpu [int, 0]: VCPU being pinned.\n"
1589 " cpumap [list, []]: list of usable CPUs.\n\n"
1590 "Returns: [int] 0 on success; -1 on error.\n" },
1592 { "domain_sethandle",
1593 (PyCFunction)pyxc_domain_sethandle,
1594 METH_VARARGS, "\n"
1595 "Set domain's opaque handle.\n"
1596 " dom [int]: Identifier of domain.\n"
1597 " handle [list of 16 ints]: New opaque handle.\n"
1598 "Returns: [int] 0 on success; -1 on error.\n" },
1600 { "domain_getinfo",
1601 (PyCFunction)pyxc_domain_getinfo,
1602 METH_VARARGS | METH_KEYWORDS, "\n"
1603 "Get information regarding a set of domains, in increasing id order.\n"
1604 " first_dom [int, 0]: First domain to retrieve info about.\n"
1605 " max_doms [int, 1024]: Maximum number of domains to retrieve info"
1606 " about.\n\n"
1607 "Returns: [list of dicts] if list length is less than 'max_doms'\n"
1608 " parameter then there was an error, or the end of the\n"
1609 " domain-id space was reached.\n"
1610 " dom [int]: Identifier of domain to which this info pertains\n"
1611 " cpu [int]: CPU to which this domain is bound\n"
1612 " vcpus [int]: Number of Virtual CPUS in this domain\n"
1613 " dying [int]: Bool - is the domain dying?\n"
1614 " crashed [int]: Bool - has the domain crashed?\n"
1615 " shutdown [int]: Bool - has the domain shut itself down?\n"
1616 " paused [int]: Bool - is the domain paused by control software?\n"
1617 " blocked [int]: Bool - is the domain blocked waiting for an event?\n"
1618 " running [int]: Bool - is the domain currently running?\n"
1619 " mem_kb [int]: Memory reservation, in kilobytes\n"
1620 " maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
1621 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1622 " shutdown_reason [int]: Numeric code from guest OS, explaining "
1623 "reason why it shut itself down.\n" },
1625 { "vcpu_getinfo",
1626 (PyCFunction)pyxc_vcpu_getinfo,
1627 METH_VARARGS | METH_KEYWORDS, "\n"
1628 "Get information regarding a VCPU.\n"
1629 " dom [int]: Domain to retrieve info about.\n"
1630 " vcpu [int, 0]: VCPU to retrieve info about.\n\n"
1631 "Returns: [dict]\n"
1632 " online [int]: Bool - Is this VCPU currently online?\n"
1633 " blocked [int]: Bool - Is this VCPU blocked waiting for an event?\n"
1634 " running [int]: Bool - Is this VCPU currently running on a CPU?\n"
1635 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1636 " cpumap [int]: Bitmap of CPUs this VCPU can run on\n"
1637 " cpu [int]: CPU that this VCPU is currently bound to\n" },
1639 { "linux_build",
1640 (PyCFunction)pyxc_linux_build,
1641 METH_VARARGS | METH_KEYWORDS, "\n"
1642 "Build a new Linux guest OS.\n"
1643 " dom [int]: Identifier of domain to build into.\n"
1644 " image [str]: Name of kernel image file. May be gzipped.\n"
1645 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
1646 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
1647 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1648 "Returns: [int] 0 on success; -1 on error.\n" },
1650 { "hvm_build",
1651 (PyCFunction)pyxc_hvm_build,
1652 METH_VARARGS | METH_KEYWORDS, "\n"
1653 "Build a new HVM guest OS.\n"
1654 " dom [int]: Identifier of domain to build into.\n"
1655 " image [str]: Name of HVM loader image file.\n"
1656 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1657 "Returns: [int] 0 on success; -1 on error.\n" },
1659 { "hvm_get_param",
1660 (PyCFunction)pyxc_get_hvm_param,
1661 METH_VARARGS | METH_KEYWORDS, "\n"
1662 "get a parameter of HVM guest OS.\n"
1663 " dom [int]: Identifier of domain to build into.\n"
1664 " param [int]: No. of HVM param.\n"
1665 "Returns: [long] value of the param.\n" },
1667 { "hvm_set_param",
1668 (PyCFunction)pyxc_set_hvm_param,
1669 METH_VARARGS | METH_KEYWORDS, "\n"
1670 "set a parameter of HVM guest OS.\n"
1671 " dom [int]: Identifier of domain to build into.\n"
1672 " param [int]: No. of HVM param.\n"
1673 " value [long]: Value of param.\n"
1674 "Returns: [int] 0 on success.\n" },
1676 { "get_device_group",
1677 (PyCFunction)pyxc_get_device_group,
1678 METH_VARARGS, "\n"
1679 "get sibling devices infomation.\n"
1680 " dom [int]: Domain to assign device to.\n"
1681 " seg [int]: PCI segment.\n"
1682 " bus [int]: PCI bus.\n"
1683 " dev [int]: PCI dev.\n"
1684 " func [int]: PCI func.\n"
1685 "Returns: [string]: Sibling devices \n" },
1687 { "test_assign_device",
1688 (PyCFunction)pyxc_test_assign_device,
1689 METH_VARARGS | METH_KEYWORDS, "\n"
1690 "test device assignment with VT-d.\n"
1691 " dom [int]: Identifier of domain to build into.\n"
1692 " pci_str [str]: PCI devices.\n"
1693 "Returns: [int] 0 on success, or device bdf that can't be assigned.\n" },
1695 { "assign_device",
1696 (PyCFunction)pyxc_assign_device,
1697 METH_VARARGS | METH_KEYWORDS, "\n"
1698 "Assign device to IOMMU domain.\n"
1699 " dom [int]: Domain to assign device to.\n"
1700 " pci_str [str]: PCI devices.\n"
1701 "Returns: [int] 0 on success, or device bdf that can't be assigned.\n" },
1703 { "deassign_device",
1704 (PyCFunction)pyxc_deassign_device,
1705 METH_VARARGS | METH_KEYWORDS, "\n"
1706 "Deassign device from IOMMU domain.\n"
1707 " dom [int]: Domain to deassign device from.\n"
1708 " pci_str [str]: PCI devices.\n"
1709 "Returns: [int] 0 on success, or device bdf that can't be deassigned.\n" },
1711 { "sched_id_get",
1712 (PyCFunction)pyxc_sched_id_get,
1713 METH_NOARGS, "\n"
1714 "Get the current scheduler type in use.\n"
1715 "Returns: [int] sched_id.\n" },
1717 { "sedf_domain_set",
1718 (PyCFunction)pyxc_sedf_domain_set,
1719 METH_KEYWORDS, "\n"
1720 "Set the scheduling parameters for a domain when running with Atropos.\n"
1721 " dom [int]: domain to set\n"
1722 " period [long]: domain's scheduling period\n"
1723 " slice [long]: domain's slice per period\n"
1724 " latency [long]: domain's wakeup latency hint\n"
1725 " extratime [int]: domain aware of extratime?\n"
1726 "Returns: [int] 0 on success; -1 on error.\n" },
1728 { "sedf_domain_get",
1729 (PyCFunction)pyxc_sedf_domain_get,
1730 METH_VARARGS, "\n"
1731 "Get the current scheduling parameters for a domain when running with\n"
1732 "the Atropos scheduler."
1733 " dom [int]: domain to query\n"
1734 "Returns: [dict]\n"
1735 " domain [int]: domain ID\n"
1736 " period [long]: scheduler period\n"
1737 " slice [long]: CPU reservation per period\n"
1738 " latency [long]: domain's wakeup latency hint\n"
1739 " extratime [int]: domain aware of extratime?\n"},
1741 { "sched_credit_domain_set",
1742 (PyCFunction)pyxc_sched_credit_domain_set,
1743 METH_KEYWORDS, "\n"
1744 "Set the scheduling parameters for a domain when running with the\n"
1745 "SMP credit scheduler.\n"
1746 " domid [int]: domain id to set\n"
1747 " weight [short]: domain's scheduling weight\n"
1748 "Returns: [int] 0 on success; -1 on error.\n" },
1750 { "sched_credit_domain_get",
1751 (PyCFunction)pyxc_sched_credit_domain_get,
1752 METH_VARARGS, "\n"
1753 "Get the scheduling parameters for a domain when running with the\n"
1754 "SMP credit scheduler.\n"
1755 " domid [int]: domain id to get\n"
1756 "Returns: [dict]\n"
1757 " weight [short]: domain's scheduling weight\n"},
1759 { "evtchn_alloc_unbound",
1760 (PyCFunction)pyxc_evtchn_alloc_unbound,
1761 METH_VARARGS | METH_KEYWORDS, "\n"
1762 "Allocate an unbound port that will await a remote connection.\n"
1763 " dom [int]: Domain whose port space to allocate from.\n"
1764 " remote_dom [int]: Remote domain to accept connections from.\n\n"
1765 "Returns: [int] Unbound event-channel port.\n" },
1767 { "evtchn_reset",
1768 (PyCFunction)pyxc_evtchn_reset,
1769 METH_VARARGS | METH_KEYWORDS, "\n"
1770 "Reset all connections.\n"
1771 " dom [int]: Domain to reset.\n" },
1773 { "physdev_map_pirq",
1774 (PyCFunction)pyxc_physdev_map_pirq,
1775 METH_VARARGS | METH_KEYWORDS, "\n"
1776 "map physical irq to guest pirq.\n"
1777 " dom [int]: Identifier of domain to map for.\n"
1778 " index [int]: physical irq.\n"
1779 " pirq [int]: guest pirq.\n"
1780 "Returns: [long] value of the param.\n" },
1782 { "physdev_pci_access_modify",
1783 (PyCFunction)pyxc_physdev_pci_access_modify,
1784 METH_VARARGS | METH_KEYWORDS, "\n"
1785 "Allow a domain access to a PCI device\n"
1786 " dom [int]: Identifier of domain to be allowed access.\n"
1787 " bus [int]: PCI bus\n"
1788 " dev [int]: PCI slot\n"
1789 " func [int]: PCI function\n"
1790 " enable [int]: Non-zero means enable access; else disable access\n\n"
1791 "Returns: [int] 0 on success; -1 on error.\n" },
1793 { "readconsolering",
1794 (PyCFunction)pyxc_readconsolering,
1795 METH_VARARGS | METH_KEYWORDS, "\n"
1796 "Read Xen's console ring.\n"
1797 " clear [int, 0]: Bool - clear the ring after reading from it?\n\n"
1798 "Returns: [str] string is empty on failure.\n" },
1800 { "physinfo",
1801 (PyCFunction)pyxc_physinfo,
1802 METH_NOARGS, "\n"
1803 "Get information about the physical host machine\n"
1804 "Returns [dict]: information about the hardware"
1805 " [None]: on failure.\n" },
1807 { "xeninfo",
1808 (PyCFunction)pyxc_xeninfo,
1809 METH_NOARGS, "\n"
1810 "Get information about the Xen host\n"
1811 "Returns [dict]: information about Xen"
1812 " [None]: on failure.\n" },
1814 { "shadow_control",
1815 (PyCFunction)pyxc_shadow_control,
1816 METH_VARARGS | METH_KEYWORDS, "\n"
1817 "Set parameter for shadow pagetable interface\n"
1818 " dom [int]: Identifier of domain.\n"
1819 " op [int, 0]: operation\n\n"
1820 "Returns: [int] 0 on success; -1 on error.\n" },
1822 { "shadow_mem_control",
1823 (PyCFunction)pyxc_shadow_mem_control,
1824 METH_VARARGS | METH_KEYWORDS, "\n"
1825 "Set or read shadow pagetable memory use\n"
1826 " dom [int]: Identifier of domain.\n"
1827 " mb [int, -1]: MB of shadow memory this domain should have.\n\n"
1828 "Returns: [int] MB of shadow memory in use by this domain.\n" },
1830 { "domain_setmaxmem",
1831 (PyCFunction)pyxc_domain_setmaxmem,
1832 METH_VARARGS, "\n"
1833 "Set a domain's memory limit\n"
1834 " dom [int]: Identifier of domain.\n"
1835 " maxmem_kb [int]: .\n"
1836 "Returns: [int] 0 on success; -1 on error.\n" },
1838 { "domain_set_target_mem",
1839 (PyCFunction)pyxc_domain_set_target_mem,
1840 METH_VARARGS, "\n"
1841 "Set a domain's memory target\n"
1842 " dom [int]: Identifier of domain.\n"
1843 " mem_kb [int]: .\n"
1844 "Returns: [int] 0 on success; -1 on error.\n" },
1846 { "domain_set_memmap_limit",
1847 (PyCFunction)pyxc_domain_set_memmap_limit,
1848 METH_VARARGS, "\n"
1849 "Set a domain's physical memory mappping limit\n"
1850 " dom [int]: Identifier of domain.\n"
1851 " map_limitkb [int]: .\n"
1852 "Returns: [int] 0 on success; -1 on error.\n" },
1854 #ifdef __ia64__
1855 { "nvram_init",
1856 (PyCFunction)pyxc_nvram_init,
1857 METH_VARARGS, "\n"
1858 "Init nvram in IA64 platform\n"
1859 "Returns: [int] 0 on success; -1 on error.\n" },
1860 { "set_os_type",
1861 (PyCFunction)pyxc_set_os_type,
1862 METH_VARARGS, "\n"
1863 "Set guest OS type on IA64 platform\n"
1864 "Returns: [int] 0 on success; -1 on error.\n" },
1865 #endif /* __ia64__ */
1866 { "domain_ioport_permission",
1867 (PyCFunction)pyxc_domain_ioport_permission,
1868 METH_VARARGS | METH_KEYWORDS, "\n"
1869 "Allow a domain access to a range of IO ports\n"
1870 " dom [int]: Identifier of domain to be allowed access.\n"
1871 " first_port [int]: First IO port\n"
1872 " nr_ports [int]: Number of IO ports\n"
1873 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1874 "Returns: [int] 0 on success; -1 on error.\n" },
1876 { "domain_irq_permission",
1877 (PyCFunction)pyxc_domain_irq_permission,
1878 METH_VARARGS | METH_KEYWORDS, "\n"
1879 "Allow a domain access to a physical IRQ\n"
1880 " dom [int]: Identifier of domain to be allowed access.\n"
1881 " pirq [int]: The Physical IRQ\n"
1882 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1883 "Returns: [int] 0 on success; -1 on error.\n" },
1885 { "domain_iomem_permission",
1886 (PyCFunction)pyxc_domain_iomem_permission,
1887 METH_VARARGS | METH_KEYWORDS, "\n"
1888 "Allow a domain access to a range of IO memory pages\n"
1889 " dom [int]: Identifier of domain to be allowed access.\n"
1890 " first_pfn [long]: First page of I/O Memory\n"
1891 " nr_pfns [long]: Number of pages of I/O Memory (>0)\n"
1892 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1893 "Returns: [int] 0 on success; -1 on error.\n" },
1895 { "pages_to_kib",
1896 (PyCFunction)pyxc_pages_to_kib,
1897 METH_VARARGS, "\n"
1898 "Returns: [int]: The size in KiB of memory spanning the given number "
1899 "of pages.\n" },
1901 { "domain_set_time_offset",
1902 (PyCFunction)pyxc_domain_set_time_offset,
1903 METH_VARARGS, "\n"
1904 "Set a domain's time offset to Dom0's localtime\n"
1905 " dom [int]: Domain whose time offset is being set.\n"
1906 " offset [int]: Time offset from UTC in seconds.\n"
1907 "Returns: [int] 0 on success; -1 on error.\n" },
1909 { "domain_send_trigger",
1910 (PyCFunction)pyxc_domain_send_trigger,
1911 METH_VARARGS | METH_KEYWORDS, "\n"
1912 "Send trigger to a domain.\n"
1913 " dom [int]: Identifier of domain to be sent trigger.\n"
1914 " trigger [int]: Trigger type number.\n"
1915 " vcpu [int]: VCPU to be sent trigger.\n"
1916 "Returns: [int] 0 on success; -1 on error.\n" },
1918 { "send_debug_keys",
1919 (PyCFunction)pyxc_send_debug_keys,
1920 METH_VARARGS | METH_KEYWORDS, "\n"
1921 "Inject debug keys into Xen.\n"
1922 " keys [str]: String of keys to inject.\n" },
1924 #if defined(__i386__) || defined(__x86_64__)
1925 { "domain_check_cpuid",
1926 (PyCFunction)pyxc_dom_check_cpuid,
1927 METH_VARARGS, "\n"
1928 "Apply checks to host CPUID.\n"
1929 " input [long]: Input for cpuid instruction (eax)\n"
1930 " sub_input [long]: Second input (optional, may be None) for cpuid "
1931 " instruction (ecx)\n"
1932 " config [dict]: Dictionary of register\n"
1933 " config [dict]: Dictionary of register, use for checking\n\n"
1934 "Returns: [int] 0 on success; exception on error.\n" },
1936 { "domain_set_cpuid",
1937 (PyCFunction)pyxc_dom_set_cpuid,
1938 METH_VARARGS, "\n"
1939 "Set cpuid response for an input and a domain.\n"
1940 " dom [int]: Identifier of domain.\n"
1941 " input [long]: Input for cpuid instruction (eax)\n"
1942 " sub_input [long]: Second input (optional, may be None) for cpuid "
1943 " instruction (ecx)\n"
1944 " config [dict]: Dictionary of register\n\n"
1945 "Returns: [int] 0 on success; exception on error.\n" },
1947 { "domain_set_policy_cpuid",
1948 (PyCFunction)pyxc_dom_set_policy_cpuid,
1949 METH_VARARGS, "\n"
1950 "Set the default cpuid policy for a domain.\n"
1951 " dom [int]: Identifier of domain.\n\n"
1952 "Returns: [int] 0 on success; exception on error.\n" },
1954 { "domain_set_machine_address_size",
1955 (PyCFunction)pyxc_dom_set_machine_address_size,
1956 METH_VARARGS, "\n"
1957 "Set maximum machine address size for this domain.\n"
1958 " dom [int]: Identifier of domain.\n"
1959 " width [int]: Maximum machine address width.\n" },
1961 { "domain_suppress_spurious_page_faults",
1962 (PyCFunction)pyxc_dom_suppress_spurious_page_faults,
1963 METH_VARARGS, "\n"
1964 "Do not propagate spurious page faults to this guest.\n"
1965 " dom [int]: Identifier of domain.\n" },
1966 #endif
1968 { NULL, NULL, 0, NULL }
1969 };
1972 static PyObject *PyXc_getattr(PyObject *obj, char *name)
1974 return Py_FindMethod(pyxc_methods, obj, name);
1977 static PyObject *PyXc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1979 XcObject *self = (XcObject *)type->tp_alloc(type, 0);
1981 if (self == NULL)
1982 return NULL;
1984 self->xc_handle = -1;
1986 return (PyObject *)self;
1989 static int
1990 PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
1992 if ((self->xc_handle = xc_interface_open()) == -1) {
1993 pyxc_error_to_exception();
1994 return -1;
1997 return 0;
2000 static void PyXc_dealloc(XcObject *self)
2002 if (self->xc_handle != -1) {
2003 xc_interface_close(self->xc_handle);
2004 self->xc_handle = -1;
2007 self->ob_type->tp_free((PyObject *)self);
2010 static PyTypeObject PyXcType = {
2011 PyObject_HEAD_INIT(NULL)
2012 0,
2013 PKG "." CLS,
2014 sizeof(XcObject),
2015 0,
2016 (destructor)PyXc_dealloc, /* tp_dealloc */
2017 NULL, /* tp_print */
2018 PyXc_getattr, /* tp_getattr */
2019 NULL, /* tp_setattr */
2020 NULL, /* tp_compare */
2021 NULL, /* tp_repr */
2022 NULL, /* tp_as_number */
2023 NULL, /* tp_as_sequence */
2024 NULL, /* tp_as_mapping */
2025 NULL, /* tp_hash */
2026 NULL, /* tp_call */
2027 NULL, /* tp_str */
2028 NULL, /* tp_getattro */
2029 NULL, /* tp_setattro */
2030 NULL, /* tp_as_buffer */
2031 Py_TPFLAGS_DEFAULT, /* tp_flags */
2032 "Xen client connections", /* tp_doc */
2033 NULL, /* tp_traverse */
2034 NULL, /* tp_clear */
2035 NULL, /* tp_richcompare */
2036 0, /* tp_weaklistoffset */
2037 NULL, /* tp_iter */
2038 NULL, /* tp_iternext */
2039 pyxc_methods, /* tp_methods */
2040 NULL, /* tp_members */
2041 NULL, /* tp_getset */
2042 NULL, /* tp_base */
2043 NULL, /* tp_dict */
2044 NULL, /* tp_descr_get */
2045 NULL, /* tp_descr_set */
2046 0, /* tp_dictoffset */
2047 (initproc)PyXc_init, /* tp_init */
2048 NULL, /* tp_alloc */
2049 PyXc_new, /* tp_new */
2050 };
2052 static PyMethodDef xc_methods[] = { { NULL } };
2054 PyMODINIT_FUNC initxc(void)
2056 PyObject *m;
2058 if (PyType_Ready(&PyXcType) < 0)
2059 return;
2061 m = Py_InitModule(PKG, xc_methods);
2063 if (m == NULL)
2064 return;
2066 xc_error_obj = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
2067 zero = PyInt_FromLong(0);
2069 /* KAF: This ensures that we get debug output in a timely manner. */
2070 setbuf(stdout, NULL);
2071 setbuf(stderr, NULL);
2073 Py_INCREF(&PyXcType);
2074 PyModule_AddObject(m, CLS, (PyObject *)&PyXcType);
2076 Py_INCREF(xc_error_obj);
2077 PyModule_AddObject(m, "Error", xc_error_obj);
2079 /* Expose some libxc constants to Python */
2080 PyModule_AddIntConstant(m, "XEN_SCHEDULER_SEDF", XEN_SCHEDULER_SEDF);
2081 PyModule_AddIntConstant(m, "XEN_SCHEDULER_CREDIT", XEN_SCHEDULER_CREDIT);
2086 /*
2087 * Local variables:
2088 * c-indent-level: 4
2089 * c-basic-offset: 4
2090 * End:
2091 */