debuggers.hg

view tools/python/xen/lowlevel/xc/xc.c @ 16970:04e24b9dcc16

xend: Obey localtime config option for HVM guests as well as PV guests.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jan 29 15:15:51 2008 +0000 (2008-01-29)
parents 98c2665056ea
children 49f87f3c2cb8
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 cpumap |= (uint64_t)1 << PyInt_AsLong(PyList_GetItem(cpulist, i));
231 }
233 if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
234 return pyxc_error_to_exception();
236 Py_INCREF(zero);
237 return zero;
238 }
240 static PyObject *pyxc_domain_setcpuweight(XcObject *self,
241 PyObject *args,
242 PyObject *kwds)
243 {
244 uint32_t dom;
245 float cpuweight = 1;
247 static char *kwd_list[] = { "domid", "cpuweight", NULL };
249 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|f", kwd_list,
250 &dom, &cpuweight) )
251 return NULL;
253 if ( xc_domain_setcpuweight(self->xc_handle, dom, cpuweight) != 0 )
254 return pyxc_error_to_exception();
256 Py_INCREF(zero);
257 return zero;
258 }
260 static PyObject *pyxc_domain_sethandle(XcObject *self, PyObject *args)
261 {
262 int i;
263 uint32_t dom;
264 PyObject *pyhandle;
265 xen_domain_handle_t handle;
267 if (!PyArg_ParseTuple(args, "iO", &dom, &pyhandle))
268 return NULL;
270 if ( !PyList_Check(pyhandle) ||
271 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
272 {
273 goto out_exception;
274 }
276 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
277 {
278 PyObject *p = PyList_GetItem(pyhandle, i);
279 if ( !PyInt_Check(p) )
280 goto out_exception;
281 handle[i] = (uint8_t)PyInt_AsLong(p);
282 }
284 if (xc_domain_sethandle(self->xc_handle, dom, handle) < 0)
285 return pyxc_error_to_exception();
287 Py_INCREF(zero);
288 return zero;
290 out_exception:
291 PyErr_SetFromErrno(xc_error_obj);
292 return NULL;
293 }
296 static PyObject *pyxc_domain_getinfo(XcObject *self,
297 PyObject *args,
298 PyObject *kwds)
299 {
300 PyObject *list, *info_dict, *pyhandle;
302 uint32_t first_dom = 0;
303 int max_doms = 1024, nr_doms, i, j;
304 xc_dominfo_t *info;
306 static char *kwd_list[] = { "first_dom", "max_doms", NULL };
308 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
309 &first_dom, &max_doms) )
310 return NULL;
312 if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL )
313 return PyErr_NoMemory();
315 nr_doms = xc_domain_getinfo(self->xc_handle, first_dom, max_doms, info);
317 if (nr_doms < 0)
318 {
319 free(info);
320 return pyxc_error_to_exception();
321 }
323 list = PyList_New(nr_doms);
324 for ( i = 0 ; i < nr_doms; i++ )
325 {
326 info_dict = Py_BuildValue(
327 "{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
328 ",s:L,s:L,s:L,s:i,s:i}",
329 "domid", (int)info[i].domid,
330 "online_vcpus", info[i].nr_online_vcpus,
331 "max_vcpu_id", info[i].max_vcpu_id,
332 "hvm", info[i].hvm,
333 "dying", info[i].dying,
334 "crashed", info[i].crashed,
335 "shutdown", info[i].shutdown,
336 "paused", info[i].paused,
337 "blocked", info[i].blocked,
338 "running", info[i].running,
339 "mem_kb", (long long)info[i].nr_pages*(XC_PAGE_SIZE/1024),
340 "cpu_time", (long long)info[i].cpu_time,
341 "maxmem_kb", (long long)info[i].max_memkb,
342 "ssidref", (int)info[i].ssidref,
343 "shutdown_reason", info[i].shutdown_reason);
344 pyhandle = PyList_New(sizeof(xen_domain_handle_t));
345 if ( (pyhandle == NULL) || (info_dict == NULL) )
346 {
347 Py_DECREF(list);
348 if ( pyhandle != NULL ) { Py_DECREF(pyhandle); }
349 if ( info_dict != NULL ) { Py_DECREF(info_dict); }
350 free(info);
351 return NULL;
352 }
353 for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
354 PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
355 PyDict_SetItemString(info_dict, "handle", pyhandle);
356 Py_DECREF(pyhandle);
357 PyList_SetItem(list, i, info_dict);
358 }
360 free(info);
362 return list;
363 }
365 static PyObject *pyxc_vcpu_getinfo(XcObject *self,
366 PyObject *args,
367 PyObject *kwds)
368 {
369 PyObject *info_dict, *cpulist;
371 uint32_t dom, vcpu = 0;
372 xc_vcpuinfo_t info;
373 int rc, i;
374 uint64_t cpumap;
376 static char *kwd_list[] = { "domid", "vcpu", NULL };
378 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
379 &dom, &vcpu) )
380 return NULL;
382 rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
383 if ( rc < 0 )
384 return pyxc_error_to_exception();
385 rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, &cpumap);
386 if ( rc < 0 )
387 return pyxc_error_to_exception();
389 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}",
390 "online", info.online,
391 "blocked", info.blocked,
392 "running", info.running,
393 "cpu_time", info.cpu_time,
394 "cpu", info.cpu);
396 cpulist = PyList_New(0);
397 for ( i = 0; cpumap != 0; i++ )
398 {
399 if ( cpumap & 1 )
400 PyList_Append(cpulist, PyInt_FromLong(i));
401 cpumap >>= 1;
402 }
403 PyDict_SetItemString(info_dict, "cpumap", cpulist);
404 Py_DECREF(cpulist);
405 return info_dict;
406 }
408 static PyObject *pyxc_linux_build(XcObject *self,
409 PyObject *args,
410 PyObject *kwds)
411 {
412 uint32_t domid;
413 struct xc_dom_image *dom;
414 char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
415 int flags = 0;
416 int store_evtchn, console_evtchn;
417 int vhpt = 0;
418 unsigned int mem_mb;
419 unsigned long store_mfn = 0;
420 unsigned long console_mfn = 0;
421 PyObject* elfnote_dict;
422 PyObject* elfnote = NULL;
423 PyObject* ret;
424 int i;
426 static char *kwd_list[] = { "domid", "store_evtchn", "memsize",
427 "console_evtchn", "image",
428 /* optional */
429 "ramdisk", "cmdline", "flags",
430 "features", "vhpt", NULL };
432 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssisi", kwd_list,
433 &domid, &store_evtchn, &mem_mb,
434 &console_evtchn, &image,
435 /* optional */
436 &ramdisk, &cmdline, &flags,
437 &features, &vhpt) )
438 return NULL;
440 xc_dom_loginit();
441 if (!(dom = xc_dom_allocate(cmdline, features)))
442 return pyxc_error_to_exception();
444 /* for IA64 */
445 dom->vhpt_size_log2 = vhpt;
447 if ( xc_dom_linux_build(self->xc_handle, dom, domid, mem_mb, image,
448 ramdisk, flags, store_evtchn, &store_mfn,
449 console_evtchn, &console_mfn) != 0 ) {
450 goto out;
451 }
453 if ( !(elfnote_dict = PyDict_New()) )
454 goto out;
456 for ( i = 0; i < ARRAY_SIZE(dom->parms.elf_notes); i++ )
457 {
458 switch ( dom->parms.elf_notes[i].type )
459 {
460 case XEN_ENT_NONE:
461 continue;
462 case XEN_ENT_LONG:
463 elfnote = Py_BuildValue("k", dom->parms.elf_notes[i].data.num);
464 break;
465 case XEN_ENT_STR:
466 elfnote = Py_BuildValue("s", dom->parms.elf_notes[i].data.str);
467 break;
468 }
469 PyDict_SetItemString(elfnote_dict,
470 dom->parms.elf_notes[i].name,
471 elfnote);
472 Py_DECREF(elfnote);
473 }
475 ret = Py_BuildValue("{s:i,s:i,s:N}",
476 "store_mfn", store_mfn,
477 "console_mfn", console_mfn,
478 "notes", elfnote_dict);
480 if ( dom->arch_hooks->native_protocol )
481 {
482 PyObject *native_protocol =
483 Py_BuildValue("s", dom->arch_hooks->native_protocol);
484 PyDict_SetItemString(ret, "native_protocol", native_protocol);
485 Py_DECREF(native_protocol);
486 }
488 xc_dom_release(dom);
490 return ret;
492 out:
493 xc_dom_release(dom);
494 return pyxc_error_to_exception();
495 }
497 static PyObject *pyxc_get_hvm_param(XcObject *self,
498 PyObject *args,
499 PyObject *kwds)
500 {
501 uint32_t dom;
502 int param;
503 unsigned long value;
505 static char *kwd_list[] = { "domid", "param", NULL };
506 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
507 &dom, &param) )
508 return NULL;
510 if ( xc_get_hvm_param(self->xc_handle, dom, param, &value) != 0 )
511 return pyxc_error_to_exception();
513 return PyLong_FromUnsignedLong(value);
515 }
517 static PyObject *pyxc_set_hvm_param(XcObject *self,
518 PyObject *args,
519 PyObject *kwds)
520 {
521 uint32_t dom;
522 int param;
523 uint64_t value;
525 static char *kwd_list[] = { "domid", "param", "value", NULL };
526 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiL", kwd_list,
527 &dom, &param, &value) )
528 return NULL;
530 if ( xc_set_hvm_param(self->xc_handle, dom, param, value) != 0 )
531 return pyxc_error_to_exception();
533 Py_INCREF(zero);
534 return zero;
535 }
537 static int token_value(char *token)
538 {
539 token = strchr(token, 'x') + 1;
540 return strtol(token, NULL, 16);
541 }
543 static int next_bdf(char **str, int *seg, int *bus, int *dev, int *func)
544 {
545 char *token;
547 if ( !(*str) || !strchr(*str, ',') )
548 return 0;
550 token = *str;
551 *seg = token_value(token);
552 token = strchr(token, ',') + 1;
553 *bus = token_value(token);
554 token = strchr(token, ',') + 1;
555 *dev = token_value(token);
556 token = strchr(token, ',') + 1;
557 *func = token_value(token);
558 token = strchr(token, ',');
559 *str = token ? token + 1 : NULL;
561 return 1;
562 }
564 static PyObject *pyxc_test_assign_device(XcObject *self,
565 PyObject *args,
566 PyObject *kwds)
567 {
568 uint32_t dom;
569 char *pci_str;
570 uint32_t bdf = 0;
571 int seg, bus, dev, func;
573 static char *kwd_list[] = { "domid", "pci", NULL };
574 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is", kwd_list,
575 &dom, &pci_str) )
576 return NULL;
578 while ( next_bdf(&pci_str, &seg, &bus, &dev, &func) )
579 {
580 bdf |= (bus & 0xff) << 16;
581 bdf |= (dev & 0x1f) << 11;
582 bdf |= (func & 0x7) << 8;
584 if ( xc_test_assign_device(self->xc_handle, dom, bdf) != 0 )
585 break;
587 bdf = 0;
588 }
590 return Py_BuildValue("i", bdf);
591 }
593 #ifdef __ia64__
594 static PyObject *pyxc_nvram_init(XcObject *self,
595 PyObject *args)
596 {
597 char *dom_name;
598 uint32_t dom;
600 if ( !PyArg_ParseTuple(args, "si", &dom_name, &dom) )
601 return NULL;
603 xc_ia64_nvram_init(self->xc_handle, dom_name, dom);
605 Py_INCREF(zero);
606 return zero;
607 }
609 static PyObject *pyxc_set_os_type(XcObject *self,
610 PyObject *args)
611 {
612 char *os_type;
613 uint32_t dom;
615 if ( !PyArg_ParseTuple(args, "si", &os_type, &dom) )
616 return NULL;
618 xc_ia64_set_os_type(self->xc_handle, os_type, dom);
620 Py_INCREF(zero);
621 return zero;
622 }
623 #endif /* __ia64__ */
625 static PyObject *pyxc_hvm_build(XcObject *self,
626 PyObject *args,
627 PyObject *kwds)
628 {
629 uint32_t dom;
630 #if !defined(__ia64__)
631 struct hvm_info_table *va_hvm;
632 uint8_t *va_map, sum;
633 int i;
634 #endif
635 char *image;
636 int memsize, vcpus = 1, acpi = 0, apic = 1;
638 static char *kwd_list[] = { "domid",
639 "memsize", "image", "vcpus", "acpi",
640 "apic", NULL };
641 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iii", kwd_list,
642 &dom, &memsize,
643 &image, &vcpus, &acpi, &apic) )
644 return NULL;
646 if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
647 return pyxc_error_to_exception();
649 #if !defined(__ia64__)
650 /* Set up the HVM info table. */
651 va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
652 PROT_READ | PROT_WRITE,
653 HVM_INFO_PFN);
654 if ( va_map == NULL )
655 return PyErr_SetFromErrno(xc_error_obj);
656 va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
657 memset(va_hvm, 0, sizeof(*va_hvm));
658 strncpy(va_hvm->signature, "HVM INFO", 8);
659 va_hvm->length = sizeof(struct hvm_info_table);
660 va_hvm->acpi_enabled = acpi;
661 va_hvm->apic_mode = apic;
662 va_hvm->nr_vcpus = vcpus;
663 for ( i = 0, sum = 0; i < va_hvm->length; i++ )
664 sum += ((uint8_t *)va_hvm)[i];
665 va_hvm->checksum = -sum;
666 munmap(va_map, XC_PAGE_SIZE);
667 #endif
669 return Py_BuildValue("{}");
670 }
672 static PyObject *pyxc_evtchn_alloc_unbound(XcObject *self,
673 PyObject *args,
674 PyObject *kwds)
675 {
676 uint32_t dom, remote_dom;
677 int port;
679 static char *kwd_list[] = { "domid", "remote_dom", NULL };
681 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
682 &dom, &remote_dom) )
683 return NULL;
685 if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) < 0 )
686 return pyxc_error_to_exception();
688 return PyInt_FromLong(port);
689 }
691 static PyObject *pyxc_evtchn_reset(XcObject *self,
692 PyObject *args,
693 PyObject *kwds)
694 {
695 uint32_t dom;
697 static char *kwd_list[] = { "dom", NULL };
699 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
700 return NULL;
702 if ( xc_evtchn_reset(self->xc_handle, dom) < 0 )
703 return pyxc_error_to_exception();
705 Py_INCREF(zero);
706 return zero;
707 }
709 static PyObject *pyxc_physdev_pci_access_modify(XcObject *self,
710 PyObject *args,
711 PyObject *kwds)
712 {
713 uint32_t dom;
714 int bus, dev, func, enable, ret;
716 static char *kwd_list[] = { "domid", "bus", "dev", "func", "enable", NULL };
718 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list,
719 &dom, &bus, &dev, &func, &enable) )
720 return NULL;
722 ret = xc_physdev_pci_access_modify(
723 self->xc_handle, dom, bus, dev, func, enable);
724 if ( ret != 0 )
725 return pyxc_error_to_exception();
727 Py_INCREF(zero);
728 return zero;
729 }
731 static PyObject *pyxc_readconsolering(XcObject *self,
732 PyObject *args,
733 PyObject *kwds)
734 {
735 unsigned int clear = 0, index = 0, incremental = 0;
736 char _str[32768], *str = _str;
737 unsigned int count = 32768;
738 int ret;
740 static char *kwd_list[] = { "clear", "index", "incremental", NULL };
742 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iii", kwd_list,
743 &clear, &index, &incremental) )
744 return NULL;
746 ret = xc_readconsolering(self->xc_handle, &str, &count, clear,
747 incremental, &index);
748 if ( ret < 0 )
749 return pyxc_error_to_exception();
751 return PyString_FromStringAndSize(str, count);
752 }
755 static unsigned long pages_to_kib(unsigned long pages)
756 {
757 return pages * (XC_PAGE_SIZE / 1024);
758 }
761 static PyObject *pyxc_pages_to_kib(XcObject *self, PyObject *args)
762 {
763 unsigned long pages;
765 if (!PyArg_ParseTuple(args, "l", &pages))
766 return NULL;
768 return PyLong_FromUnsignedLong(pages_to_kib(pages));
769 }
772 static PyObject *pyxc_physinfo(XcObject *self)
773 {
774 #define MAX_CPU_ID 255
775 xc_physinfo_t info;
776 char cpu_cap[128], *p=cpu_cap, *q=cpu_cap;
777 int i, j, max_cpu_id;
778 PyObject *ret_obj, *node_to_cpu_obj;
779 xc_cpu_to_node_t map[MAX_CPU_ID + 1];
781 set_xen_guest_handle(info.cpu_to_node, map);
782 info.max_cpu_id = MAX_CPU_ID;
784 if ( xc_physinfo(self->xc_handle, &info) != 0 )
785 return pyxc_error_to_exception();
787 *q = 0;
788 for ( i = 0; i < sizeof(info.hw_cap)/4; i++ )
789 {
790 p += sprintf(p, "%08x:", info.hw_cap[i]);
791 if ( info.hw_cap[i] )
792 q = p;
793 }
794 if ( q > cpu_cap )
795 *(q-1) = 0;
797 ret_obj = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s}",
798 "nr_nodes", info.nr_nodes,
799 "max_cpu_id", info.max_cpu_id,
800 "threads_per_core", info.threads_per_core,
801 "cores_per_socket", info.cores_per_socket,
802 "nr_cpus", info.nr_cpus,
803 "total_memory", pages_to_kib(info.total_pages),
804 "free_memory", pages_to_kib(info.free_pages),
805 "scrub_memory", pages_to_kib(info.scrub_pages),
806 "cpu_khz", info.cpu_khz,
807 "hw_caps", cpu_cap);
809 max_cpu_id = info.max_cpu_id;
810 if ( max_cpu_id > MAX_CPU_ID )
811 max_cpu_id = MAX_CPU_ID;
813 /* Construct node-to-cpu lists. */
814 node_to_cpu_obj = PyList_New(0);
816 /* Make a list for each node. */
817 for ( i = 0; i < info.nr_nodes; i++ )
818 {
819 PyObject *cpus = PyList_New(0);
820 for ( j = 0; j <= max_cpu_id; j++ )
821 if ( i == map[j])
822 PyList_Append(cpus, PyInt_FromLong(j));
823 PyList_Append(node_to_cpu_obj, cpus);
824 }
826 PyDict_SetItemString(ret_obj, "node_to_cpu", node_to_cpu_obj);
828 return ret_obj;
829 #undef MAX_CPU_ID
830 }
832 static PyObject *pyxc_xeninfo(XcObject *self)
833 {
834 xen_extraversion_t xen_extra;
835 xen_compile_info_t xen_cc;
836 xen_changeset_info_t xen_chgset;
837 xen_capabilities_info_t xen_caps;
838 xen_platform_parameters_t p_parms;
839 long xen_version;
840 long xen_pagesize;
841 char str[128];
843 xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
845 if ( xc_version(self->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
846 return pyxc_error_to_exception();
848 if ( xc_version(self->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
849 return pyxc_error_to_exception();
851 if ( xc_version(self->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
852 return pyxc_error_to_exception();
854 if ( xc_version(self->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
855 return pyxc_error_to_exception();
857 if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) != 0 )
858 return pyxc_error_to_exception();
860 sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
862 xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
863 if (xen_pagesize < 0 )
864 return pyxc_error_to_exception();
866 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}",
867 "xen_major", xen_version >> 16,
868 "xen_minor", (xen_version & 0xffff),
869 "xen_extra", xen_extra,
870 "xen_caps", xen_caps,
871 "xen_pagesize", xen_pagesize,
872 "platform_params", str,
873 "xen_changeset", xen_chgset,
874 "cc_compiler", xen_cc.compiler,
875 "cc_compile_by", xen_cc.compile_by,
876 "cc_compile_domain", xen_cc.compile_domain,
877 "cc_compile_date", xen_cc.compile_date);
878 }
881 static PyObject *pyxc_sedf_domain_set(XcObject *self,
882 PyObject *args,
883 PyObject *kwds)
884 {
885 uint32_t domid;
886 uint64_t period, slice, latency;
887 uint16_t extratime, weight;
888 static char *kwd_list[] = { "domid", "period", "slice",
889 "latency", "extratime", "weight",NULL };
891 if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLhh", kwd_list,
892 &domid, &period, &slice,
893 &latency, &extratime, &weight) )
894 return NULL;
895 if ( xc_sedf_domain_set(self->xc_handle, domid, period,
896 slice, latency, extratime,weight) != 0 )
897 return pyxc_error_to_exception();
899 Py_INCREF(zero);
900 return zero;
901 }
903 static PyObject *pyxc_sedf_domain_get(XcObject *self, PyObject *args)
904 {
905 uint32_t domid;
906 uint64_t period, slice,latency;
907 uint16_t weight, extratime;
909 if(!PyArg_ParseTuple(args, "i", &domid))
910 return NULL;
912 if (xc_sedf_domain_get(self->xc_handle, domid, &period,
913 &slice,&latency,&extratime,&weight))
914 return pyxc_error_to_exception();
916 return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
917 "domid", domid,
918 "period", period,
919 "slice", slice,
920 "latency", latency,
921 "extratime", extratime,
922 "weight", weight);
923 }
925 static PyObject *pyxc_shadow_control(PyObject *self,
926 PyObject *args,
927 PyObject *kwds)
928 {
929 XcObject *xc = (XcObject *)self;
931 uint32_t dom;
932 int op=0;
934 static char *kwd_list[] = { "dom", "op", NULL };
936 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
937 &dom, &op) )
938 return NULL;
940 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL, 0, NULL)
941 < 0 )
942 return pyxc_error_to_exception();
944 Py_INCREF(zero);
945 return zero;
946 }
948 static PyObject *pyxc_shadow_mem_control(PyObject *self,
949 PyObject *args,
950 PyObject *kwds)
951 {
952 XcObject *xc = (XcObject *)self;
953 int op;
954 uint32_t dom;
955 int mbarg = -1;
956 unsigned long mb;
958 static char *kwd_list[] = { "dom", "mb", NULL };
960 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
961 &dom, &mbarg) )
962 return NULL;
964 if ( mbarg < 0 )
965 op = XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION;
966 else
967 {
968 mb = mbarg;
969 op = XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION;
970 }
971 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, &mb, 0, NULL) < 0 )
972 return pyxc_error_to_exception();
974 mbarg = mb;
975 return Py_BuildValue("i", mbarg);
976 }
978 static PyObject *pyxc_sched_id_get(XcObject *self) {
980 int sched_id;
981 if (xc_sched_id(self->xc_handle, &sched_id) != 0)
982 return PyErr_SetFromErrno(xc_error_obj);
984 return Py_BuildValue("i", sched_id);
985 }
987 static PyObject *pyxc_sched_credit_domain_set(XcObject *self,
988 PyObject *args,
989 PyObject *kwds)
990 {
991 uint32_t domid;
992 uint16_t weight;
993 uint16_t cap;
994 static char *kwd_list[] = { "domid", "weight", "cap", NULL };
995 static char kwd_type[] = "I|HH";
996 struct xen_domctl_sched_credit sdom;
998 weight = 0;
999 cap = (uint16_t)~0U;
1000 if( !PyArg_ParseTupleAndKeywords(args, kwds, kwd_type, kwd_list,
1001 &domid, &weight, &cap) )
1002 return NULL;
1004 sdom.weight = weight;
1005 sdom.cap = cap;
1007 if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 )
1008 return pyxc_error_to_exception();
1010 Py_INCREF(zero);
1011 return zero;
1014 static PyObject *pyxc_sched_credit_domain_get(XcObject *self, PyObject *args)
1016 uint32_t domid;
1017 struct xen_domctl_sched_credit sdom;
1019 if( !PyArg_ParseTuple(args, "I", &domid) )
1020 return NULL;
1022 if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 )
1023 return pyxc_error_to_exception();
1025 return Py_BuildValue("{s:H,s:H}",
1026 "weight", sdom.weight,
1027 "cap", sdom.cap);
1030 static PyObject *pyxc_domain_setmaxmem(XcObject *self, PyObject *args)
1032 uint32_t dom;
1033 unsigned int maxmem_kb;
1035 if (!PyArg_ParseTuple(args, "ii", &dom, &maxmem_kb))
1036 return NULL;
1038 if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0)
1039 return pyxc_error_to_exception();
1041 Py_INCREF(zero);
1042 return zero;
1045 static PyObject *pyxc_domain_set_memmap_limit(XcObject *self, PyObject *args)
1047 uint32_t dom;
1048 unsigned int maplimit_kb;
1050 if ( !PyArg_ParseTuple(args, "ii", &dom, &maplimit_kb) )
1051 return NULL;
1053 if ( xc_domain_set_memmap_limit(self->xc_handle, dom, maplimit_kb) != 0 )
1054 return pyxc_error_to_exception();
1056 Py_INCREF(zero);
1057 return zero;
1060 static PyObject *pyxc_domain_memory_increase_reservation(XcObject *self,
1061 PyObject *args,
1062 PyObject *kwds)
1064 uint32_t dom;
1065 unsigned long mem_kb;
1066 unsigned int extent_order = 0 , address_bits = 0;
1067 unsigned long nr_extents;
1069 static char *kwd_list[] = { "domid", "mem_kb", "extent_order", "address_bits", NULL };
1071 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "il|ii", kwd_list,
1072 &dom, &mem_kb, &extent_order, &address_bits) )
1073 return NULL;
1075 /* round down to nearest power of 2. Assume callers using extent_order>0
1076 know what they are doing */
1077 nr_extents = (mem_kb / (XC_PAGE_SIZE/1024)) >> extent_order;
1078 if ( xc_domain_memory_increase_reservation(self->xc_handle, dom,
1079 nr_extents, extent_order,
1080 address_bits, NULL) )
1081 return pyxc_error_to_exception();
1083 Py_INCREF(zero);
1084 return zero;
1087 static PyObject *pyxc_domain_ioport_permission(XcObject *self,
1088 PyObject *args,
1089 PyObject *kwds)
1091 uint32_t dom;
1092 int first_port, nr_ports, allow_access, ret;
1094 static char *kwd_list[] = { "domid", "first_port", "nr_ports", "allow_access", NULL };
1096 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiii", kwd_list,
1097 &dom, &first_port, &nr_ports, &allow_access) )
1098 return NULL;
1100 ret = xc_domain_ioport_permission(
1101 self->xc_handle, dom, first_port, nr_ports, allow_access);
1102 if ( ret != 0 )
1103 return pyxc_error_to_exception();
1105 Py_INCREF(zero);
1106 return zero;
1109 static PyObject *pyxc_domain_irq_permission(PyObject *self,
1110 PyObject *args,
1111 PyObject *kwds)
1113 XcObject *xc = (XcObject *)self;
1114 uint32_t dom;
1115 int pirq, allow_access, ret;
1117 static char *kwd_list[] = { "domid", "pirq", "allow_access", NULL };
1119 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list,
1120 &dom, &pirq, &allow_access) )
1121 return NULL;
1123 ret = xc_domain_irq_permission(
1124 xc->xc_handle, dom, pirq, allow_access);
1125 if ( ret != 0 )
1126 return pyxc_error_to_exception();
1128 Py_INCREF(zero);
1129 return zero;
1132 static PyObject *pyxc_domain_iomem_permission(PyObject *self,
1133 PyObject *args,
1134 PyObject *kwds)
1136 XcObject *xc = (XcObject *)self;
1137 uint32_t dom;
1138 unsigned long first_pfn, nr_pfns, allow_access, ret;
1140 static char *kwd_list[] = { "domid", "first_pfn", "nr_pfns", "allow_access", NULL };
1142 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illi", kwd_list,
1143 &dom, &first_pfn, &nr_pfns, &allow_access) )
1144 return NULL;
1146 ret = xc_domain_iomem_permission(
1147 xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
1148 if ( ret != 0 )
1149 return pyxc_error_to_exception();
1151 Py_INCREF(zero);
1152 return zero;
1155 static PyObject *pyxc_domain_set_time_offset(XcObject *self, PyObject *args)
1157 uint32_t dom;
1158 int32_t offset;
1160 if (!PyArg_ParseTuple(args, "ii", &dom, &offset))
1161 return NULL;
1163 if (xc_domain_set_time_offset(self->xc_handle, dom, offset) != 0)
1164 return pyxc_error_to_exception();
1166 Py_INCREF(zero);
1167 return zero;
1170 static PyObject *pyxc_domain_send_trigger(XcObject *self,
1171 PyObject *args,
1172 PyObject *kwds)
1174 uint32_t dom;
1175 int trigger, vcpu = 0;
1177 static char *kwd_list[] = { "domid", "trigger", "vcpu", NULL };
1179 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii|i", kwd_list,
1180 &dom, &trigger, &vcpu) )
1181 return NULL;
1183 if (xc_domain_send_trigger(self->xc_handle, dom, trigger, vcpu) != 0)
1184 return pyxc_error_to_exception();
1186 Py_INCREF(zero);
1187 return zero;
1190 static PyObject *pyxc_send_debug_keys(XcObject *self,
1191 PyObject *args,
1192 PyObject *kwds)
1194 char *keys;
1196 static char *kwd_list[] = { "keys", NULL };
1198 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list, &keys) )
1199 return NULL;
1201 if ( xc_send_debug_keys(self->xc_handle, keys) != 0 )
1202 return pyxc_error_to_exception();
1204 Py_INCREF(zero);
1205 return zero;
1208 static PyObject *dom_op(XcObject *self, PyObject *args,
1209 int (*fn)(int, uint32_t))
1211 uint32_t dom;
1213 if (!PyArg_ParseTuple(args, "i", &dom))
1214 return NULL;
1216 if (fn(self->xc_handle, dom) != 0)
1217 return pyxc_error_to_exception();
1219 Py_INCREF(zero);
1220 return zero;
1223 #ifdef __powerpc__
1224 static PyObject *pyxc_alloc_real_mode_area(XcObject *self,
1225 PyObject *args,
1226 PyObject *kwds)
1228 uint32_t dom;
1229 unsigned int log;
1231 static char *kwd_list[] = { "dom", "log", NULL };
1233 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
1234 &dom, &log) )
1235 return NULL;
1237 if ( xc_alloc_real_mode_area(self->xc_handle, dom, log) )
1238 return pyxc_error_to_exception();
1240 Py_INCREF(zero);
1241 return zero;
1243 #endif /* powerpc */
1245 static PyMethodDef pyxc_methods[] = {
1246 { "handle",
1247 (PyCFunction)pyxc_handle,
1248 METH_NOARGS, "\n"
1249 "Query the xc control interface file descriptor.\n\n"
1250 "Returns: [int] file descriptor\n" },
1252 { "domain_create",
1253 (PyCFunction)pyxc_domain_create,
1254 METH_VARARGS | METH_KEYWORDS, "\n"
1255 "Create a new domain.\n"
1256 " dom [int, 0]: Domain identifier to use (allocated if zero).\n"
1257 "Returns: [int] new domain identifier; -1 on error.\n" },
1259 { "domain_max_vcpus",
1260 (PyCFunction)pyxc_domain_max_vcpus,
1261 METH_VARARGS, "\n"
1262 "Set the maximum number of VCPUs a domain may create.\n"
1263 " dom [int, 0]: Domain identifier to use.\n"
1264 " max [int, 0]: New maximum number of VCPUs in domain.\n"
1265 "Returns: [int] 0 on success; -1 on error.\n" },
1267 { "domain_dumpcore",
1268 (PyCFunction)pyxc_domain_dumpcore,
1269 METH_VARARGS, "\n"
1270 "Dump core of a domain.\n"
1271 " dom [int]: Identifier of domain to dump core of.\n"
1272 " corefile [string]: Name of corefile to be created.\n\n"
1273 "Returns: [int] 0 on success; -1 on error.\n" },
1275 { "domain_pause",
1276 (PyCFunction)pyxc_domain_pause,
1277 METH_VARARGS, "\n"
1278 "Temporarily pause execution of a domain.\n"
1279 " dom [int]: Identifier of domain to be paused.\n\n"
1280 "Returns: [int] 0 on success; -1 on error.\n" },
1282 { "domain_unpause",
1283 (PyCFunction)pyxc_domain_unpause,
1284 METH_VARARGS, "\n"
1285 "(Re)start execution of a domain.\n"
1286 " dom [int]: Identifier of domain to be unpaused.\n\n"
1287 "Returns: [int] 0 on success; -1 on error.\n" },
1289 { "domain_destroy",
1290 (PyCFunction)pyxc_domain_destroy,
1291 METH_VARARGS, "\n"
1292 "Destroy a domain.\n"
1293 " dom [int]: Identifier of domain to be destroyed.\n\n"
1294 "Returns: [int] 0 on success; -1 on error.\n" },
1296 { "domain_destroy_hook",
1297 (PyCFunction)pyxc_domain_destroy_hook,
1298 METH_VARARGS, "\n"
1299 "Add a hook for arch stuff before destroy a domain.\n"
1300 " dom [int]: Identifier of domain to be destroyed.\n\n"
1301 "Returns: [int] 0 on success; -1 on error.\n" },
1303 { "domain_resume",
1304 (PyCFunction)pyxc_domain_resume,
1305 METH_VARARGS, "\n"
1306 "Resume execution of a suspended domain.\n"
1307 " dom [int]: Identifier of domain to be resumed.\n"
1308 " fast [int]: Use cooperative resume.\n\n"
1309 "Returns: [int] 0 on success; -1 on error.\n" },
1311 { "domain_shutdown",
1312 (PyCFunction)pyxc_domain_shutdown,
1313 METH_VARARGS, "\n"
1314 "Shutdown a domain.\n"
1315 " dom [int, 0]: Domain identifier to use.\n"
1316 " reason [int, 0]: Reason for shutdown.\n"
1317 "Returns: [int] 0 on success; -1 on error.\n" },
1319 { "vcpu_setaffinity",
1320 (PyCFunction)pyxc_vcpu_setaffinity,
1321 METH_VARARGS | METH_KEYWORDS, "\n"
1322 "Pin a VCPU to a specified set CPUs.\n"
1323 " dom [int]: Identifier of domain to which VCPU belongs.\n"
1324 " vcpu [int, 0]: VCPU being pinned.\n"
1325 " cpumap [list, []]: list of usable CPUs.\n\n"
1326 "Returns: [int] 0 on success; -1 on error.\n" },
1328 { "domain_setcpuweight",
1329 (PyCFunction)pyxc_domain_setcpuweight,
1330 METH_VARARGS | METH_KEYWORDS, "\n"
1331 "Set cpuweight scheduler parameter for domain.\n"
1332 " dom [int]: Identifier of domain to be changed.\n"
1333 " cpuweight [float, 1]: VCPU being pinned.\n"
1334 "Returns: [int] 0 on success; -1 on error.\n" },
1336 { "domain_sethandle",
1337 (PyCFunction)pyxc_domain_sethandle,
1338 METH_VARARGS, "\n"
1339 "Set domain's opaque handle.\n"
1340 " dom [int]: Identifier of domain.\n"
1341 " handle [list of 16 ints]: New opaque handle.\n"
1342 "Returns: [int] 0 on success; -1 on error.\n" },
1344 { "domain_getinfo",
1345 (PyCFunction)pyxc_domain_getinfo,
1346 METH_VARARGS | METH_KEYWORDS, "\n"
1347 "Get information regarding a set of domains, in increasing id order.\n"
1348 " first_dom [int, 0]: First domain to retrieve info about.\n"
1349 " max_doms [int, 1024]: Maximum number of domains to retrieve info"
1350 " about.\n\n"
1351 "Returns: [list of dicts] if list length is less than 'max_doms'\n"
1352 " parameter then there was an error, or the end of the\n"
1353 " domain-id space was reached.\n"
1354 " dom [int]: Identifier of domain to which this info pertains\n"
1355 " cpu [int]: CPU to which this domain is bound\n"
1356 " vcpus [int]: Number of Virtual CPUS in this domain\n"
1357 " dying [int]: Bool - is the domain dying?\n"
1358 " crashed [int]: Bool - has the domain crashed?\n"
1359 " shutdown [int]: Bool - has the domain shut itself down?\n"
1360 " paused [int]: Bool - is the domain paused by control software?\n"
1361 " blocked [int]: Bool - is the domain blocked waiting for an event?\n"
1362 " running [int]: Bool - is the domain currently running?\n"
1363 " mem_kb [int]: Memory reservation, in kilobytes\n"
1364 " maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
1365 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1366 " shutdown_reason [int]: Numeric code from guest OS, explaining "
1367 "reason why it shut itself down.\n" },
1369 { "vcpu_getinfo",
1370 (PyCFunction)pyxc_vcpu_getinfo,
1371 METH_VARARGS | METH_KEYWORDS, "\n"
1372 "Get information regarding a VCPU.\n"
1373 " dom [int]: Domain to retrieve info about.\n"
1374 " vcpu [int, 0]: VCPU to retrieve info about.\n\n"
1375 "Returns: [dict]\n"
1376 " online [int]: Bool - Is this VCPU currently online?\n"
1377 " blocked [int]: Bool - Is this VCPU blocked waiting for an event?\n"
1378 " running [int]: Bool - Is this VCPU currently running on a CPU?\n"
1379 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1380 " cpumap [int]: Bitmap of CPUs this VCPU can run on\n"
1381 " cpu [int]: CPU that this VCPU is currently bound to\n" },
1383 { "linux_build",
1384 (PyCFunction)pyxc_linux_build,
1385 METH_VARARGS | METH_KEYWORDS, "\n"
1386 "Build a new Linux guest OS.\n"
1387 " dom [int]: Identifier of domain to build into.\n"
1388 " image [str]: Name of kernel image file. May be gzipped.\n"
1389 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
1390 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
1391 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1392 "Returns: [int] 0 on success; -1 on error.\n" },
1394 { "hvm_build",
1395 (PyCFunction)pyxc_hvm_build,
1396 METH_VARARGS | METH_KEYWORDS, "\n"
1397 "Build a new HVM guest OS.\n"
1398 " dom [int]: Identifier of domain to build into.\n"
1399 " image [str]: Name of HVM loader image file.\n"
1400 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1401 "Returns: [int] 0 on success; -1 on error.\n" },
1403 { "hvm_get_param",
1404 (PyCFunction)pyxc_get_hvm_param,
1405 METH_VARARGS | METH_KEYWORDS, "\n"
1406 "get a parameter of HVM guest OS.\n"
1407 " dom [int]: Identifier of domain to build into.\n"
1408 " param [int]: No. of HVM param.\n"
1409 "Returns: [long] value of the param.\n" },
1411 { "hvm_set_param",
1412 (PyCFunction)pyxc_set_hvm_param,
1413 METH_VARARGS | METH_KEYWORDS, "\n"
1414 "set a parameter of HVM guest OS.\n"
1415 " dom [int]: Identifier of domain to build into.\n"
1416 " param [int]: No. of HVM param.\n"
1417 " value [long]: Value of param.\n"
1418 "Returns: [int] 0 on success.\n" },
1420 { "test_assign_device",
1421 (PyCFunction)pyxc_test_assign_device,
1422 METH_VARARGS | METH_KEYWORDS, "\n"
1423 "test device assignment with VT-d.\n"
1424 " dom [int]: Identifier of domain to build into.\n"
1425 " pci_str [str]: PCI devices.\n"
1426 "Returns: [int] 0 on success, or device bdf that can't be assigned.\n" },
1428 { "sched_id_get",
1429 (PyCFunction)pyxc_sched_id_get,
1430 METH_NOARGS, "\n"
1431 "Get the current scheduler type in use.\n"
1432 "Returns: [int] sched_id.\n" },
1434 { "sedf_domain_set",
1435 (PyCFunction)pyxc_sedf_domain_set,
1436 METH_KEYWORDS, "\n"
1437 "Set the scheduling parameters for a domain when running with Atropos.\n"
1438 " dom [int]: domain to set\n"
1439 " period [long]: domain's scheduling period\n"
1440 " slice [long]: domain's slice per period\n"
1441 " latency [long]: domain's wakeup latency hint\n"
1442 " extratime [int]: domain aware of extratime?\n"
1443 "Returns: [int] 0 on success; -1 on error.\n" },
1445 { "sedf_domain_get",
1446 (PyCFunction)pyxc_sedf_domain_get,
1447 METH_VARARGS, "\n"
1448 "Get the current scheduling parameters for a domain when running with\n"
1449 "the Atropos scheduler."
1450 " dom [int]: domain to query\n"
1451 "Returns: [dict]\n"
1452 " domain [int]: domain ID\n"
1453 " period [long]: scheduler period\n"
1454 " slice [long]: CPU reservation per period\n"
1455 " latency [long]: domain's wakeup latency hint\n"
1456 " extratime [int]: domain aware of extratime?\n"},
1458 { "sched_credit_domain_set",
1459 (PyCFunction)pyxc_sched_credit_domain_set,
1460 METH_KEYWORDS, "\n"
1461 "Set the scheduling parameters for a domain when running with the\n"
1462 "SMP credit scheduler.\n"
1463 " domid [int]: domain id to set\n"
1464 " weight [short]: domain's scheduling weight\n"
1465 "Returns: [int] 0 on success; -1 on error.\n" },
1467 { "sched_credit_domain_get",
1468 (PyCFunction)pyxc_sched_credit_domain_get,
1469 METH_VARARGS, "\n"
1470 "Get the scheduling parameters for a domain when running with the\n"
1471 "SMP credit scheduler.\n"
1472 " domid [int]: domain id to get\n"
1473 "Returns: [dict]\n"
1474 " weight [short]: domain's scheduling weight\n"},
1476 { "evtchn_alloc_unbound",
1477 (PyCFunction)pyxc_evtchn_alloc_unbound,
1478 METH_VARARGS | METH_KEYWORDS, "\n"
1479 "Allocate an unbound port that will await a remote connection.\n"
1480 " dom [int]: Domain whose port space to allocate from.\n"
1481 " remote_dom [int]: Remote domain to accept connections from.\n\n"
1482 "Returns: [int] Unbound event-channel port.\n" },
1484 { "evtchn_reset",
1485 (PyCFunction)pyxc_evtchn_reset,
1486 METH_VARARGS | METH_KEYWORDS, "\n"
1487 "Reset all connections.\n"
1488 " dom [int]: Domain to reset.\n" },
1490 { "physdev_pci_access_modify",
1491 (PyCFunction)pyxc_physdev_pci_access_modify,
1492 METH_VARARGS | METH_KEYWORDS, "\n"
1493 "Allow a domain access to a PCI device\n"
1494 " dom [int]: Identifier of domain to be allowed access.\n"
1495 " bus [int]: PCI bus\n"
1496 " dev [int]: PCI slot\n"
1497 " func [int]: PCI function\n"
1498 " enable [int]: Non-zero means enable access; else disable access\n\n"
1499 "Returns: [int] 0 on success; -1 on error.\n" },
1501 { "readconsolering",
1502 (PyCFunction)pyxc_readconsolering,
1503 METH_VARARGS | METH_KEYWORDS, "\n"
1504 "Read Xen's console ring.\n"
1505 " clear [int, 0]: Bool - clear the ring after reading from it?\n\n"
1506 "Returns: [str] string is empty on failure.\n" },
1508 { "physinfo",
1509 (PyCFunction)pyxc_physinfo,
1510 METH_NOARGS, "\n"
1511 "Get information about the physical host machine\n"
1512 "Returns [dict]: information about the hardware"
1513 " [None]: on failure.\n" },
1515 { "xeninfo",
1516 (PyCFunction)pyxc_xeninfo,
1517 METH_NOARGS, "\n"
1518 "Get information about the Xen host\n"
1519 "Returns [dict]: information about Xen"
1520 " [None]: on failure.\n" },
1522 { "shadow_control",
1523 (PyCFunction)pyxc_shadow_control,
1524 METH_VARARGS | METH_KEYWORDS, "\n"
1525 "Set parameter for shadow pagetable interface\n"
1526 " dom [int]: Identifier of domain.\n"
1527 " op [int, 0]: operation\n\n"
1528 "Returns: [int] 0 on success; -1 on error.\n" },
1530 { "shadow_mem_control",
1531 (PyCFunction)pyxc_shadow_mem_control,
1532 METH_VARARGS | METH_KEYWORDS, "\n"
1533 "Set or read shadow pagetable memory use\n"
1534 " dom [int]: Identifier of domain.\n"
1535 " mb [int, -1]: MB of shadow memory this domain should have.\n\n"
1536 "Returns: [int] MB of shadow memory in use by this domain.\n" },
1538 { "domain_setmaxmem",
1539 (PyCFunction)pyxc_domain_setmaxmem,
1540 METH_VARARGS, "\n"
1541 "Set a domain's memory limit\n"
1542 " dom [int]: Identifier of domain.\n"
1543 " maxmem_kb [int]: .\n"
1544 "Returns: [int] 0 on success; -1 on error.\n" },
1546 { "domain_set_memmap_limit",
1547 (PyCFunction)pyxc_domain_set_memmap_limit,
1548 METH_VARARGS, "\n"
1549 "Set a domain's physical memory mappping limit\n"
1550 " dom [int]: Identifier of domain.\n"
1551 " map_limitkb [int]: .\n"
1552 "Returns: [int] 0 on success; -1 on error.\n" },
1554 { "domain_memory_increase_reservation",
1555 (PyCFunction)pyxc_domain_memory_increase_reservation,
1556 METH_VARARGS | METH_KEYWORDS, "\n"
1557 "Increase a domain's memory reservation\n"
1558 " dom [int]: Identifier of domain.\n"
1559 " mem_kb [long]: .\n"
1560 "Returns: [int] 0 on success; -1 on error.\n" },
1561 #ifdef __ia64__
1562 { "nvram_init",
1563 (PyCFunction)pyxc_nvram_init,
1564 METH_VARARGS, "\n"
1565 "Init nvram in IA64 platform\n"
1566 "Returns: [int] 0 on success; -1 on error.\n" },
1567 { "set_os_type",
1568 (PyCFunction)pyxc_set_os_type,
1569 METH_VARARGS, "\n"
1570 "Set guest OS type on IA64 platform\n"
1571 "Returns: [int] 0 on success; -1 on error.\n" },
1572 #endif /* __ia64__ */
1573 { "domain_ioport_permission",
1574 (PyCFunction)pyxc_domain_ioport_permission,
1575 METH_VARARGS | METH_KEYWORDS, "\n"
1576 "Allow a domain access to a range of IO ports\n"
1577 " dom [int]: Identifier of domain to be allowed access.\n"
1578 " first_port [int]: First IO port\n"
1579 " nr_ports [int]: Number of IO ports\n"
1580 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1581 "Returns: [int] 0 on success; -1 on error.\n" },
1583 { "domain_irq_permission",
1584 (PyCFunction)pyxc_domain_irq_permission,
1585 METH_VARARGS | METH_KEYWORDS, "\n"
1586 "Allow a domain access to a physical IRQ\n"
1587 " dom [int]: Identifier of domain to be allowed access.\n"
1588 " pirq [int]: The Physical IRQ\n"
1589 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1590 "Returns: [int] 0 on success; -1 on error.\n" },
1592 { "domain_iomem_permission",
1593 (PyCFunction)pyxc_domain_iomem_permission,
1594 METH_VARARGS | METH_KEYWORDS, "\n"
1595 "Allow a domain access to a range of IO memory pages\n"
1596 " dom [int]: Identifier of domain to be allowed access.\n"
1597 " first_pfn [long]: First page of I/O Memory\n"
1598 " nr_pfns [long]: Number of pages of I/O Memory (>0)\n"
1599 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1600 "Returns: [int] 0 on success; -1 on error.\n" },
1602 { "pages_to_kib",
1603 (PyCFunction)pyxc_pages_to_kib,
1604 METH_VARARGS, "\n"
1605 "Returns: [int]: The size in KiB of memory spanning the given number "
1606 "of pages.\n" },
1608 { "domain_set_time_offset",
1609 (PyCFunction)pyxc_domain_set_time_offset,
1610 METH_VARARGS, "\n"
1611 "Set a domain's time offset to Dom0's localtime\n"
1612 " dom [int]: Domain whose time offset is being set.\n"
1613 " offset [int]: Time offset from UTC in seconds.\n"
1614 "Returns: [int] 0 on success; -1 on error.\n" },
1616 { "domain_send_trigger",
1617 (PyCFunction)pyxc_domain_send_trigger,
1618 METH_VARARGS | METH_KEYWORDS, "\n"
1619 "Send trigger to a domain.\n"
1620 " dom [int]: Identifier of domain to be sent trigger.\n"
1621 " trigger [int]: Trigger type number.\n"
1622 " vcpu [int]: VCPU to be sent trigger.\n"
1623 "Returns: [int] 0 on success; -1 on error.\n" },
1625 { "send_debug_keys",
1626 (PyCFunction)pyxc_send_debug_keys,
1627 METH_VARARGS | METH_KEYWORDS, "\n"
1628 "Inject debug keys into Xen.\n"
1629 " keys [str]: String of keys to inject.\n" },
1631 #ifdef __powerpc__
1632 { "arch_alloc_real_mode_area",
1633 (PyCFunction)pyxc_alloc_real_mode_area,
1634 METH_VARARGS | METH_KEYWORDS, "\n"
1635 "Allocate a domain's real mode area.\n"
1636 " dom [int]: Identifier of domain.\n"
1637 " log [int]: Specifies the area's size.\n"
1638 "Returns: [int] 0 on success; -1 on error.\n" },
1639 #endif /* __powerpc */
1641 { NULL, NULL, 0, NULL }
1642 };
1645 static PyObject *PyXc_getattr(PyObject *obj, char *name)
1647 return Py_FindMethod(pyxc_methods, obj, name);
1650 static PyObject *PyXc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1652 XcObject *self = (XcObject *)type->tp_alloc(type, 0);
1654 if (self == NULL)
1655 return NULL;
1657 self->xc_handle = -1;
1659 return (PyObject *)self;
1662 static int
1663 PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
1665 if ((self->xc_handle = xc_interface_open()) == -1) {
1666 pyxc_error_to_exception();
1667 return -1;
1670 return 0;
1673 static void PyXc_dealloc(XcObject *self)
1675 if (self->xc_handle != -1) {
1676 xc_interface_close(self->xc_handle);
1677 self->xc_handle = -1;
1680 self->ob_type->tp_free((PyObject *)self);
1683 static PyTypeObject PyXcType = {
1684 PyObject_HEAD_INIT(NULL)
1685 0,
1686 PKG "." CLS,
1687 sizeof(XcObject),
1688 0,
1689 (destructor)PyXc_dealloc, /* tp_dealloc */
1690 NULL, /* tp_print */
1691 PyXc_getattr, /* tp_getattr */
1692 NULL, /* tp_setattr */
1693 NULL, /* tp_compare */
1694 NULL, /* tp_repr */
1695 NULL, /* tp_as_number */
1696 NULL, /* tp_as_sequence */
1697 NULL, /* tp_as_mapping */
1698 NULL, /* tp_hash */
1699 NULL, /* tp_call */
1700 NULL, /* tp_str */
1701 NULL, /* tp_getattro */
1702 NULL, /* tp_setattro */
1703 NULL, /* tp_as_buffer */
1704 Py_TPFLAGS_DEFAULT, /* tp_flags */
1705 "Xen client connections", /* tp_doc */
1706 NULL, /* tp_traverse */
1707 NULL, /* tp_clear */
1708 NULL, /* tp_richcompare */
1709 0, /* tp_weaklistoffset */
1710 NULL, /* tp_iter */
1711 NULL, /* tp_iternext */
1712 pyxc_methods, /* tp_methods */
1713 NULL, /* tp_members */
1714 NULL, /* tp_getset */
1715 NULL, /* tp_base */
1716 NULL, /* tp_dict */
1717 NULL, /* tp_descr_get */
1718 NULL, /* tp_descr_set */
1719 0, /* tp_dictoffset */
1720 (initproc)PyXc_init, /* tp_init */
1721 NULL, /* tp_alloc */
1722 PyXc_new, /* tp_new */
1723 };
1725 static PyMethodDef xc_methods[] = { { NULL } };
1727 PyMODINIT_FUNC initxc(void)
1729 PyObject *m;
1731 if (PyType_Ready(&PyXcType) < 0)
1732 return;
1734 m = Py_InitModule(PKG, xc_methods);
1736 if (m == NULL)
1737 return;
1739 xc_error_obj = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
1740 zero = PyInt_FromLong(0);
1742 /* KAF: This ensures that we get debug output in a timely manner. */
1743 setbuf(stdout, NULL);
1744 setbuf(stderr, NULL);
1746 Py_INCREF(&PyXcType);
1747 PyModule_AddObject(m, CLS, (PyObject *)&PyXcType);
1749 Py_INCREF(xc_error_obj);
1750 PyModule_AddObject(m, "Error", xc_error_obj);
1752 /* Expose some libxc constants to Python */
1753 PyModule_AddIntConstant(m, "XEN_SCHEDULER_SEDF", XEN_SCHEDULER_SEDF);
1754 PyModule_AddIntConstant(m, "XEN_SCHEDULER_CREDIT", XEN_SCHEDULER_CREDIT);
1759 /*
1760 * Local variables:
1761 * c-indent-level: 4
1762 * c-basic-offset: 4
1763 * End:
1764 */