ia64/xen-unstable

view tools/python/xen/lowlevel/xc/xc.c @ 19792:407e2e7dca5b

Allow tools to see the hypervisor command line.

This is useful from tools in the same way /proc/cmdline is useful for
the domain 0 kernel.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jun 18 10:20:45 2009 +0100 (2009-06-18)
parents f210a633571c
children
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 <xen/tmem.h>
23 #include "xc_dom.h"
24 #include <xen/hvm/hvm_info_table.h>
25 #include <xen/hvm/params.h>
27 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
29 /* Needed for Python versions earlier than 2.3. */
30 #ifndef PyMODINIT_FUNC
31 #define PyMODINIT_FUNC DL_EXPORT(void)
32 #endif
34 #define PKG "xen.lowlevel.xc"
35 #define CLS "xc"
37 static PyObject *xc_error_obj, *zero;
39 typedef struct {
40 PyObject_HEAD;
41 int xc_handle;
42 } XcObject;
45 static PyObject *dom_op(XcObject *self, PyObject *args,
46 int (*fn)(int, uint32_t));
48 static PyObject *pyxc_error_to_exception(void)
49 {
50 PyObject *pyerr;
51 const xc_error *err = xc_get_last_error();
52 const char *desc = xc_error_code_to_desc(err->code);
54 if ( err->code == XC_ERROR_NONE )
55 return PyErr_SetFromErrno(xc_error_obj);
57 if ( err->message[0] != '\0' )
58 pyerr = Py_BuildValue("(iss)", err->code, desc, err->message);
59 else
60 pyerr = Py_BuildValue("(is)", err->code, desc);
62 xc_clear_last_error();
64 if ( pyerr != NULL )
65 {
66 PyErr_SetObject(xc_error_obj, pyerr);
67 Py_DECREF(pyerr);
68 }
70 return NULL;
71 }
73 static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
74 {
75 uint32_t dom;
76 char *corefile;
78 if ( !PyArg_ParseTuple(args, "is", &dom, &corefile) )
79 return NULL;
81 if ( (corefile == NULL) || (corefile[0] == '\0') )
82 return NULL;
84 if ( xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0 )
85 return pyxc_error_to_exception();
87 Py_INCREF(zero);
88 return zero;
89 }
91 static PyObject *pyxc_handle(XcObject *self)
92 {
93 return PyInt_FromLong(self->xc_handle);
94 }
96 static PyObject *pyxc_domain_create(XcObject *self,
97 PyObject *args,
98 PyObject *kwds)
99 {
100 uint32_t dom = 0, ssidref = 0, flags = 0, target = 0;
101 int ret, i;
102 PyObject *pyhandle = NULL;
103 xen_domain_handle_t handle = {
104 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
105 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef };
107 static char *kwd_list[] = { "domid", "ssidref", "handle", "flags", "target", NULL };
109 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOii", kwd_list,
110 &dom, &ssidref, &pyhandle, &flags, &target))
111 return NULL;
112 if ( pyhandle != NULL )
113 {
114 if ( !PyList_Check(pyhandle) ||
115 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
116 goto out_exception;
118 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
119 {
120 PyObject *p = PyList_GetItem(pyhandle, i);
121 if ( !PyInt_Check(p) )
122 goto out_exception;
123 handle[i] = (uint8_t)PyInt_AsLong(p);
124 }
125 }
127 if ( (ret = xc_domain_create(self->xc_handle, ssidref,
128 handle, flags, &dom)) < 0 )
129 return pyxc_error_to_exception();
131 if ( target )
132 if ( (ret = xc_domain_set_target(self->xc_handle, dom, target)) < 0 )
133 return pyxc_error_to_exception();
136 return PyInt_FromLong(dom);
138 out_exception:
139 errno = EINVAL;
140 PyErr_SetFromErrno(xc_error_obj);
141 return NULL;
142 }
144 static PyObject *pyxc_domain_max_vcpus(XcObject *self, PyObject *args)
145 {
146 uint32_t dom, max;
148 if (!PyArg_ParseTuple(args, "ii", &dom, &max))
149 return NULL;
151 if (xc_domain_max_vcpus(self->xc_handle, dom, max) != 0)
152 return pyxc_error_to_exception();
154 Py_INCREF(zero);
155 return zero;
156 }
158 static PyObject *pyxc_domain_pause(XcObject *self, PyObject *args)
159 {
160 return dom_op(self, args, xc_domain_pause);
161 }
163 static PyObject *pyxc_domain_unpause(XcObject *self, PyObject *args)
164 {
165 return dom_op(self, args, xc_domain_unpause);
166 }
168 static PyObject *pyxc_domain_destroy_hook(XcObject *self, PyObject *args)
169 {
170 #ifdef __ia64__
171 dom_op(self, args, xc_ia64_save_to_nvram);
172 #endif
174 Py_INCREF(zero);
175 return zero;
176 }
178 static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args)
179 {
180 return dom_op(self, args, xc_domain_destroy);
181 }
183 static PyObject *pyxc_domain_shutdown(XcObject *self, PyObject *args)
184 {
185 uint32_t dom, reason;
187 if ( !PyArg_ParseTuple(args, "ii", &dom, &reason) )
188 return NULL;
190 if ( xc_domain_shutdown(self->xc_handle, dom, reason) != 0 )
191 return pyxc_error_to_exception();
193 Py_INCREF(zero);
194 return zero;
195 }
197 static PyObject *pyxc_domain_resume(XcObject *self, PyObject *args)
198 {
199 uint32_t dom;
200 int fast;
202 if ( !PyArg_ParseTuple(args, "ii", &dom, &fast) )
203 return NULL;
205 if ( xc_domain_resume(self->xc_handle, dom, fast) != 0 )
206 return pyxc_error_to_exception();
208 Py_INCREF(zero);
209 return zero;
210 }
212 static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
213 PyObject *args,
214 PyObject *kwds)
215 {
216 uint32_t dom;
217 int vcpu = 0, i;
218 uint64_t cpumap = ~0ULL;
219 PyObject *cpulist = NULL;
221 static char *kwd_list[] = { "domid", "vcpu", "cpumap", NULL };
223 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|iO", kwd_list,
224 &dom, &vcpu, &cpulist) )
225 return NULL;
227 if ( (cpulist != NULL) && PyList_Check(cpulist) )
228 {
229 cpumap = 0ULL;
230 for ( i = 0; i < PyList_Size(cpulist); i++ )
231 {
232 long cpu = PyInt_AsLong(PyList_GetItem(cpulist, i));
233 if ( cpu >= 64 )
234 {
235 errno = EINVAL;
236 PyErr_SetFromErrno(xc_error_obj);
237 return NULL;
238 }
239 cpumap |= (uint64_t)1 << cpu;
240 }
241 }
243 if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
244 return pyxc_error_to_exception();
246 Py_INCREF(zero);
247 return zero;
248 }
250 static PyObject *pyxc_domain_sethandle(XcObject *self, PyObject *args)
251 {
252 int i;
253 uint32_t dom;
254 PyObject *pyhandle;
255 xen_domain_handle_t handle;
257 if (!PyArg_ParseTuple(args, "iO", &dom, &pyhandle))
258 return NULL;
260 if ( !PyList_Check(pyhandle) ||
261 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
262 {
263 goto out_exception;
264 }
266 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
267 {
268 PyObject *p = PyList_GetItem(pyhandle, i);
269 if ( !PyInt_Check(p) )
270 goto out_exception;
271 handle[i] = (uint8_t)PyInt_AsLong(p);
272 }
274 if (xc_domain_sethandle(self->xc_handle, dom, handle) < 0)
275 return pyxc_error_to_exception();
277 Py_INCREF(zero);
278 return zero;
280 out_exception:
281 PyErr_SetFromErrno(xc_error_obj);
282 return NULL;
283 }
286 static PyObject *pyxc_domain_getinfo(XcObject *self,
287 PyObject *args,
288 PyObject *kwds)
289 {
290 PyObject *list, *info_dict, *pyhandle;
292 uint32_t first_dom = 0;
293 int max_doms = 1024, nr_doms, i, j;
294 xc_dominfo_t *info;
296 static char *kwd_list[] = { "first_dom", "max_doms", NULL };
298 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
299 &first_dom, &max_doms) )
300 return NULL;
302 info = calloc(max_doms, sizeof(xc_dominfo_t));
303 if (info == NULL)
304 return PyErr_NoMemory();
306 nr_doms = xc_domain_getinfo(self->xc_handle, first_dom, max_doms, info);
308 if (nr_doms < 0)
309 {
310 free(info);
311 return pyxc_error_to_exception();
312 }
314 list = PyList_New(nr_doms);
315 for ( i = 0 ; i < nr_doms; i++ )
316 {
317 info_dict = Py_BuildValue(
318 "{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
319 ",s:L,s:L,s:L,s:i,s:i}",
320 "domid", (int)info[i].domid,
321 "online_vcpus", info[i].nr_online_vcpus,
322 "max_vcpu_id", info[i].max_vcpu_id,
323 "hvm", info[i].hvm,
324 "dying", info[i].dying,
325 "crashed", info[i].crashed,
326 "shutdown", info[i].shutdown,
327 "paused", info[i].paused,
328 "blocked", info[i].blocked,
329 "running", info[i].running,
330 "mem_kb", (long long)info[i].nr_pages*(XC_PAGE_SIZE/1024),
331 "cpu_time", (long long)info[i].cpu_time,
332 "maxmem_kb", (long long)info[i].max_memkb,
333 "ssidref", (int)info[i].ssidref,
334 "shutdown_reason", info[i].shutdown_reason);
335 pyhandle = PyList_New(sizeof(xen_domain_handle_t));
336 if ( (pyhandle == NULL) || (info_dict == NULL) )
337 {
338 Py_DECREF(list);
339 if ( pyhandle != NULL ) { Py_DECREF(pyhandle); }
340 if ( info_dict != NULL ) { Py_DECREF(info_dict); }
341 free(info);
342 return NULL;
343 }
344 for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
345 PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
346 PyDict_SetItemString(info_dict, "handle", pyhandle);
347 Py_DECREF(pyhandle);
348 PyList_SetItem(list, i, info_dict);
349 }
351 free(info);
353 return list;
354 }
356 static PyObject *pyxc_vcpu_getinfo(XcObject *self,
357 PyObject *args,
358 PyObject *kwds)
359 {
360 PyObject *info_dict, *cpulist;
362 uint32_t dom, vcpu = 0;
363 xc_vcpuinfo_t info;
364 int rc, i;
365 uint64_t cpumap;
367 static char *kwd_list[] = { "domid", "vcpu", NULL };
369 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
370 &dom, &vcpu) )
371 return NULL;
373 rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
374 if ( rc < 0 )
375 return pyxc_error_to_exception();
376 rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, &cpumap);
377 if ( rc < 0 )
378 return pyxc_error_to_exception();
380 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}",
381 "online", info.online,
382 "blocked", info.blocked,
383 "running", info.running,
384 "cpu_time", info.cpu_time,
385 "cpu", info.cpu);
387 cpulist = PyList_New(0);
388 for ( i = 0; cpumap != 0; i++ )
389 {
390 if ( cpumap & 1 )
391 PyList_Append(cpulist, PyInt_FromLong(i));
392 cpumap >>= 1;
393 }
394 PyDict_SetItemString(info_dict, "cpumap", cpulist);
395 Py_DECREF(cpulist);
396 return info_dict;
397 }
399 static PyObject *pyxc_linux_build(XcObject *self,
400 PyObject *args,
401 PyObject *kwds)
402 {
403 uint32_t domid;
404 struct xc_dom_image *dom;
405 char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
406 int flags = 0;
407 int store_evtchn, console_evtchn;
408 int vhpt = 0;
409 int superpages = 0;
410 unsigned int mem_mb;
411 unsigned long store_mfn = 0;
412 unsigned long console_mfn = 0;
413 PyObject* elfnote_dict;
414 PyObject* elfnote = NULL;
415 PyObject* ret;
416 int i;
418 static char *kwd_list[] = { "domid", "store_evtchn", "memsize",
419 "console_evtchn", "image",
420 /* optional */
421 "ramdisk", "cmdline", "flags",
422 "features", "vhpt", "superpages", NULL };
424 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssisii", kwd_list,
425 &domid, &store_evtchn, &mem_mb,
426 &console_evtchn, &image,
427 /* optional */
428 &ramdisk, &cmdline, &flags,
429 &features, &vhpt, &superpages) )
430 return NULL;
432 xc_dom_loginit();
433 if (!(dom = xc_dom_allocate(cmdline, features)))
434 return pyxc_error_to_exception();
436 /* for IA64 */
437 dom->vhpt_size_log2 = vhpt;
439 if ( xc_dom_linux_build(self->xc_handle, dom, domid, mem_mb, image,
440 ramdisk, flags, store_evtchn, &store_mfn,
441 console_evtchn, &console_mfn, superpages) != 0 ) {
442 goto out;
443 }
445 if ( !(elfnote_dict = PyDict_New()) )
446 goto out;
448 for ( i = 0; i < ARRAY_SIZE(dom->parms.elf_notes); i++ )
449 {
450 switch ( dom->parms.elf_notes[i].type )
451 {
452 case XEN_ENT_NONE:
453 continue;
454 case XEN_ENT_LONG:
455 elfnote = Py_BuildValue("k", dom->parms.elf_notes[i].data.num);
456 break;
457 case XEN_ENT_STR:
458 elfnote = Py_BuildValue("s", dom->parms.elf_notes[i].data.str);
459 break;
460 }
461 PyDict_SetItemString(elfnote_dict,
462 dom->parms.elf_notes[i].name,
463 elfnote);
464 Py_DECREF(elfnote);
465 }
467 ret = Py_BuildValue("{s:i,s:i,s:N}",
468 "store_mfn", store_mfn,
469 "console_mfn", console_mfn,
470 "notes", elfnote_dict);
472 if ( dom->arch_hooks->native_protocol )
473 {
474 PyObject *native_protocol =
475 Py_BuildValue("s", dom->arch_hooks->native_protocol);
476 PyDict_SetItemString(ret, "native_protocol", native_protocol);
477 Py_DECREF(native_protocol);
478 }
480 xc_dom_release(dom);
482 return ret;
484 out:
485 xc_dom_release(dom);
486 return pyxc_error_to_exception();
487 }
489 static PyObject *pyxc_get_hvm_param(XcObject *self,
490 PyObject *args,
491 PyObject *kwds)
492 {
493 uint32_t dom;
494 int param;
495 unsigned long value;
497 static char *kwd_list[] = { "domid", "param", NULL };
498 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
499 &dom, &param) )
500 return NULL;
502 if ( xc_get_hvm_param(self->xc_handle, dom, param, &value) != 0 )
503 return pyxc_error_to_exception();
505 return PyLong_FromUnsignedLong(value);
507 }
509 static PyObject *pyxc_set_hvm_param(XcObject *self,
510 PyObject *args,
511 PyObject *kwds)
512 {
513 uint32_t dom;
514 int param;
515 uint64_t value;
517 static char *kwd_list[] = { "domid", "param", "value", NULL };
518 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiL", kwd_list,
519 &dom, &param, &value) )
520 return NULL;
522 if ( xc_set_hvm_param(self->xc_handle, dom, param, value) != 0 )
523 return pyxc_error_to_exception();
525 Py_INCREF(zero);
526 return zero;
527 }
529 static int token_value(char *token)
530 {
531 token = strchr(token, 'x') + 1;
532 return strtol(token, NULL, 16);
533 }
535 static int next_bdf(char **str, int *seg, int *bus, int *dev, int *func)
536 {
537 char *token;
539 if ( !(*str) || !strchr(*str, ',') )
540 return 0;
542 token = *str;
543 *seg = token_value(token);
544 token = strchr(token, ',') + 1;
545 *bus = token_value(token);
546 token = strchr(token, ',') + 1;
547 *dev = token_value(token);
548 token = strchr(token, ',') + 1;
549 *func = token_value(token);
550 token = strchr(token, ',');
551 *str = token ? token + 1 : NULL;
553 return 1;
554 }
556 static PyObject *pyxc_test_assign_device(XcObject *self,
557 PyObject *args,
558 PyObject *kwds)
559 {
560 uint32_t dom;
561 char *pci_str;
562 int32_t bdf = 0;
563 int seg, bus, dev, func;
565 static char *kwd_list[] = { "domid", "pci", NULL };
566 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is", kwd_list,
567 &dom, &pci_str) )
568 return NULL;
570 while ( next_bdf(&pci_str, &seg, &bus, &dev, &func) )
571 {
572 bdf |= (bus & 0xff) << 16;
573 bdf |= (dev & 0x1f) << 11;
574 bdf |= (func & 0x7) << 8;
576 if ( xc_test_assign_device(self->xc_handle, dom, bdf) != 0 )
577 {
578 if (errno == ENOSYS)
579 bdf = -1;
580 break;
581 }
582 bdf = 0;
583 }
585 return Py_BuildValue("i", bdf);
586 }
588 static PyObject *pyxc_assign_device(XcObject *self,
589 PyObject *args,
590 PyObject *kwds)
591 {
592 uint32_t dom;
593 char *pci_str;
594 int32_t bdf = 0;
595 int seg, bus, dev, func;
597 static char *kwd_list[] = { "domid", "pci", NULL };
598 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is", kwd_list,
599 &dom, &pci_str) )
600 return NULL;
602 while ( next_bdf(&pci_str, &seg, &bus, &dev, &func) )
603 {
604 bdf |= (bus & 0xff) << 16;
605 bdf |= (dev & 0x1f) << 11;
606 bdf |= (func & 0x7) << 8;
608 if ( xc_assign_device(self->xc_handle, dom, bdf) != 0 )
609 {
610 if (errno == ENOSYS)
611 bdf = -1;
612 break;
613 }
614 bdf = 0;
615 }
617 return Py_BuildValue("i", bdf);
618 }
620 static PyObject *pyxc_deassign_device(XcObject *self,
621 PyObject *args,
622 PyObject *kwds)
623 {
624 uint32_t dom;
625 char *pci_str;
626 int32_t bdf = 0;
627 int seg, bus, dev, func;
629 static char *kwd_list[] = { "domid", "pci", NULL };
630 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is", kwd_list,
631 &dom, &pci_str) )
632 return NULL;
634 while ( next_bdf(&pci_str, &seg, &bus, &dev, &func) )
635 {
636 bdf |= (bus & 0xff) << 16;
637 bdf |= (dev & 0x1f) << 11;
638 bdf |= (func & 0x7) << 8;
640 if ( xc_deassign_device(self->xc_handle, dom, bdf) != 0 )
641 {
642 if (errno == ENOSYS)
643 bdf = -1;
644 break;
645 }
646 bdf = 0;
647 }
649 return Py_BuildValue("i", bdf);
650 }
652 static PyObject *pyxc_get_device_group(XcObject *self,
653 PyObject *args)
654 {
655 domid_t domid;
656 uint32_t bdf = 0;
657 uint32_t max_sdevs, num_sdevs;
658 int seg, bus, dev, func, rc, i;
659 PyObject *Pystr;
660 char *group_str;
661 char dev_str[9];
662 uint32_t *sdev_array;
664 if ( !PyArg_ParseTuple(args, "iiiii", &domid, &seg, &bus, &dev, &func) )
665 return NULL;
667 /* Maximum allowed siblings device number per group */
668 max_sdevs = 1024;
670 sdev_array = calloc(max_sdevs, sizeof(*sdev_array));
671 if (sdev_array == NULL)
672 return PyErr_NoMemory();
674 bdf |= (bus & 0xff) << 16;
675 bdf |= (dev & 0x1f) << 11;
676 bdf |= (func & 0x7) << 8;
678 rc = xc_get_device_group(self->xc_handle,
679 domid, bdf, max_sdevs, &num_sdevs, sdev_array);
681 if ( rc < 0 )
682 {
683 free(sdev_array);
684 return pyxc_error_to_exception();
685 }
687 if ( !num_sdevs )
688 {
689 free(sdev_array);
690 return Py_BuildValue("s", "");
691 }
693 group_str = calloc(num_sdevs, sizeof(dev_str));
694 if (group_str == NULL)
695 {
696 free(sdev_array);
697 return PyErr_NoMemory();
698 }
700 for ( i = 0; i < num_sdevs; i++ )
701 {
702 bus = (sdev_array[i] >> 16) & 0xff;
703 dev = (sdev_array[i] >> 11) & 0x1f;
704 func = (sdev_array[i] >> 8) & 0x7;
705 snprintf(dev_str, sizeof(dev_str), "%02x:%02x.%x,", bus, dev, func);
706 strcat(group_str, dev_str);
707 }
709 Pystr = Py_BuildValue("s", group_str);
711 free(sdev_array);
712 free(group_str);
714 return Pystr;
715 }
717 #ifdef __ia64__
718 static PyObject *pyxc_nvram_init(XcObject *self,
719 PyObject *args)
720 {
721 char *dom_name;
722 uint32_t dom;
724 if ( !PyArg_ParseTuple(args, "si", &dom_name, &dom) )
725 return NULL;
727 xc_ia64_nvram_init(self->xc_handle, dom_name, dom);
729 Py_INCREF(zero);
730 return zero;
731 }
733 static PyObject *pyxc_set_os_type(XcObject *self,
734 PyObject *args)
735 {
736 char *os_type;
737 uint32_t dom;
739 if ( !PyArg_ParseTuple(args, "si", &os_type, &dom) )
740 return NULL;
742 xc_ia64_set_os_type(self->xc_handle, os_type, dom);
744 Py_INCREF(zero);
745 return zero;
746 }
747 #endif /* __ia64__ */
750 #if defined(__i386__) || defined(__x86_64__)
751 static void pyxc_dom_extract_cpuid(PyObject *config,
752 char **regs)
753 {
754 const char *regs_extract[4] = { "eax", "ebx", "ecx", "edx" };
755 PyObject *obj;
756 int i;
758 memset(regs, 0, 4*sizeof(*regs));
760 if ( !PyDict_Check(config) )
761 return;
763 for ( i = 0; i < 4; i++ )
764 if ( (obj = PyDict_GetItemString(config, regs_extract[i])) != NULL )
765 regs[i] = PyString_AS_STRING(obj);
766 }
768 static PyObject *pyxc_create_cpuid_dict(char **regs)
769 {
770 const char *regs_extract[4] = { "eax", "ebx", "ecx", "edx" };
771 PyObject *dict;
772 int i;
774 dict = PyDict_New();
775 for ( i = 0; i < 4; i++ )
776 {
777 if ( regs[i] == NULL )
778 continue;
779 PyDict_SetItemString(dict, regs_extract[i],
780 PyString_FromString(regs[i]));
781 free(regs[i]);
782 regs[i] = NULL;
783 }
784 return dict;
785 }
787 static PyObject *pyxc_dom_check_cpuid(XcObject *self,
788 PyObject *args)
789 {
790 PyObject *sub_input, *config;
791 unsigned int input[2];
792 char *regs[4], *regs_transform[4];
794 if ( !PyArg_ParseTuple(args, "iOO", &input[0], &sub_input, &config) )
795 return NULL;
797 pyxc_dom_extract_cpuid(config, regs);
799 input[1] = XEN_CPUID_INPUT_UNUSED;
800 if ( PyLong_Check(sub_input) )
801 input[1] = PyLong_AsUnsignedLong(sub_input);
803 if ( xc_cpuid_check(self->xc_handle, input,
804 (const char **)regs, regs_transform) )
805 return pyxc_error_to_exception();
807 return pyxc_create_cpuid_dict(regs_transform);
808 }
810 static PyObject *pyxc_dom_set_policy_cpuid(XcObject *self,
811 PyObject *args)
812 {
813 domid_t domid;
815 if ( !PyArg_ParseTuple(args, "i", &domid) )
816 return NULL;
818 if ( xc_cpuid_apply_policy(self->xc_handle, domid) )
819 return pyxc_error_to_exception();
821 Py_INCREF(zero);
822 return zero;
823 }
826 static PyObject *pyxc_dom_set_cpuid(XcObject *self,
827 PyObject *args)
828 {
829 domid_t domid;
830 PyObject *sub_input, *config;
831 unsigned int input[2];
832 char *regs[4], *regs_transform[4];
834 if ( !PyArg_ParseTuple(args, "IIOO", &domid,
835 &input[0], &sub_input, &config) )
836 return NULL;
838 pyxc_dom_extract_cpuid(config, regs);
840 input[1] = XEN_CPUID_INPUT_UNUSED;
841 if ( PyLong_Check(sub_input) )
842 input[1] = PyLong_AsUnsignedLong(sub_input);
844 if ( xc_cpuid_set(self->xc_handle, domid, input, (const char **)regs,
845 regs_transform) )
846 return pyxc_error_to_exception();
848 return pyxc_create_cpuid_dict(regs_transform);
849 }
851 static PyObject *pyxc_dom_set_machine_address_size(XcObject *self,
852 PyObject *args,
853 PyObject *kwds)
854 {
855 uint32_t dom, width;
857 if (!PyArg_ParseTuple(args, "ii", &dom, &width))
858 return NULL;
860 if (xc_domain_set_machine_address_size(self->xc_handle, dom, width) != 0)
861 return pyxc_error_to_exception();
863 Py_INCREF(zero);
864 return zero;
865 }
867 static PyObject *pyxc_dom_suppress_spurious_page_faults(XcObject *self,
868 PyObject *args,
869 PyObject *kwds)
870 {
871 uint32_t dom;
873 if (!PyArg_ParseTuple(args, "i", &dom))
874 return NULL;
876 if (xc_domain_suppress_spurious_page_faults(self->xc_handle, dom) != 0)
877 return pyxc_error_to_exception();
879 Py_INCREF(zero);
880 return zero;
881 }
882 #endif /* __i386__ || __x86_64__ */
884 static PyObject *pyxc_hvm_build(XcObject *self,
885 PyObject *args,
886 PyObject *kwds)
887 {
888 uint32_t dom;
889 #if !defined(__ia64__)
890 struct hvm_info_table *va_hvm;
891 uint8_t *va_map, sum;
892 int i;
893 #endif
894 char *image;
895 int memsize, target=-1, vcpus = 1, acpi = 0, apic = 1;
897 static char *kwd_list[] = { "domid",
898 "memsize", "image", "target", "vcpus", "acpi",
899 "apic", NULL };
900 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iiii", kwd_list,
901 &dom, &memsize, &image, &target, &vcpus,
902 &acpi, &apic) )
903 return NULL;
905 if ( target == -1 )
906 target = memsize;
908 if ( xc_hvm_build_target_mem(self->xc_handle, dom, memsize,
909 target, image) != 0 )
910 return pyxc_error_to_exception();
912 #if !defined(__ia64__)
913 /* Fix up the HVM info table. */
914 va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
915 PROT_READ | PROT_WRITE,
916 HVM_INFO_PFN);
917 if ( va_map == NULL )
918 return PyErr_SetFromErrno(xc_error_obj);
919 va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
920 va_hvm->acpi_enabled = acpi;
921 va_hvm->apic_mode = apic;
922 va_hvm->nr_vcpus = vcpus;
923 for ( i = 0, sum = 0; i < va_hvm->length; i++ )
924 sum += ((uint8_t *)va_hvm)[i];
925 va_hvm->checksum -= sum;
926 munmap(va_map, XC_PAGE_SIZE);
927 #endif
929 return Py_BuildValue("{}");
930 }
932 static PyObject *pyxc_evtchn_alloc_unbound(XcObject *self,
933 PyObject *args,
934 PyObject *kwds)
935 {
936 uint32_t dom, remote_dom;
937 int port;
939 static char *kwd_list[] = { "domid", "remote_dom", NULL };
941 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
942 &dom, &remote_dom) )
943 return NULL;
945 if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) < 0 )
946 return pyxc_error_to_exception();
948 return PyInt_FromLong(port);
949 }
951 static PyObject *pyxc_evtchn_reset(XcObject *self,
952 PyObject *args,
953 PyObject *kwds)
954 {
955 uint32_t dom;
957 static char *kwd_list[] = { "dom", NULL };
959 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
960 return NULL;
962 if ( xc_evtchn_reset(self->xc_handle, dom) < 0 )
963 return pyxc_error_to_exception();
965 Py_INCREF(zero);
966 return zero;
967 }
969 static PyObject *pyxc_physdev_map_pirq(PyObject *self,
970 PyObject *args,
971 PyObject *kwds)
972 {
973 XcObject *xc = (XcObject *)self;
974 uint32_t dom;
975 int index, pirq, ret;
977 static char *kwd_list[] = {"domid", "index", "pirq", NULL};
979 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list,
980 &dom, &index, &pirq) )
981 return NULL;
982 ret = xc_physdev_map_pirq(xc->xc_handle, dom, index, &pirq);
983 if ( ret != 0 )
984 return pyxc_error_to_exception();
985 return PyLong_FromUnsignedLong(pirq);
986 }
988 static PyObject *pyxc_physdev_pci_access_modify(XcObject *self,
989 PyObject *args,
990 PyObject *kwds)
991 {
992 uint32_t dom;
993 int bus, dev, func, enable, ret;
995 static char *kwd_list[] = { "domid", "bus", "dev", "func", "enable", NULL };
997 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list,
998 &dom, &bus, &dev, &func, &enable) )
999 return NULL;
1001 ret = xc_physdev_pci_access_modify(
1002 self->xc_handle, dom, bus, dev, func, enable);
1003 if ( ret != 0 )
1004 return pyxc_error_to_exception();
1006 Py_INCREF(zero);
1007 return zero;
1010 static PyObject *pyxc_readconsolering(XcObject *self,
1011 PyObject *args,
1012 PyObject *kwds)
1014 unsigned int clear = 0, index = 0, incremental = 0;
1015 char _str[32768], *str = _str;
1016 unsigned int count = 32768;
1017 int ret;
1019 static char *kwd_list[] = { "clear", "index", "incremental", NULL };
1021 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iii", kwd_list,
1022 &clear, &index, &incremental) )
1023 return NULL;
1025 ret = xc_readconsolering(self->xc_handle, &str, &count, clear,
1026 incremental, &index);
1027 if ( ret < 0 )
1028 return pyxc_error_to_exception();
1030 return PyString_FromStringAndSize(str, count);
1034 static unsigned long pages_to_kib(unsigned long pages)
1036 return pages * (XC_PAGE_SIZE / 1024);
1040 static PyObject *pyxc_pages_to_kib(XcObject *self, PyObject *args)
1042 unsigned long pages;
1044 if (!PyArg_ParseTuple(args, "l", &pages))
1045 return NULL;
1047 return PyLong_FromUnsignedLong(pages_to_kib(pages));
1051 static PyObject *pyxc_physinfo(XcObject *self)
1053 #define MAX_CPU_ID 255
1054 xc_physinfo_t info;
1055 char cpu_cap[128], virt_caps[128], *p;
1056 int i, j, max_cpu_id;
1057 uint64_t free_heap;
1058 PyObject *ret_obj, *node_to_cpu_obj, *node_to_memory_obj;
1059 xc_cpu_to_node_t map[MAX_CPU_ID + 1];
1060 const char *virtcap_names[] = { "hvm", "hvm_directio" };
1062 set_xen_guest_handle(info.cpu_to_node, map);
1063 info.max_cpu_id = MAX_CPU_ID;
1065 if ( xc_physinfo(self->xc_handle, &info) != 0 )
1066 return pyxc_error_to_exception();
1068 p = cpu_cap;
1069 *p = '\0';
1070 for ( i = 0; i < sizeof(info.hw_cap)/4; i++ )
1071 p += sprintf(p, "%08x:", info.hw_cap[i]);
1072 *(p-1) = 0;
1074 p = virt_caps;
1075 *p = '\0';
1076 for ( i = 0; i < 2; i++ )
1077 if ( (info.capabilities >> i) & 1 )
1078 p += sprintf(p, "%s ", virtcap_names[i]);
1079 if ( p != virt_caps )
1080 *(p-1) = '\0';
1082 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}",
1083 "nr_nodes", info.nr_nodes,
1084 "max_cpu_id", info.max_cpu_id,
1085 "threads_per_core", info.threads_per_core,
1086 "cores_per_socket", info.cores_per_socket,
1087 "nr_cpus", info.nr_cpus,
1088 "total_memory", pages_to_kib(info.total_pages),
1089 "free_memory", pages_to_kib(info.free_pages),
1090 "scrub_memory", pages_to_kib(info.scrub_pages),
1091 "cpu_khz", info.cpu_khz,
1092 "hw_caps", cpu_cap,
1093 "virt_caps", virt_caps);
1095 max_cpu_id = info.max_cpu_id;
1096 if ( max_cpu_id > MAX_CPU_ID )
1097 max_cpu_id = MAX_CPU_ID;
1099 /* Construct node-to-cpu lists. */
1100 node_to_cpu_obj = PyList_New(0);
1102 /* Make a list for each node. */
1103 for ( i = 0; i < info.nr_nodes; i++ )
1105 PyObject *cpus = PyList_New(0);
1106 for ( j = 0; j <= max_cpu_id; j++ )
1107 if ( i == map[j])
1108 PyList_Append(cpus, PyInt_FromLong(j));
1109 PyList_Append(node_to_cpu_obj, cpus);
1112 node_to_memory_obj = PyList_New(0);
1114 for ( i = 0; i < info.nr_nodes; i++ )
1116 xc_availheap(self->xc_handle, 0, 0, i, &free_heap);
1117 PyList_Append(node_to_memory_obj,
1118 PyInt_FromLong(free_heap / 1024));
1121 PyDict_SetItemString(ret_obj, "node_to_cpu", node_to_cpu_obj);
1122 PyDict_SetItemString(ret_obj, "node_to_memory", node_to_memory_obj);
1124 return ret_obj;
1125 #undef MAX_CPU_ID
1128 static PyObject *pyxc_xeninfo(XcObject *self)
1130 xen_extraversion_t xen_extra;
1131 xen_compile_info_t xen_cc;
1132 xen_changeset_info_t xen_chgset;
1133 xen_capabilities_info_t xen_caps;
1134 xen_platform_parameters_t p_parms;
1135 xen_commandline_t xen_commandline;
1136 long xen_version;
1137 long xen_pagesize;
1138 char str[128];
1140 xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
1142 if ( xc_version(self->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
1143 return pyxc_error_to_exception();
1145 if ( xc_version(self->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
1146 return pyxc_error_to_exception();
1148 if ( xc_version(self->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
1149 return pyxc_error_to_exception();
1151 if ( xc_version(self->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
1152 return pyxc_error_to_exception();
1154 if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) != 0 )
1155 return pyxc_error_to_exception();
1157 if ( xc_version(self->xc_handle, XENVER_commandline, &xen_commandline) != 0 )
1158 return pyxc_error_to_exception();
1160 snprintf(str, sizeof(str), "virt_start=0x%lx", p_parms.virt_start);
1162 xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
1163 if (xen_pagesize < 0 )
1164 return pyxc_error_to_exception();
1166 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,s:s}",
1167 "xen_major", xen_version >> 16,
1168 "xen_minor", (xen_version & 0xffff),
1169 "xen_extra", xen_extra,
1170 "xen_caps", xen_caps,
1171 "xen_pagesize", xen_pagesize,
1172 "platform_params", str,
1173 "xen_changeset", xen_chgset,
1174 "xen_commandline", xen_commandline,
1175 "cc_compiler", xen_cc.compiler,
1176 "cc_compile_by", xen_cc.compile_by,
1177 "cc_compile_domain", xen_cc.compile_domain,
1178 "cc_compile_date", xen_cc.compile_date);
1182 static PyObject *pyxc_sedf_domain_set(XcObject *self,
1183 PyObject *args,
1184 PyObject *kwds)
1186 uint32_t domid;
1187 uint64_t period, slice, latency;
1188 uint16_t extratime, weight;
1189 static char *kwd_list[] = { "domid", "period", "slice",
1190 "latency", "extratime", "weight",NULL };
1192 if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLhh", kwd_list,
1193 &domid, &period, &slice,
1194 &latency, &extratime, &weight) )
1195 return NULL;
1196 if ( xc_sedf_domain_set(self->xc_handle, domid, period,
1197 slice, latency, extratime,weight) != 0 )
1198 return pyxc_error_to_exception();
1200 Py_INCREF(zero);
1201 return zero;
1204 static PyObject *pyxc_sedf_domain_get(XcObject *self, PyObject *args)
1206 uint32_t domid;
1207 uint64_t period, slice,latency;
1208 uint16_t weight, extratime;
1210 if(!PyArg_ParseTuple(args, "i", &domid))
1211 return NULL;
1213 if (xc_sedf_domain_get(self->xc_handle, domid, &period,
1214 &slice,&latency,&extratime,&weight))
1215 return pyxc_error_to_exception();
1217 return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
1218 "domid", domid,
1219 "period", period,
1220 "slice", slice,
1221 "latency", latency,
1222 "extratime", extratime,
1223 "weight", weight);
1226 static PyObject *pyxc_shadow_control(PyObject *self,
1227 PyObject *args,
1228 PyObject *kwds)
1230 XcObject *xc = (XcObject *)self;
1232 uint32_t dom;
1233 int op=0;
1235 static char *kwd_list[] = { "dom", "op", NULL };
1237 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
1238 &dom, &op) )
1239 return NULL;
1241 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL, 0, NULL)
1242 < 0 )
1243 return pyxc_error_to_exception();
1245 Py_INCREF(zero);
1246 return zero;
1249 static PyObject *pyxc_shadow_mem_control(PyObject *self,
1250 PyObject *args,
1251 PyObject *kwds)
1253 XcObject *xc = (XcObject *)self;
1254 int op;
1255 uint32_t dom;
1256 int mbarg = -1;
1257 unsigned long mb;
1259 static char *kwd_list[] = { "dom", "mb", NULL };
1261 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
1262 &dom, &mbarg) )
1263 return NULL;
1265 if ( mbarg < 0 )
1266 op = XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION;
1267 else
1269 mb = mbarg;
1270 op = XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION;
1272 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, &mb, 0, NULL) < 0 )
1273 return pyxc_error_to_exception();
1275 mbarg = mb;
1276 return Py_BuildValue("i", mbarg);
1279 static PyObject *pyxc_sched_id_get(XcObject *self) {
1281 int sched_id;
1282 if (xc_sched_id(self->xc_handle, &sched_id) != 0)
1283 return PyErr_SetFromErrno(xc_error_obj);
1285 return Py_BuildValue("i", sched_id);
1288 static PyObject *pyxc_sched_credit_domain_set(XcObject *self,
1289 PyObject *args,
1290 PyObject *kwds)
1292 uint32_t domid;
1293 uint16_t weight;
1294 uint16_t cap;
1295 static char *kwd_list[] = { "domid", "weight", "cap", NULL };
1296 static char kwd_type[] = "I|HH";
1297 struct xen_domctl_sched_credit sdom;
1299 weight = 0;
1300 cap = (uint16_t)~0U;
1301 if( !PyArg_ParseTupleAndKeywords(args, kwds, kwd_type, kwd_list,
1302 &domid, &weight, &cap) )
1303 return NULL;
1305 sdom.weight = weight;
1306 sdom.cap = cap;
1308 if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 )
1309 return pyxc_error_to_exception();
1311 Py_INCREF(zero);
1312 return zero;
1315 static PyObject *pyxc_sched_credit_domain_get(XcObject *self, PyObject *args)
1317 uint32_t domid;
1318 struct xen_domctl_sched_credit sdom;
1320 if( !PyArg_ParseTuple(args, "I", &domid) )
1321 return NULL;
1323 if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 )
1324 return pyxc_error_to_exception();
1326 return Py_BuildValue("{s:H,s:H}",
1327 "weight", sdom.weight,
1328 "cap", sdom.cap);
1331 static PyObject *pyxc_domain_setmaxmem(XcObject *self, PyObject *args)
1333 uint32_t dom;
1334 unsigned int maxmem_kb;
1336 if (!PyArg_ParseTuple(args, "ii", &dom, &maxmem_kb))
1337 return NULL;
1339 if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0)
1340 return pyxc_error_to_exception();
1342 Py_INCREF(zero);
1343 return zero;
1346 static PyObject *pyxc_domain_set_target_mem(XcObject *self, PyObject *args)
1348 uint32_t dom;
1349 unsigned int mem_kb, mem_pages;
1351 if (!PyArg_ParseTuple(args, "ii", &dom, &mem_kb))
1352 return NULL;
1354 mem_pages = mem_kb / 4;
1356 if (xc_domain_memory_set_pod_target(self->xc_handle, dom, mem_pages,
1357 NULL, NULL, NULL) != 0)
1358 return pyxc_error_to_exception();
1360 Py_INCREF(zero);
1361 return zero;
1364 static PyObject *pyxc_domain_set_memmap_limit(XcObject *self, PyObject *args)
1366 uint32_t dom;
1367 unsigned int maplimit_kb;
1369 if ( !PyArg_ParseTuple(args, "ii", &dom, &maplimit_kb) )
1370 return NULL;
1372 if ( xc_domain_set_memmap_limit(self->xc_handle, dom, maplimit_kb) != 0 )
1373 return pyxc_error_to_exception();
1375 Py_INCREF(zero);
1376 return zero;
1379 static PyObject *pyxc_domain_ioport_permission(XcObject *self,
1380 PyObject *args,
1381 PyObject *kwds)
1383 uint32_t dom;
1384 int first_port, nr_ports, allow_access, ret;
1386 static char *kwd_list[] = { "domid", "first_port", "nr_ports", "allow_access", NULL };
1388 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiii", kwd_list,
1389 &dom, &first_port, &nr_ports, &allow_access) )
1390 return NULL;
1392 ret = xc_domain_ioport_permission(
1393 self->xc_handle, dom, first_port, nr_ports, allow_access);
1394 if ( ret != 0 )
1395 return pyxc_error_to_exception();
1397 Py_INCREF(zero);
1398 return zero;
1401 static PyObject *pyxc_domain_irq_permission(PyObject *self,
1402 PyObject *args,
1403 PyObject *kwds)
1405 XcObject *xc = (XcObject *)self;
1406 uint32_t dom;
1407 int pirq, allow_access, ret;
1409 static char *kwd_list[] = { "domid", "pirq", "allow_access", NULL };
1411 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list,
1412 &dom, &pirq, &allow_access) )
1413 return NULL;
1415 ret = xc_domain_irq_permission(
1416 xc->xc_handle, dom, pirq, allow_access);
1417 if ( ret != 0 )
1418 return pyxc_error_to_exception();
1420 Py_INCREF(zero);
1421 return zero;
1424 static PyObject *pyxc_domain_iomem_permission(PyObject *self,
1425 PyObject *args,
1426 PyObject *kwds)
1428 XcObject *xc = (XcObject *)self;
1429 uint32_t dom;
1430 unsigned long first_pfn, nr_pfns, allow_access, ret;
1432 static char *kwd_list[] = { "domid", "first_pfn", "nr_pfns", "allow_access", NULL };
1434 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illi", kwd_list,
1435 &dom, &first_pfn, &nr_pfns, &allow_access) )
1436 return NULL;
1438 ret = xc_domain_iomem_permission(
1439 xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
1440 if ( ret != 0 )
1441 return pyxc_error_to_exception();
1443 Py_INCREF(zero);
1444 return zero;
1447 static PyObject *pyxc_domain_set_time_offset(XcObject *self, PyObject *args)
1449 uint32_t dom;
1450 int32_t offset;
1452 if (!PyArg_ParseTuple(args, "ii", &dom, &offset))
1453 return NULL;
1455 if (xc_domain_set_time_offset(self->xc_handle, dom, offset) != 0)
1456 return pyxc_error_to_exception();
1458 Py_INCREF(zero);
1459 return zero;
1462 static PyObject *pyxc_domain_send_trigger(XcObject *self,
1463 PyObject *args,
1464 PyObject *kwds)
1466 uint32_t dom;
1467 int trigger, vcpu = 0;
1469 static char *kwd_list[] = { "domid", "trigger", "vcpu", NULL };
1471 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii|i", kwd_list,
1472 &dom, &trigger, &vcpu) )
1473 return NULL;
1475 if (xc_domain_send_trigger(self->xc_handle, dom, trigger, vcpu) != 0)
1476 return pyxc_error_to_exception();
1478 Py_INCREF(zero);
1479 return zero;
1482 static PyObject *pyxc_send_debug_keys(XcObject *self,
1483 PyObject *args,
1484 PyObject *kwds)
1486 char *keys;
1488 static char *kwd_list[] = { "keys", NULL };
1490 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list, &keys) )
1491 return NULL;
1493 if ( xc_send_debug_keys(self->xc_handle, keys) != 0 )
1494 return pyxc_error_to_exception();
1496 Py_INCREF(zero);
1497 return zero;
1500 static PyObject *dom_op(XcObject *self, PyObject *args,
1501 int (*fn)(int, uint32_t))
1503 uint32_t dom;
1505 if (!PyArg_ParseTuple(args, "i", &dom))
1506 return NULL;
1508 if (fn(self->xc_handle, dom) != 0)
1509 return pyxc_error_to_exception();
1511 Py_INCREF(zero);
1512 return zero;
1515 static PyObject *pyxc_tmem_control(XcObject *self,
1516 PyObject *args,
1517 PyObject *kwds)
1519 int32_t pool_id;
1520 uint32_t subop;
1521 uint32_t cli_id;
1522 uint32_t arg1;
1523 uint32_t arg2;
1524 char *buf;
1525 char _buffer[32768], *buffer = _buffer;
1526 int rc;
1528 static char *kwd_list[] = { "pool_id", "subop", "cli_id", "arg1", "arg2", "buf", NULL };
1530 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiiis", kwd_list,
1531 &pool_id, &subop, &cli_id, &arg1, &arg2, &buf) )
1532 return NULL;
1534 if ( (subop == TMEMC_LIST) && (arg1 > 32768) )
1535 arg1 = 32768;
1537 if ( (rc = xc_tmem_control(self->xc_handle, pool_id, subop, cli_id, arg1, arg2, buffer)) < 0 )
1538 return Py_BuildValue("i", rc);
1540 switch (subop) {
1541 case TMEMC_LIST:
1542 return Py_BuildValue("s", buffer);
1543 case TMEMC_FLUSH:
1544 return Py_BuildValue("i", rc);
1545 case TMEMC_THAW:
1546 case TMEMC_FREEZE:
1547 case TMEMC_DESTROY:
1548 case TMEMC_SET_WEIGHT:
1549 case TMEMC_SET_CAP:
1550 case TMEMC_SET_COMPRESS:
1551 default:
1552 break;
1555 Py_INCREF(zero);
1556 return zero;
1559 static PyMethodDef pyxc_methods[] = {
1560 { "handle",
1561 (PyCFunction)pyxc_handle,
1562 METH_NOARGS, "\n"
1563 "Query the xc control interface file descriptor.\n\n"
1564 "Returns: [int] file descriptor\n" },
1566 { "domain_create",
1567 (PyCFunction)pyxc_domain_create,
1568 METH_VARARGS | METH_KEYWORDS, "\n"
1569 "Create a new domain.\n"
1570 " dom [int, 0]: Domain identifier to use (allocated if zero).\n"
1571 "Returns: [int] new domain identifier; -1 on error.\n" },
1573 { "domain_max_vcpus",
1574 (PyCFunction)pyxc_domain_max_vcpus,
1575 METH_VARARGS, "\n"
1576 "Set the maximum number of VCPUs a domain may create.\n"
1577 " dom [int, 0]: Domain identifier to use.\n"
1578 " max [int, 0]: New maximum number of VCPUs in domain.\n"
1579 "Returns: [int] 0 on success; -1 on error.\n" },
1581 { "domain_dumpcore",
1582 (PyCFunction)pyxc_domain_dumpcore,
1583 METH_VARARGS, "\n"
1584 "Dump core of a domain.\n"
1585 " dom [int]: Identifier of domain to dump core of.\n"
1586 " corefile [string]: Name of corefile to be created.\n\n"
1587 "Returns: [int] 0 on success; -1 on error.\n" },
1589 { "domain_pause",
1590 (PyCFunction)pyxc_domain_pause,
1591 METH_VARARGS, "\n"
1592 "Temporarily pause execution of a domain.\n"
1593 " dom [int]: Identifier of domain to be paused.\n\n"
1594 "Returns: [int] 0 on success; -1 on error.\n" },
1596 { "domain_unpause",
1597 (PyCFunction)pyxc_domain_unpause,
1598 METH_VARARGS, "\n"
1599 "(Re)start execution of a domain.\n"
1600 " dom [int]: Identifier of domain to be unpaused.\n\n"
1601 "Returns: [int] 0 on success; -1 on error.\n" },
1603 { "domain_destroy",
1604 (PyCFunction)pyxc_domain_destroy,
1605 METH_VARARGS, "\n"
1606 "Destroy a domain.\n"
1607 " dom [int]: Identifier of domain to be destroyed.\n\n"
1608 "Returns: [int] 0 on success; -1 on error.\n" },
1610 { "domain_destroy_hook",
1611 (PyCFunction)pyxc_domain_destroy_hook,
1612 METH_VARARGS, "\n"
1613 "Add a hook for arch stuff before destroy a domain.\n"
1614 " dom [int]: Identifier of domain to be destroyed.\n\n"
1615 "Returns: [int] 0 on success; -1 on error.\n" },
1617 { "domain_resume",
1618 (PyCFunction)pyxc_domain_resume,
1619 METH_VARARGS, "\n"
1620 "Resume execution of a suspended domain.\n"
1621 " dom [int]: Identifier of domain to be resumed.\n"
1622 " fast [int]: Use cooperative resume.\n\n"
1623 "Returns: [int] 0 on success; -1 on error.\n" },
1625 { "domain_shutdown",
1626 (PyCFunction)pyxc_domain_shutdown,
1627 METH_VARARGS, "\n"
1628 "Shutdown a domain.\n"
1629 " dom [int, 0]: Domain identifier to use.\n"
1630 " reason [int, 0]: Reason for shutdown.\n"
1631 "Returns: [int] 0 on success; -1 on error.\n" },
1633 { "vcpu_setaffinity",
1634 (PyCFunction)pyxc_vcpu_setaffinity,
1635 METH_VARARGS | METH_KEYWORDS, "\n"
1636 "Pin a VCPU to a specified set CPUs.\n"
1637 " dom [int]: Identifier of domain to which VCPU belongs.\n"
1638 " vcpu [int, 0]: VCPU being pinned.\n"
1639 " cpumap [list, []]: list of usable CPUs.\n\n"
1640 "Returns: [int] 0 on success; -1 on error.\n" },
1642 { "domain_sethandle",
1643 (PyCFunction)pyxc_domain_sethandle,
1644 METH_VARARGS, "\n"
1645 "Set domain's opaque handle.\n"
1646 " dom [int]: Identifier of domain.\n"
1647 " handle [list of 16 ints]: New opaque handle.\n"
1648 "Returns: [int] 0 on success; -1 on error.\n" },
1650 { "domain_getinfo",
1651 (PyCFunction)pyxc_domain_getinfo,
1652 METH_VARARGS | METH_KEYWORDS, "\n"
1653 "Get information regarding a set of domains, in increasing id order.\n"
1654 " first_dom [int, 0]: First domain to retrieve info about.\n"
1655 " max_doms [int, 1024]: Maximum number of domains to retrieve info"
1656 " about.\n\n"
1657 "Returns: [list of dicts] if list length is less than 'max_doms'\n"
1658 " parameter then there was an error, or the end of the\n"
1659 " domain-id space was reached.\n"
1660 " dom [int]: Identifier of domain to which this info pertains\n"
1661 " cpu [int]: CPU to which this domain is bound\n"
1662 " vcpus [int]: Number of Virtual CPUS in this domain\n"
1663 " dying [int]: Bool - is the domain dying?\n"
1664 " crashed [int]: Bool - has the domain crashed?\n"
1665 " shutdown [int]: Bool - has the domain shut itself down?\n"
1666 " paused [int]: Bool - is the domain paused by control software?\n"
1667 " blocked [int]: Bool - is the domain blocked waiting for an event?\n"
1668 " running [int]: Bool - is the domain currently running?\n"
1669 " mem_kb [int]: Memory reservation, in kilobytes\n"
1670 " maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
1671 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1672 " shutdown_reason [int]: Numeric code from guest OS, explaining "
1673 "reason why it shut itself down.\n" },
1675 { "vcpu_getinfo",
1676 (PyCFunction)pyxc_vcpu_getinfo,
1677 METH_VARARGS | METH_KEYWORDS, "\n"
1678 "Get information regarding a VCPU.\n"
1679 " dom [int]: Domain to retrieve info about.\n"
1680 " vcpu [int, 0]: VCPU to retrieve info about.\n\n"
1681 "Returns: [dict]\n"
1682 " online [int]: Bool - Is this VCPU currently online?\n"
1683 " blocked [int]: Bool - Is this VCPU blocked waiting for an event?\n"
1684 " running [int]: Bool - Is this VCPU currently running on a CPU?\n"
1685 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1686 " cpumap [int]: Bitmap of CPUs this VCPU can run on\n"
1687 " cpu [int]: CPU that this VCPU is currently bound to\n" },
1689 { "linux_build",
1690 (PyCFunction)pyxc_linux_build,
1691 METH_VARARGS | METH_KEYWORDS, "\n"
1692 "Build a new Linux guest OS.\n"
1693 " dom [int]: Identifier of domain to build into.\n"
1694 " image [str]: Name of kernel image file. May be gzipped.\n"
1695 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
1696 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
1697 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1698 "Returns: [int] 0 on success; -1 on error.\n" },
1700 { "hvm_build",
1701 (PyCFunction)pyxc_hvm_build,
1702 METH_VARARGS | METH_KEYWORDS, "\n"
1703 "Build a new HVM guest OS.\n"
1704 " dom [int]: Identifier of domain to build into.\n"
1705 " image [str]: Name of HVM loader image file.\n"
1706 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1707 "Returns: [int] 0 on success; -1 on error.\n" },
1709 { "hvm_get_param",
1710 (PyCFunction)pyxc_get_hvm_param,
1711 METH_VARARGS | METH_KEYWORDS, "\n"
1712 "get a parameter of HVM guest OS.\n"
1713 " dom [int]: Identifier of domain to build into.\n"
1714 " param [int]: No. of HVM param.\n"
1715 "Returns: [long] value of the param.\n" },
1717 { "hvm_set_param",
1718 (PyCFunction)pyxc_set_hvm_param,
1719 METH_VARARGS | METH_KEYWORDS, "\n"
1720 "set a parameter of HVM guest OS.\n"
1721 " dom [int]: Identifier of domain to build into.\n"
1722 " param [int]: No. of HVM param.\n"
1723 " value [long]: Value of param.\n"
1724 "Returns: [int] 0 on success.\n" },
1726 { "get_device_group",
1727 (PyCFunction)pyxc_get_device_group,
1728 METH_VARARGS, "\n"
1729 "get sibling devices infomation.\n"
1730 " dom [int]: Domain to assign device to.\n"
1731 " seg [int]: PCI segment.\n"
1732 " bus [int]: PCI bus.\n"
1733 " dev [int]: PCI dev.\n"
1734 " func [int]: PCI func.\n"
1735 "Returns: [string]: Sibling devices \n" },
1737 { "test_assign_device",
1738 (PyCFunction)pyxc_test_assign_device,
1739 METH_VARARGS | METH_KEYWORDS, "\n"
1740 "test device assignment with VT-d.\n"
1741 " dom [int]: Identifier of domain to build into.\n"
1742 " pci_str [str]: PCI devices.\n"
1743 "Returns: [int] 0 on success, or device bdf that can't be assigned.\n" },
1745 { "assign_device",
1746 (PyCFunction)pyxc_assign_device,
1747 METH_VARARGS | METH_KEYWORDS, "\n"
1748 "Assign device to IOMMU domain.\n"
1749 " dom [int]: Domain to assign device to.\n"
1750 " pci_str [str]: PCI devices.\n"
1751 "Returns: [int] 0 on success, or device bdf that can't be assigned.\n" },
1753 { "deassign_device",
1754 (PyCFunction)pyxc_deassign_device,
1755 METH_VARARGS | METH_KEYWORDS, "\n"
1756 "Deassign device from IOMMU domain.\n"
1757 " dom [int]: Domain to deassign device from.\n"
1758 " pci_str [str]: PCI devices.\n"
1759 "Returns: [int] 0 on success, or device bdf that can't be deassigned.\n" },
1761 { "sched_id_get",
1762 (PyCFunction)pyxc_sched_id_get,
1763 METH_NOARGS, "\n"
1764 "Get the current scheduler type in use.\n"
1765 "Returns: [int] sched_id.\n" },
1767 { "sedf_domain_set",
1768 (PyCFunction)pyxc_sedf_domain_set,
1769 METH_KEYWORDS, "\n"
1770 "Set the scheduling parameters for a domain when running with Atropos.\n"
1771 " dom [int]: domain to set\n"
1772 " period [long]: domain's scheduling period\n"
1773 " slice [long]: domain's slice per period\n"
1774 " latency [long]: domain's wakeup latency hint\n"
1775 " extratime [int]: domain aware of extratime?\n"
1776 "Returns: [int] 0 on success; -1 on error.\n" },
1778 { "sedf_domain_get",
1779 (PyCFunction)pyxc_sedf_domain_get,
1780 METH_VARARGS, "\n"
1781 "Get the current scheduling parameters for a domain when running with\n"
1782 "the Atropos scheduler."
1783 " dom [int]: domain to query\n"
1784 "Returns: [dict]\n"
1785 " domain [int]: domain ID\n"
1786 " period [long]: scheduler period\n"
1787 " slice [long]: CPU reservation per period\n"
1788 " latency [long]: domain's wakeup latency hint\n"
1789 " extratime [int]: domain aware of extratime?\n"},
1791 { "sched_credit_domain_set",
1792 (PyCFunction)pyxc_sched_credit_domain_set,
1793 METH_KEYWORDS, "\n"
1794 "Set the scheduling parameters for a domain when running with the\n"
1795 "SMP credit scheduler.\n"
1796 " domid [int]: domain id to set\n"
1797 " weight [short]: domain's scheduling weight\n"
1798 "Returns: [int] 0 on success; -1 on error.\n" },
1800 { "sched_credit_domain_get",
1801 (PyCFunction)pyxc_sched_credit_domain_get,
1802 METH_VARARGS, "\n"
1803 "Get the scheduling parameters for a domain when running with the\n"
1804 "SMP credit scheduler.\n"
1805 " domid [int]: domain id to get\n"
1806 "Returns: [dict]\n"
1807 " weight [short]: domain's scheduling weight\n"},
1809 { "evtchn_alloc_unbound",
1810 (PyCFunction)pyxc_evtchn_alloc_unbound,
1811 METH_VARARGS | METH_KEYWORDS, "\n"
1812 "Allocate an unbound port that will await a remote connection.\n"
1813 " dom [int]: Domain whose port space to allocate from.\n"
1814 " remote_dom [int]: Remote domain to accept connections from.\n\n"
1815 "Returns: [int] Unbound event-channel port.\n" },
1817 { "evtchn_reset",
1818 (PyCFunction)pyxc_evtchn_reset,
1819 METH_VARARGS | METH_KEYWORDS, "\n"
1820 "Reset all connections.\n"
1821 " dom [int]: Domain to reset.\n" },
1823 { "physdev_map_pirq",
1824 (PyCFunction)pyxc_physdev_map_pirq,
1825 METH_VARARGS | METH_KEYWORDS, "\n"
1826 "map physical irq to guest pirq.\n"
1827 " dom [int]: Identifier of domain to map for.\n"
1828 " index [int]: physical irq.\n"
1829 " pirq [int]: guest pirq.\n"
1830 "Returns: [long] value of the param.\n" },
1832 { "physdev_pci_access_modify",
1833 (PyCFunction)pyxc_physdev_pci_access_modify,
1834 METH_VARARGS | METH_KEYWORDS, "\n"
1835 "Allow a domain access to a PCI device\n"
1836 " dom [int]: Identifier of domain to be allowed access.\n"
1837 " bus [int]: PCI bus\n"
1838 " dev [int]: PCI slot\n"
1839 " func [int]: PCI function\n"
1840 " enable [int]: Non-zero means enable access; else disable access\n\n"
1841 "Returns: [int] 0 on success; -1 on error.\n" },
1843 { "readconsolering",
1844 (PyCFunction)pyxc_readconsolering,
1845 METH_VARARGS | METH_KEYWORDS, "\n"
1846 "Read Xen's console ring.\n"
1847 " clear [int, 0]: Bool - clear the ring after reading from it?\n\n"
1848 "Returns: [str] string is empty on failure.\n" },
1850 { "physinfo",
1851 (PyCFunction)pyxc_physinfo,
1852 METH_NOARGS, "\n"
1853 "Get information about the physical host machine\n"
1854 "Returns [dict]: information about the hardware"
1855 " [None]: on failure.\n" },
1857 { "xeninfo",
1858 (PyCFunction)pyxc_xeninfo,
1859 METH_NOARGS, "\n"
1860 "Get information about the Xen host\n"
1861 "Returns [dict]: information about Xen"
1862 " [None]: on failure.\n" },
1864 { "shadow_control",
1865 (PyCFunction)pyxc_shadow_control,
1866 METH_VARARGS | METH_KEYWORDS, "\n"
1867 "Set parameter for shadow pagetable interface\n"
1868 " dom [int]: Identifier of domain.\n"
1869 " op [int, 0]: operation\n\n"
1870 "Returns: [int] 0 on success; -1 on error.\n" },
1872 { "shadow_mem_control",
1873 (PyCFunction)pyxc_shadow_mem_control,
1874 METH_VARARGS | METH_KEYWORDS, "\n"
1875 "Set or read shadow pagetable memory use\n"
1876 " dom [int]: Identifier of domain.\n"
1877 " mb [int, -1]: MB of shadow memory this domain should have.\n\n"
1878 "Returns: [int] MB of shadow memory in use by this domain.\n" },
1880 { "domain_setmaxmem",
1881 (PyCFunction)pyxc_domain_setmaxmem,
1882 METH_VARARGS, "\n"
1883 "Set a domain's memory limit\n"
1884 " dom [int]: Identifier of domain.\n"
1885 " maxmem_kb [int]: .\n"
1886 "Returns: [int] 0 on success; -1 on error.\n" },
1888 { "domain_set_target_mem",
1889 (PyCFunction)pyxc_domain_set_target_mem,
1890 METH_VARARGS, "\n"
1891 "Set a domain's memory target\n"
1892 " dom [int]: Identifier of domain.\n"
1893 " mem_kb [int]: .\n"
1894 "Returns: [int] 0 on success; -1 on error.\n" },
1896 { "domain_set_memmap_limit",
1897 (PyCFunction)pyxc_domain_set_memmap_limit,
1898 METH_VARARGS, "\n"
1899 "Set a domain's physical memory mappping limit\n"
1900 " dom [int]: Identifier of domain.\n"
1901 " map_limitkb [int]: .\n"
1902 "Returns: [int] 0 on success; -1 on error.\n" },
1904 #ifdef __ia64__
1905 { "nvram_init",
1906 (PyCFunction)pyxc_nvram_init,
1907 METH_VARARGS, "\n"
1908 "Init nvram in IA64 platform\n"
1909 "Returns: [int] 0 on success; -1 on error.\n" },
1910 { "set_os_type",
1911 (PyCFunction)pyxc_set_os_type,
1912 METH_VARARGS, "\n"
1913 "Set guest OS type on IA64 platform\n"
1914 "Returns: [int] 0 on success; -1 on error.\n" },
1915 #endif /* __ia64__ */
1916 { "domain_ioport_permission",
1917 (PyCFunction)pyxc_domain_ioport_permission,
1918 METH_VARARGS | METH_KEYWORDS, "\n"
1919 "Allow a domain access to a range of IO ports\n"
1920 " dom [int]: Identifier of domain to be allowed access.\n"
1921 " first_port [int]: First IO port\n"
1922 " nr_ports [int]: Number of IO ports\n"
1923 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1924 "Returns: [int] 0 on success; -1 on error.\n" },
1926 { "domain_irq_permission",
1927 (PyCFunction)pyxc_domain_irq_permission,
1928 METH_VARARGS | METH_KEYWORDS, "\n"
1929 "Allow a domain access to a physical IRQ\n"
1930 " dom [int]: Identifier of domain to be allowed access.\n"
1931 " pirq [int]: The Physical IRQ\n"
1932 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1933 "Returns: [int] 0 on success; -1 on error.\n" },
1935 { "domain_iomem_permission",
1936 (PyCFunction)pyxc_domain_iomem_permission,
1937 METH_VARARGS | METH_KEYWORDS, "\n"
1938 "Allow a domain access to a range of IO memory pages\n"
1939 " dom [int]: Identifier of domain to be allowed access.\n"
1940 " first_pfn [long]: First page of I/O Memory\n"
1941 " nr_pfns [long]: Number of pages of I/O Memory (>0)\n"
1942 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1943 "Returns: [int] 0 on success; -1 on error.\n" },
1945 { "pages_to_kib",
1946 (PyCFunction)pyxc_pages_to_kib,
1947 METH_VARARGS, "\n"
1948 "Returns: [int]: The size in KiB of memory spanning the given number "
1949 "of pages.\n" },
1951 { "domain_set_time_offset",
1952 (PyCFunction)pyxc_domain_set_time_offset,
1953 METH_VARARGS, "\n"
1954 "Set a domain's time offset to Dom0's localtime\n"
1955 " dom [int]: Domain whose time offset is being set.\n"
1956 " offset [int]: Time offset from UTC in seconds.\n"
1957 "Returns: [int] 0 on success; -1 on error.\n" },
1959 { "domain_send_trigger",
1960 (PyCFunction)pyxc_domain_send_trigger,
1961 METH_VARARGS | METH_KEYWORDS, "\n"
1962 "Send trigger to a domain.\n"
1963 " dom [int]: Identifier of domain to be sent trigger.\n"
1964 " trigger [int]: Trigger type number.\n"
1965 " vcpu [int]: VCPU to be sent trigger.\n"
1966 "Returns: [int] 0 on success; -1 on error.\n" },
1968 { "send_debug_keys",
1969 (PyCFunction)pyxc_send_debug_keys,
1970 METH_VARARGS | METH_KEYWORDS, "\n"
1971 "Inject debug keys into Xen.\n"
1972 " keys [str]: String of keys to inject.\n" },
1974 #if defined(__i386__) || defined(__x86_64__)
1975 { "domain_check_cpuid",
1976 (PyCFunction)pyxc_dom_check_cpuid,
1977 METH_VARARGS, "\n"
1978 "Apply checks to host CPUID.\n"
1979 " input [long]: Input for cpuid instruction (eax)\n"
1980 " sub_input [long]: Second input (optional, may be None) for cpuid "
1981 " instruction (ecx)\n"
1982 " config [dict]: Dictionary of register\n"
1983 " config [dict]: Dictionary of register, use for checking\n\n"
1984 "Returns: [int] 0 on success; exception on error.\n" },
1986 { "domain_set_cpuid",
1987 (PyCFunction)pyxc_dom_set_cpuid,
1988 METH_VARARGS, "\n"
1989 "Set cpuid response for an input and a domain.\n"
1990 " dom [int]: Identifier of domain.\n"
1991 " input [long]: Input for cpuid instruction (eax)\n"
1992 " sub_input [long]: Second input (optional, may be None) for cpuid "
1993 " instruction (ecx)\n"
1994 " config [dict]: Dictionary of register\n\n"
1995 "Returns: [int] 0 on success; exception on error.\n" },
1997 { "domain_set_policy_cpuid",
1998 (PyCFunction)pyxc_dom_set_policy_cpuid,
1999 METH_VARARGS, "\n"
2000 "Set the default cpuid policy for a domain.\n"
2001 " dom [int]: Identifier of domain.\n\n"
2002 "Returns: [int] 0 on success; exception on error.\n" },
2004 { "domain_set_machine_address_size",
2005 (PyCFunction)pyxc_dom_set_machine_address_size,
2006 METH_VARARGS, "\n"
2007 "Set maximum machine address size for this domain.\n"
2008 " dom [int]: Identifier of domain.\n"
2009 " width [int]: Maximum machine address width.\n" },
2011 { "domain_suppress_spurious_page_faults",
2012 (PyCFunction)pyxc_dom_suppress_spurious_page_faults,
2013 METH_VARARGS, "\n"
2014 "Do not propagate spurious page faults to this guest.\n"
2015 " dom [int]: Identifier of domain.\n" },
2016 #endif
2018 { "tmem_control",
2019 (PyCFunction)pyxc_tmem_control,
2020 METH_VARARGS | METH_KEYWORDS, "\n"
2021 "Do various control on a tmem pool.\n"
2022 " pool_id [int]: Identifier of the tmem pool (-1 == all).\n"
2023 " subop [int]: Supplementary Operation.\n"
2024 " cli_id [int]: Client identifier (-1 == all).\n"
2025 " arg1 [int]: Argument.\n"
2026 " arg2 [int]: Argument.\n"
2027 " buf [str]: Buffer.\n\n"
2028 "Returns: [int] 0 or [str] tmem info on success; exception on error.\n" },
2030 { NULL, NULL, 0, NULL }
2031 };
2034 static PyObject *PyXc_getattr(PyObject *obj, char *name)
2036 return Py_FindMethod(pyxc_methods, obj, name);
2039 static PyObject *PyXc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2041 XcObject *self = (XcObject *)type->tp_alloc(type, 0);
2043 if (self == NULL)
2044 return NULL;
2046 self->xc_handle = -1;
2048 return (PyObject *)self;
2051 static int
2052 PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
2054 if ((self->xc_handle = xc_interface_open()) == -1) {
2055 pyxc_error_to_exception();
2056 return -1;
2059 return 0;
2062 static void PyXc_dealloc(XcObject *self)
2064 if (self->xc_handle != -1) {
2065 xc_interface_close(self->xc_handle);
2066 self->xc_handle = -1;
2069 self->ob_type->tp_free((PyObject *)self);
2072 static PyTypeObject PyXcType = {
2073 PyObject_HEAD_INIT(NULL)
2074 0,
2075 PKG "." CLS,
2076 sizeof(XcObject),
2077 0,
2078 (destructor)PyXc_dealloc, /* tp_dealloc */
2079 NULL, /* tp_print */
2080 PyXc_getattr, /* tp_getattr */
2081 NULL, /* tp_setattr */
2082 NULL, /* tp_compare */
2083 NULL, /* tp_repr */
2084 NULL, /* tp_as_number */
2085 NULL, /* tp_as_sequence */
2086 NULL, /* tp_as_mapping */
2087 NULL, /* tp_hash */
2088 NULL, /* tp_call */
2089 NULL, /* tp_str */
2090 NULL, /* tp_getattro */
2091 NULL, /* tp_setattro */
2092 NULL, /* tp_as_buffer */
2093 Py_TPFLAGS_DEFAULT, /* tp_flags */
2094 "Xen client connections", /* tp_doc */
2095 NULL, /* tp_traverse */
2096 NULL, /* tp_clear */
2097 NULL, /* tp_richcompare */
2098 0, /* tp_weaklistoffset */
2099 NULL, /* tp_iter */
2100 NULL, /* tp_iternext */
2101 pyxc_methods, /* tp_methods */
2102 NULL, /* tp_members */
2103 NULL, /* tp_getset */
2104 NULL, /* tp_base */
2105 NULL, /* tp_dict */
2106 NULL, /* tp_descr_get */
2107 NULL, /* tp_descr_set */
2108 0, /* tp_dictoffset */
2109 (initproc)PyXc_init, /* tp_init */
2110 NULL, /* tp_alloc */
2111 PyXc_new, /* tp_new */
2112 };
2114 static PyMethodDef xc_methods[] = { { NULL } };
2116 PyMODINIT_FUNC initxc(void)
2118 PyObject *m;
2120 if (PyType_Ready(&PyXcType) < 0)
2121 return;
2123 m = Py_InitModule(PKG, xc_methods);
2125 if (m == NULL)
2126 return;
2128 xc_error_obj = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
2129 zero = PyInt_FromLong(0);
2131 /* KAF: This ensures that we get debug output in a timely manner. */
2132 setbuf(stdout, NULL);
2133 setbuf(stderr, NULL);
2135 Py_INCREF(&PyXcType);
2136 PyModule_AddObject(m, CLS, (PyObject *)&PyXcType);
2138 Py_INCREF(xc_error_obj);
2139 PyModule_AddObject(m, "Error", xc_error_obj);
2141 /* Expose some libxc constants to Python */
2142 PyModule_AddIntConstant(m, "XEN_SCHEDULER_SEDF", XEN_SCHEDULER_SEDF);
2143 PyModule_AddIntConstant(m, "XEN_SCHEDULER_CREDIT", XEN_SCHEDULER_CREDIT);
2148 /*
2149 * Local variables:
2150 * c-indent-level: 4
2151 * c-basic-offset: 4
2152 * End:
2153 */