direct-io.hg

view tools/python/xen/lowlevel/xc/xc.c @ 14429:2b58c9e32549

xend: Avoid use of 'k' specifier to Py_BuildValue(). Its
implementation is broken until Python v2.4.3. Instead cast the C value
to long long and use the 'L' specifier.
Signed-off-by: Keir Fraser <keir@xensource.com>
author Keir Fraser <keir@xensource.com>
date Sun Mar 18 18:26:34 2007 +0000 (2007-03-18)
parents 7521c87983e0
children 49ec3725d0c0
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;
100 int ret, i, hvm = 0;
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", "hvm", NULL };
108 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOi", kwd_list,
109 &dom, &ssidref, &pyhandle, &hvm))
110 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 ( hvm )
128 flags |= XEN_DOMCTL_CDF_hvm_guest;
130 if ( (ret = xc_domain_create(self->xc_handle, ssidref,
131 handle, flags, &dom)) < 0 )
132 return pyxc_error_to_exception();
134 return PyInt_FromLong(dom);
136 out_exception:
137 errno = EINVAL;
138 PyErr_SetFromErrno(xc_error_obj);
139 return NULL;
140 }
142 static PyObject *pyxc_domain_max_vcpus(XcObject *self, PyObject *args)
143 {
144 uint32_t dom, max;
146 if (!PyArg_ParseTuple(args, "ii", &dom, &max))
147 return NULL;
149 if (xc_domain_max_vcpus(self->xc_handle, dom, max) != 0)
150 return pyxc_error_to_exception();
152 Py_INCREF(zero);
153 return zero;
154 }
156 static PyObject *pyxc_domain_pause(XcObject *self, PyObject *args)
157 {
158 return dom_op(self, args, xc_domain_pause);
159 }
161 static PyObject *pyxc_domain_unpause(XcObject *self, PyObject *args)
162 {
163 return dom_op(self, args, xc_domain_unpause);
164 }
166 static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args)
167 {
168 return dom_op(self, args, xc_domain_destroy);
169 }
171 static PyObject *pyxc_domain_shutdown(XcObject *self, PyObject *args)
172 {
173 uint32_t dom, reason;
175 if ( !PyArg_ParseTuple(args, "ii", &dom, &reason) )
176 return NULL;
178 if ( xc_domain_shutdown(self->xc_handle, dom, reason) != 0 )
179 return pyxc_error_to_exception();
181 Py_INCREF(zero);
182 return zero;
183 }
185 static PyObject *pyxc_domain_resume(XcObject *self, PyObject *args)
186 {
187 uint32_t dom;
188 int fast;
190 if ( !PyArg_ParseTuple(args, "ii", &dom, &fast) )
191 return NULL;
193 if ( xc_domain_resume(self->xc_handle, dom, fast) != 0 )
194 return pyxc_error_to_exception();
196 Py_INCREF(zero);
197 return zero;
198 }
200 static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
201 PyObject *args,
202 PyObject *kwds)
203 {
204 uint32_t dom;
205 int vcpu = 0, i;
206 uint64_t cpumap = ~0ULL;
207 PyObject *cpulist = NULL;
209 static char *kwd_list[] = { "domid", "vcpu", "cpumap", NULL };
211 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|iO", kwd_list,
212 &dom, &vcpu, &cpulist) )
213 return NULL;
215 if ( (cpulist != NULL) && PyList_Check(cpulist) )
216 {
217 cpumap = 0ULL;
218 for ( i = 0; i < PyList_Size(cpulist); i++ )
219 cpumap |= (uint64_t)1 << PyInt_AsLong(PyList_GetItem(cpulist, i));
220 }
222 if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
223 return pyxc_error_to_exception();
225 Py_INCREF(zero);
226 return zero;
227 }
229 static PyObject *pyxc_domain_setcpuweight(XcObject *self,
230 PyObject *args,
231 PyObject *kwds)
232 {
233 uint32_t dom;
234 float cpuweight = 1;
236 static char *kwd_list[] = { "domid", "cpuweight", NULL };
238 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|f", kwd_list,
239 &dom, &cpuweight) )
240 return NULL;
242 if ( xc_domain_setcpuweight(self->xc_handle, dom, cpuweight) != 0 )
243 return pyxc_error_to_exception();
245 Py_INCREF(zero);
246 return zero;
247 }
249 static PyObject *pyxc_domain_sethandle(XcObject *self, PyObject *args)
250 {
251 int i;
252 uint32_t dom;
253 PyObject *pyhandle;
254 xen_domain_handle_t handle;
256 if (!PyArg_ParseTuple(args, "iO", &dom, &pyhandle))
257 return NULL;
259 if ( !PyList_Check(pyhandle) ||
260 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
261 {
262 goto out_exception;
263 }
265 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
266 {
267 PyObject *p = PyList_GetItem(pyhandle, i);
268 if ( !PyInt_Check(p) )
269 goto out_exception;
270 handle[i] = (uint8_t)PyInt_AsLong(p);
271 }
273 if (xc_domain_sethandle(self->xc_handle, dom, handle) < 0)
274 return pyxc_error_to_exception();
276 Py_INCREF(zero);
277 return zero;
279 out_exception:
280 PyErr_SetFromErrno(xc_error_obj);
281 return NULL;
282 }
285 static PyObject *pyxc_domain_getinfo(XcObject *self,
286 PyObject *args,
287 PyObject *kwds)
288 {
289 PyObject *list, *info_dict, *pyhandle;
291 uint32_t first_dom = 0;
292 int max_doms = 1024, nr_doms, i, j;
293 xc_dominfo_t *info;
295 static char *kwd_list[] = { "first_dom", "max_doms", NULL };
297 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
298 &first_dom, &max_doms) )
299 return NULL;
301 if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL )
302 return PyErr_NoMemory();
304 nr_doms = xc_domain_getinfo(self->xc_handle, first_dom, max_doms, info);
306 if (nr_doms < 0)
307 {
308 free(info);
309 return pyxc_error_to_exception();
310 }
312 list = PyList_New(nr_doms);
313 for ( i = 0 ; i < nr_doms; i++ )
314 {
315 info_dict = Py_BuildValue(
316 "{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
317 ",s:L,s:L,s:L,s:i,s:i}",
318 "domid", (int)info[i].domid,
319 "online_vcpus", info[i].nr_online_vcpus,
320 "max_vcpu_id", info[i].max_vcpu_id,
321 "hvm", info[i].hvm,
322 "dying", info[i].dying,
323 "crashed", info[i].crashed,
324 "shutdown", info[i].shutdown,
325 "paused", info[i].paused,
326 "blocked", info[i].blocked,
327 "running", info[i].running,
328 "mem_kb", (long long)info[i].nr_pages*(XC_PAGE_SIZE/1024),
329 "cpu_time", (long long)info[i].cpu_time,
330 "maxmem_kb", (long long)info[i].max_memkb,
331 "ssidref", (int)info[i].ssidref,
332 "shutdown_reason", info[i].shutdown_reason);
333 pyhandle = PyList_New(sizeof(xen_domain_handle_t));
334 if ( (pyhandle == NULL) || (info_dict == NULL) )
335 {
336 Py_DECREF(list);
337 if ( pyhandle != NULL ) { Py_DECREF(pyhandle); }
338 if ( info_dict != NULL ) { Py_DECREF(info_dict); }
339 return NULL;
340 }
341 for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
342 PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
343 PyDict_SetItemString(info_dict, "handle", pyhandle);
344 Py_DECREF(pyhandle);
345 PyList_SetItem(list, i, info_dict);
346 }
348 free(info);
350 return list;
351 }
353 static PyObject *pyxc_vcpu_getinfo(XcObject *self,
354 PyObject *args,
355 PyObject *kwds)
356 {
357 PyObject *info_dict, *cpulist;
359 uint32_t dom, vcpu = 0;
360 xc_vcpuinfo_t info;
361 int rc, i;
362 uint64_t cpumap;
364 static char *kwd_list[] = { "domid", "vcpu", NULL };
366 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
367 &dom, &vcpu) )
368 return NULL;
370 rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
371 if ( rc < 0 )
372 return pyxc_error_to_exception();
373 rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, &cpumap);
374 if ( rc < 0 )
375 return pyxc_error_to_exception();
377 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}",
378 "online", info.online,
379 "blocked", info.blocked,
380 "running", info.running,
381 "cpu_time", info.cpu_time,
382 "cpu", info.cpu);
384 cpulist = PyList_New(0);
385 for ( i = 0; cpumap != 0; i++ )
386 {
387 if ( cpumap & 1 )
388 PyList_Append(cpulist, PyInt_FromLong(i));
389 cpumap >>= 1;
390 }
391 PyDict_SetItemString(info_dict, "cpumap", cpulist);
392 Py_DECREF(cpulist);
393 return info_dict;
394 }
396 static PyObject *pyxc_linux_build(XcObject *self,
397 PyObject *args,
398 PyObject *kwds)
399 {
400 uint32_t domid;
401 struct xc_dom_image *dom;
402 char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
403 int flags = 0;
404 int store_evtchn, console_evtchn;
405 unsigned int mem_mb;
406 unsigned long store_mfn = 0;
407 unsigned long console_mfn = 0;
408 PyObject* elfnote_dict;
409 PyObject* elfnote = NULL;
410 int i;
412 static char *kwd_list[] = { "domid", "store_evtchn", "memsize",
413 "console_evtchn", "image",
414 /* optional */
415 "ramdisk", "cmdline", "flags",
416 "features", NULL };
418 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis", kwd_list,
419 &domid, &store_evtchn, &mem_mb,
420 &console_evtchn, &image,
421 /* optional */
422 &ramdisk, &cmdline, &flags,
423 &features) )
424 return NULL;
426 xc_dom_loginit();
427 if (!(dom = xc_dom_allocate(cmdline, features)))
428 return pyxc_error_to_exception();
430 if ( xc_dom_linux_build(self->xc_handle, dom, domid, mem_mb, image,
431 ramdisk, flags, store_evtchn, &store_mfn,
432 console_evtchn, &console_mfn) != 0 ) {
433 goto out;
434 }
436 if ( !(elfnote_dict = PyDict_New()) )
437 goto out;
439 for ( i = 0; i < ARRAY_SIZE(dom->parms.elf_notes); i++ )
440 {
441 switch ( dom->parms.elf_notes[i].type )
442 {
443 case XEN_ENT_NONE:
444 continue;
445 case XEN_ENT_LONG:
446 elfnote = Py_BuildValue("k", dom->parms.elf_notes[i].data.num);
447 break;
448 case XEN_ENT_STR:
449 elfnote = Py_BuildValue("s", dom->parms.elf_notes[i].data.str);
450 break;
451 }
452 PyDict_SetItemString(elfnote_dict,
453 dom->parms.elf_notes[i].name,
454 elfnote);
455 Py_DECREF(elfnote);
456 }
458 xc_dom_release(dom);
460 return Py_BuildValue("{s:i,s:i,s:N}",
461 "store_mfn", store_mfn,
462 "console_mfn", console_mfn,
463 "notes", elfnote_dict);
465 out:
466 xc_dom_release(dom);
467 return pyxc_error_to_exception();
468 }
470 static PyObject *pyxc_hvm_build(XcObject *self,
471 PyObject *args,
472 PyObject *kwds)
473 {
474 uint32_t dom;
475 #if !defined(__ia64__)
476 struct hvm_info_table *va_hvm;
477 uint8_t *va_map, sum;
478 int i;
479 #endif
480 char *image;
481 int store_evtchn, memsize, vcpus = 1, pae = 0, acpi = 0, apic = 1;
482 unsigned long store_mfn;
484 static char *kwd_list[] = { "domid", "store_evtchn",
485 "memsize", "image", "vcpus", "pae", "acpi",
486 "apic", NULL };
487 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|iiii", kwd_list,
488 &dom, &store_evtchn, &memsize,
489 &image, &vcpus, &pae, &acpi, &apic) )
490 return NULL;
492 if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
493 return pyxc_error_to_exception();
495 #if !defined(__ia64__)
496 /* Set up the HVM info table. */
497 va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
498 PROT_READ | PROT_WRITE,
499 HVM_INFO_PFN);
500 if ( va_map == NULL )
501 return PyErr_SetFromErrno(xc_error_obj);
502 va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
503 memset(va_hvm, 0, sizeof(*va_hvm));
504 strncpy(va_hvm->signature, "HVM INFO", 8);
505 va_hvm->length = sizeof(struct hvm_info_table);
506 va_hvm->acpi_enabled = acpi;
507 va_hvm->apic_mode = apic;
508 va_hvm->nr_vcpus = vcpus;
509 for ( i = 0, sum = 0; i < va_hvm->length; i++ )
510 sum += ((uint8_t *)va_hvm)[i];
511 va_hvm->checksum = -sum;
512 munmap(va_map, XC_PAGE_SIZE);
513 #endif
515 xc_get_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_PFN, &store_mfn);
516 #if !defined(__ia64__)
517 xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
518 #endif
519 xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_EVTCHN,
520 store_evtchn);
522 return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
523 }
525 static PyObject *pyxc_evtchn_alloc_unbound(XcObject *self,
526 PyObject *args,
527 PyObject *kwds)
528 {
529 uint32_t dom, remote_dom;
530 int port;
532 static char *kwd_list[] = { "domid", "remote_dom", NULL };
534 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
535 &dom, &remote_dom) )
536 return NULL;
538 if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) < 0 )
539 return pyxc_error_to_exception();
541 return PyInt_FromLong(port);
542 }
544 static PyObject *pyxc_evtchn_reset(XcObject *self,
545 PyObject *args,
546 PyObject *kwds)
547 {
548 uint32_t dom;
550 static char *kwd_list[] = { "dom", NULL };
552 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
553 return NULL;
555 if ( xc_evtchn_reset(self->xc_handle, dom) < 0 )
556 return pyxc_error_to_exception();
558 Py_INCREF(zero);
559 return zero;
560 }
562 static PyObject *pyxc_physdev_pci_access_modify(XcObject *self,
563 PyObject *args,
564 PyObject *kwds)
565 {
566 uint32_t dom;
567 int bus, dev, func, enable, ret;
569 static char *kwd_list[] = { "domid", "bus", "dev", "func", "enable", NULL };
571 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list,
572 &dom, &bus, &dev, &func, &enable) )
573 return NULL;
575 ret = xc_physdev_pci_access_modify(
576 self->xc_handle, dom, bus, dev, func, enable);
577 if ( ret != 0 )
578 return pyxc_error_to_exception();
580 Py_INCREF(zero);
581 return zero;
582 }
584 static PyObject *pyxc_readconsolering(XcObject *self,
585 PyObject *args,
586 PyObject *kwds)
587 {
588 unsigned int clear = 0;
589 char _str[32768], *str = _str;
590 unsigned int count = 32768;
591 int ret;
593 static char *kwd_list[] = { "clear", NULL };
595 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &clear) )
596 return NULL;
598 ret = xc_readconsolering(self->xc_handle, &str, &count, clear);
599 if ( ret < 0 )
600 return pyxc_error_to_exception();
602 return PyString_FromStringAndSize(str, count);
603 }
606 static unsigned long pages_to_kib(unsigned long pages)
607 {
608 return pages * (XC_PAGE_SIZE / 1024);
609 }
612 static PyObject *pyxc_pages_to_kib(XcObject *self, PyObject *args)
613 {
614 unsigned long pages;
616 if (!PyArg_ParseTuple(args, "l", &pages))
617 return NULL;
619 return PyLong_FromUnsignedLong(pages_to_kib(pages));
620 }
623 static PyObject *pyxc_physinfo(XcObject *self)
624 {
625 xc_physinfo_t info;
626 char cpu_cap[128], *p=cpu_cap, *q=cpu_cap;
627 int i;
629 if ( xc_physinfo(self->xc_handle, &info) != 0 )
630 return pyxc_error_to_exception();
632 *q=0;
633 for(i=0;i<sizeof(info.hw_cap)/4;i++)
634 {
635 p+=sprintf(p,"%08x:",info.hw_cap[i]);
636 if(info.hw_cap[i])
637 q=p;
638 }
639 if(q>cpu_cap)
640 *(q-1)=0;
642 return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s}",
643 "threads_per_core", info.threads_per_core,
644 "cores_per_socket", info.cores_per_socket,
645 "sockets_per_node", info.sockets_per_node,
646 "nr_nodes", info.nr_nodes,
647 "total_memory", pages_to_kib(info.total_pages),
648 "free_memory", pages_to_kib(info.free_pages),
649 "scrub_memory", pages_to_kib(info.scrub_pages),
650 "cpu_khz", info.cpu_khz,
651 "hw_caps", cpu_cap);
652 }
654 static PyObject *pyxc_xeninfo(XcObject *self)
655 {
656 xen_extraversion_t xen_extra;
657 xen_compile_info_t xen_cc;
658 xen_changeset_info_t xen_chgset;
659 xen_capabilities_info_t xen_caps;
660 xen_platform_parameters_t p_parms;
661 long xen_version;
662 long xen_pagesize;
663 char str[128];
665 xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
667 if ( xc_version(self->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
668 return pyxc_error_to_exception();
670 if ( xc_version(self->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
671 return pyxc_error_to_exception();
673 if ( xc_version(self->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
674 return pyxc_error_to_exception();
676 if ( xc_version(self->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
677 return pyxc_error_to_exception();
679 if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) != 0 )
680 return pyxc_error_to_exception();
682 sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
684 xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
685 if (xen_pagesize < 0 )
686 return pyxc_error_to_exception();
688 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}",
689 "xen_major", xen_version >> 16,
690 "xen_minor", (xen_version & 0xffff),
691 "xen_extra", xen_extra,
692 "xen_caps", xen_caps,
693 "xen_pagesize", xen_pagesize,
694 "platform_params", str,
695 "xen_changeset", xen_chgset,
696 "cc_compiler", xen_cc.compiler,
697 "cc_compile_by", xen_cc.compile_by,
698 "cc_compile_domain", xen_cc.compile_domain,
699 "cc_compile_date", xen_cc.compile_date);
700 }
703 static PyObject *pyxc_sedf_domain_set(XcObject *self,
704 PyObject *args,
705 PyObject *kwds)
706 {
707 uint32_t domid;
708 uint64_t period, slice, latency;
709 uint16_t extratime, weight;
710 static char *kwd_list[] = { "domid", "period", "slice",
711 "latency", "extratime", "weight",NULL };
713 if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLhh", kwd_list,
714 &domid, &period, &slice,
715 &latency, &extratime, &weight) )
716 return NULL;
717 if ( xc_sedf_domain_set(self->xc_handle, domid, period,
718 slice, latency, extratime,weight) != 0 )
719 return pyxc_error_to_exception();
721 Py_INCREF(zero);
722 return zero;
723 }
725 static PyObject *pyxc_sedf_domain_get(XcObject *self, PyObject *args)
726 {
727 uint32_t domid;
728 uint64_t period, slice,latency;
729 uint16_t weight, extratime;
731 if(!PyArg_ParseTuple(args, "i", &domid))
732 return NULL;
734 if (xc_sedf_domain_get(self->xc_handle, domid, &period,
735 &slice,&latency,&extratime,&weight))
736 return pyxc_error_to_exception();
738 return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
739 "domid", domid,
740 "period", period,
741 "slice", slice,
742 "latency", latency,
743 "extratime", extratime,
744 "weight", weight);
745 }
747 static PyObject *pyxc_shadow_control(PyObject *self,
748 PyObject *args,
749 PyObject *kwds)
750 {
751 XcObject *xc = (XcObject *)self;
753 uint32_t dom;
754 int op=0;
756 static char *kwd_list[] = { "dom", "op", NULL };
758 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
759 &dom, &op) )
760 return NULL;
762 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL, 0, NULL)
763 < 0 )
764 return pyxc_error_to_exception();
766 Py_INCREF(zero);
767 return zero;
768 }
770 static PyObject *pyxc_shadow_mem_control(PyObject *self,
771 PyObject *args,
772 PyObject *kwds)
773 {
774 XcObject *xc = (XcObject *)self;
775 int op;
776 uint32_t dom;
777 int mbarg = -1;
778 unsigned long mb;
780 static char *kwd_list[] = { "dom", "mb", NULL };
782 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
783 &dom, &mbarg) )
784 return NULL;
786 if ( mbarg < 0 )
787 op = XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION;
788 else
789 {
790 mb = mbarg;
791 op = XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION;
792 }
793 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, &mb, 0, NULL) < 0 )
794 return pyxc_error_to_exception();
796 mbarg = mb;
797 return Py_BuildValue("i", mbarg);
798 }
800 static PyObject *pyxc_sched_id_get(XcObject *self) {
802 int sched_id;
803 if (xc_sched_id(self->xc_handle, &sched_id) != 0)
804 return PyErr_SetFromErrno(xc_error_obj);
806 return Py_BuildValue("i", sched_id);
807 }
809 static PyObject *pyxc_sched_credit_domain_set(XcObject *self,
810 PyObject *args,
811 PyObject *kwds)
812 {
813 uint32_t domid;
814 uint16_t weight;
815 uint16_t cap;
816 static char *kwd_list[] = { "domid", "weight", "cap", NULL };
817 static char kwd_type[] = "I|HH";
818 struct xen_domctl_sched_credit sdom;
820 weight = 0;
821 cap = (uint16_t)~0U;
822 if( !PyArg_ParseTupleAndKeywords(args, kwds, kwd_type, kwd_list,
823 &domid, &weight, &cap) )
824 return NULL;
826 sdom.weight = weight;
827 sdom.cap = cap;
829 if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 )
830 return pyxc_error_to_exception();
832 Py_INCREF(zero);
833 return zero;
834 }
836 static PyObject *pyxc_sched_credit_domain_get(XcObject *self, PyObject *args)
837 {
838 uint32_t domid;
839 struct xen_domctl_sched_credit sdom;
841 if( !PyArg_ParseTuple(args, "I", &domid) )
842 return NULL;
844 if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 )
845 return pyxc_error_to_exception();
847 return Py_BuildValue("{s:H,s:H}",
848 "weight", sdom.weight,
849 "cap", sdom.cap);
850 }
852 static PyObject *pyxc_domain_setmaxmem(XcObject *self, PyObject *args)
853 {
854 uint32_t dom;
855 unsigned int maxmem_kb;
857 if (!PyArg_ParseTuple(args, "ii", &dom, &maxmem_kb))
858 return NULL;
860 if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0)
861 return pyxc_error_to_exception();
863 Py_INCREF(zero);
864 return zero;
865 }
867 static PyObject *pyxc_domain_set_memmap_limit(XcObject *self, PyObject *args)
868 {
869 uint32_t dom;
870 unsigned int maplimit_kb;
872 if ( !PyArg_ParseTuple(args, "ii", &dom, &maplimit_kb) )
873 return NULL;
875 if ( xc_domain_set_memmap_limit(self->xc_handle, dom, maplimit_kb) != 0 )
876 return pyxc_error_to_exception();
878 Py_INCREF(zero);
879 return zero;
880 }
882 static PyObject *pyxc_domain_memory_increase_reservation(XcObject *self,
883 PyObject *args,
884 PyObject *kwds)
885 {
886 uint32_t dom;
887 unsigned long mem_kb;
888 unsigned int extent_order = 0 , address_bits = 0;
889 unsigned long nr_extents;
891 static char *kwd_list[] = { "domid", "mem_kb", "extent_order", "address_bits", NULL };
893 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "il|ii", kwd_list,
894 &dom, &mem_kb, &extent_order, &address_bits) )
895 return NULL;
897 /* round down to nearest power of 2. Assume callers using extent_order>0
898 know what they are doing */
899 nr_extents = (mem_kb / (XC_PAGE_SIZE/1024)) >> extent_order;
900 if ( xc_domain_memory_increase_reservation(self->xc_handle, dom,
901 nr_extents, extent_order,
902 address_bits, NULL) )
903 return pyxc_error_to_exception();
905 Py_INCREF(zero);
906 return zero;
907 }
909 static PyObject *pyxc_domain_ioport_permission(XcObject *self,
910 PyObject *args,
911 PyObject *kwds)
912 {
913 uint32_t dom;
914 int first_port, nr_ports, allow_access, ret;
916 static char *kwd_list[] = { "domid", "first_port", "nr_ports", "allow_access", NULL };
918 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiii", kwd_list,
919 &dom, &first_port, &nr_ports, &allow_access) )
920 return NULL;
922 ret = xc_domain_ioport_permission(
923 self->xc_handle, dom, first_port, nr_ports, allow_access);
924 if ( ret != 0 )
925 return pyxc_error_to_exception();
927 Py_INCREF(zero);
928 return zero;
929 }
931 static PyObject *pyxc_domain_irq_permission(PyObject *self,
932 PyObject *args,
933 PyObject *kwds)
934 {
935 XcObject *xc = (XcObject *)self;
936 uint32_t dom;
937 int pirq, allow_access, ret;
939 static char *kwd_list[] = { "domid", "pirq", "allow_access", NULL };
941 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list,
942 &dom, &pirq, &allow_access) )
943 return NULL;
945 ret = xc_domain_irq_permission(
946 xc->xc_handle, dom, pirq, allow_access);
947 if ( ret != 0 )
948 return pyxc_error_to_exception();
950 Py_INCREF(zero);
951 return zero;
952 }
954 static PyObject *pyxc_domain_iomem_permission(PyObject *self,
955 PyObject *args,
956 PyObject *kwds)
957 {
958 XcObject *xc = (XcObject *)self;
959 uint32_t dom;
960 unsigned long first_pfn, nr_pfns, allow_access, ret;
962 static char *kwd_list[] = { "domid", "first_pfn", "nr_pfns", "allow_access", NULL };
964 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illi", kwd_list,
965 &dom, &first_pfn, &nr_pfns, &allow_access) )
966 return NULL;
968 ret = xc_domain_iomem_permission(
969 xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
970 if ( ret != 0 )
971 return pyxc_error_to_exception();
973 Py_INCREF(zero);
974 return zero;
975 }
977 static PyObject *pyxc_domain_set_time_offset(XcObject *self, PyObject *args)
978 {
979 uint32_t dom;
980 int32_t time_offset_seconds;
981 time_t calendar_time;
982 struct tm local_time;
983 struct tm utc_time;
985 if (!PyArg_ParseTuple(args, "i", &dom))
986 return NULL;
988 calendar_time = time(NULL);
989 localtime_r(&calendar_time, &local_time);
990 gmtime_r(&calendar_time, &utc_time);
991 /* set up to get calendar time based on utc_time, with local dst setting */
992 utc_time.tm_isdst = local_time.tm_isdst;
993 time_offset_seconds = (int32_t)difftime(calendar_time, mktime(&utc_time));
995 if (xc_domain_set_time_offset(self->xc_handle, dom, time_offset_seconds) != 0)
996 return NULL;
998 Py_INCREF(zero);
999 return zero;
1002 static PyObject *pyxc_domain_send_trigger(XcObject *self,
1003 PyObject *args,
1004 PyObject *kwds)
1006 uint32_t dom;
1007 int trigger, vcpu = 0;
1009 static char *kwd_list[] = { "domid", "trigger", "vcpu", NULL };
1011 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii|i", kwd_list,
1012 &dom, &trigger, &vcpu) )
1013 return NULL;
1015 if (xc_domain_send_trigger(self->xc_handle, dom, trigger, vcpu) != 0)
1016 return pyxc_error_to_exception();
1018 Py_INCREF(zero);
1019 return zero;
1022 static PyObject *pyxc_send_debug_keys(XcObject *self,
1023 PyObject *args,
1024 PyObject *kwds)
1026 char *keys;
1028 static char *kwd_list[] = { "keys", NULL };
1030 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list, &keys) )
1031 return NULL;
1033 if ( xc_send_debug_keys(self->xc_handle, keys) != 0 )
1034 return pyxc_error_to_exception();
1036 Py_INCREF(zero);
1037 return zero;
1040 static PyObject *dom_op(XcObject *self, PyObject *args,
1041 int (*fn)(int, uint32_t))
1043 uint32_t dom;
1045 if (!PyArg_ParseTuple(args, "i", &dom))
1046 return NULL;
1048 if (fn(self->xc_handle, dom) != 0)
1049 return pyxc_error_to_exception();
1051 Py_INCREF(zero);
1052 return zero;
1055 #ifdef __powerpc__
1056 static PyObject *pyxc_alloc_real_mode_area(XcObject *self,
1057 PyObject *args,
1058 PyObject *kwds)
1060 uint32_t dom;
1061 unsigned int log;
1063 static char *kwd_list[] = { "dom", "log", NULL };
1065 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
1066 &dom, &log) )
1067 return NULL;
1069 if ( xc_alloc_real_mode_area(self->xc_handle, dom, log) )
1070 return pyxc_error_to_exception();
1072 Py_INCREF(zero);
1073 return zero;
1076 static PyObject *pyxc_prose_build(XcObject *self,
1077 PyObject *args,
1078 PyObject *kwds)
1080 uint32_t dom;
1081 char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
1082 int flags = 0;
1083 int store_evtchn, console_evtchn;
1084 unsigned int mem_mb;
1085 unsigned long store_mfn = 0;
1086 unsigned long console_mfn = 0;
1087 int unused;
1089 static char *kwd_list[] = { "dom", "store_evtchn",
1090 "console_evtchn", "image", "memsize",
1091 /* optional */
1092 "ramdisk", "cmdline", "flags",
1093 "features", NULL };
1095 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis#", kwd_list,
1096 &dom, &store_evtchn, &mem_mb,
1097 &console_evtchn, &image,
1098 /* optional */
1099 &ramdisk, &cmdline, &flags,
1100 &features, &unused) )
1101 return NULL;
1103 if ( xc_prose_build(self->xc_handle, dom, mem_mb, image,
1104 ramdisk, cmdline, features, flags,
1105 store_evtchn, &store_mfn,
1106 console_evtchn, &console_mfn) != 0 ) {
1107 if (!errno)
1108 errno = EINVAL;
1109 return pyxc_error_to_exception();
1111 return Py_BuildValue("{s:i,s:i}",
1112 "store_mfn", store_mfn,
1113 "console_mfn", console_mfn);
1115 #endif /* powerpc */
1117 static PyMethodDef pyxc_methods[] = {
1118 { "handle",
1119 (PyCFunction)pyxc_handle,
1120 METH_NOARGS, "\n"
1121 "Query the xc control interface file descriptor.\n\n"
1122 "Returns: [int] file descriptor\n" },
1124 { "domain_create",
1125 (PyCFunction)pyxc_domain_create,
1126 METH_VARARGS | METH_KEYWORDS, "\n"
1127 "Create a new domain.\n"
1128 " dom [int, 0]: Domain identifier to use (allocated if zero).\n"
1129 "Returns: [int] new domain identifier; -1 on error.\n" },
1131 { "domain_max_vcpus",
1132 (PyCFunction)pyxc_domain_max_vcpus,
1133 METH_VARARGS, "\n"
1134 "Set the maximum number of VCPUs a domain may create.\n"
1135 " dom [int, 0]: Domain identifier to use.\n"
1136 " max [int, 0]: New maximum number of VCPUs in domain.\n"
1137 "Returns: [int] 0 on success; -1 on error.\n" },
1139 { "domain_dumpcore",
1140 (PyCFunction)pyxc_domain_dumpcore,
1141 METH_VARARGS, "\n"
1142 "Dump core of a domain.\n"
1143 " dom [int]: Identifier of domain to dump core of.\n"
1144 " corefile [string]: Name of corefile to be created.\n\n"
1145 "Returns: [int] 0 on success; -1 on error.\n" },
1147 { "domain_pause",
1148 (PyCFunction)pyxc_domain_pause,
1149 METH_VARARGS, "\n"
1150 "Temporarily pause execution of a domain.\n"
1151 " dom [int]: Identifier of domain to be paused.\n\n"
1152 "Returns: [int] 0 on success; -1 on error.\n" },
1154 { "domain_unpause",
1155 (PyCFunction)pyxc_domain_unpause,
1156 METH_VARARGS, "\n"
1157 "(Re)start execution of a domain.\n"
1158 " dom [int]: Identifier of domain to be unpaused.\n\n"
1159 "Returns: [int] 0 on success; -1 on error.\n" },
1161 { "domain_destroy",
1162 (PyCFunction)pyxc_domain_destroy,
1163 METH_VARARGS, "\n"
1164 "Destroy a domain.\n"
1165 " dom [int]: Identifier of domain to be destroyed.\n\n"
1166 "Returns: [int] 0 on success; -1 on error.\n" },
1168 { "domain_resume",
1169 (PyCFunction)pyxc_domain_resume,
1170 METH_VARARGS, "\n"
1171 "Resume execution of a suspended domain.\n"
1172 " dom [int]: Identifier of domain to be resumed.\n"
1173 " fast [int]: Use cooperative resume.\n\n"
1174 "Returns: [int] 0 on success; -1 on error.\n" },
1176 { "domain_shutdown",
1177 (PyCFunction)pyxc_domain_shutdown,
1178 METH_VARARGS, "\n"
1179 "Shutdown a domain.\n"
1180 " dom [int, 0]: Domain identifier to use.\n"
1181 " reason [int, 0]: Reason for shutdown.\n"
1182 "Returns: [int] 0 on success; -1 on error.\n" },
1184 { "vcpu_setaffinity",
1185 (PyCFunction)pyxc_vcpu_setaffinity,
1186 METH_VARARGS | METH_KEYWORDS, "\n"
1187 "Pin a VCPU to a specified set CPUs.\n"
1188 " dom [int]: Identifier of domain to which VCPU belongs.\n"
1189 " vcpu [int, 0]: VCPU being pinned.\n"
1190 " cpumap [list, []]: list of usable CPUs.\n\n"
1191 "Returns: [int] 0 on success; -1 on error.\n" },
1193 { "domain_setcpuweight",
1194 (PyCFunction)pyxc_domain_setcpuweight,
1195 METH_VARARGS | METH_KEYWORDS, "\n"
1196 "Set cpuweight scheduler parameter for domain.\n"
1197 " dom [int]: Identifier of domain to be changed.\n"
1198 " cpuweight [float, 1]: VCPU being pinned.\n"
1199 "Returns: [int] 0 on success; -1 on error.\n" },
1201 { "domain_sethandle",
1202 (PyCFunction)pyxc_domain_sethandle,
1203 METH_VARARGS, "\n"
1204 "Set domain's opaque handle.\n"
1205 " dom [int]: Identifier of domain.\n"
1206 " handle [list of 16 ints]: New opaque handle.\n"
1207 "Returns: [int] 0 on success; -1 on error.\n" },
1209 { "domain_getinfo",
1210 (PyCFunction)pyxc_domain_getinfo,
1211 METH_VARARGS | METH_KEYWORDS, "\n"
1212 "Get information regarding a set of domains, in increasing id order.\n"
1213 " first_dom [int, 0]: First domain to retrieve info about.\n"
1214 " max_doms [int, 1024]: Maximum number of domains to retrieve info"
1215 " about.\n\n"
1216 "Returns: [list of dicts] if list length is less than 'max_doms'\n"
1217 " parameter then there was an error, or the end of the\n"
1218 " domain-id space was reached.\n"
1219 " dom [int]: Identifier of domain to which this info pertains\n"
1220 " cpu [int]: CPU to which this domain is bound\n"
1221 " vcpus [int]: Number of Virtual CPUS in this domain\n"
1222 " dying [int]: Bool - is the domain dying?\n"
1223 " crashed [int]: Bool - has the domain crashed?\n"
1224 " shutdown [int]: Bool - has the domain shut itself down?\n"
1225 " paused [int]: Bool - is the domain paused by control software?\n"
1226 " blocked [int]: Bool - is the domain blocked waiting for an event?\n"
1227 " running [int]: Bool - is the domain currently running?\n"
1228 " mem_kb [int]: Memory reservation, in kilobytes\n"
1229 " maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
1230 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1231 " shutdown_reason [int]: Numeric code from guest OS, explaining "
1232 "reason why it shut itself down.\n" },
1234 { "vcpu_getinfo",
1235 (PyCFunction)pyxc_vcpu_getinfo,
1236 METH_VARARGS | METH_KEYWORDS, "\n"
1237 "Get information regarding a VCPU.\n"
1238 " dom [int]: Domain to retrieve info about.\n"
1239 " vcpu [int, 0]: VCPU to retrieve info about.\n\n"
1240 "Returns: [dict]\n"
1241 " online [int]: Bool - Is this VCPU currently online?\n"
1242 " blocked [int]: Bool - Is this VCPU blocked waiting for an event?\n"
1243 " running [int]: Bool - Is this VCPU currently running on a CPU?\n"
1244 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1245 " cpumap [int]: Bitmap of CPUs this VCPU can run on\n"
1246 " cpu [int]: CPU that this VCPU is currently bound to\n" },
1248 { "linux_build",
1249 (PyCFunction)pyxc_linux_build,
1250 METH_VARARGS | METH_KEYWORDS, "\n"
1251 "Build a new Linux guest OS.\n"
1252 " dom [int]: Identifier of domain to build into.\n"
1253 " image [str]: Name of kernel image file. May be gzipped.\n"
1254 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
1255 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
1256 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1257 "Returns: [int] 0 on success; -1 on error.\n" },
1259 { "hvm_build",
1260 (PyCFunction)pyxc_hvm_build,
1261 METH_VARARGS | METH_KEYWORDS, "\n"
1262 "Build a new HVM guest OS.\n"
1263 " dom [int]: Identifier of domain to build into.\n"
1264 " image [str]: Name of HVM loader image file.\n"
1265 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1266 "Returns: [int] 0 on success; -1 on error.\n" },
1268 { "sched_id_get",
1269 (PyCFunction)pyxc_sched_id_get,
1270 METH_NOARGS, "\n"
1271 "Get the current scheduler type in use.\n"
1272 "Returns: [int] sched_id.\n" },
1274 { "sedf_domain_set",
1275 (PyCFunction)pyxc_sedf_domain_set,
1276 METH_KEYWORDS, "\n"
1277 "Set the scheduling parameters for a domain when running with Atropos.\n"
1278 " dom [int]: domain to set\n"
1279 " period [long]: domain's scheduling period\n"
1280 " slice [long]: domain's slice per period\n"
1281 " latency [long]: domain's wakeup latency hint\n"
1282 " extratime [int]: domain aware of extratime?\n"
1283 "Returns: [int] 0 on success; -1 on error.\n" },
1285 { "sedf_domain_get",
1286 (PyCFunction)pyxc_sedf_domain_get,
1287 METH_VARARGS, "\n"
1288 "Get the current scheduling parameters for a domain when running with\n"
1289 "the Atropos scheduler."
1290 " dom [int]: domain to query\n"
1291 "Returns: [dict]\n"
1292 " domain [int]: domain ID\n"
1293 " period [long]: scheduler period\n"
1294 " slice [long]: CPU reservation per period\n"
1295 " latency [long]: domain's wakeup latency hint\n"
1296 " extratime [int]: domain aware of extratime?\n"},
1298 { "sched_credit_domain_set",
1299 (PyCFunction)pyxc_sched_credit_domain_set,
1300 METH_KEYWORDS, "\n"
1301 "Set the scheduling parameters for a domain when running with the\n"
1302 "SMP credit scheduler.\n"
1303 " domid [int]: domain id to set\n"
1304 " weight [short]: domain's scheduling weight\n"
1305 "Returns: [int] 0 on success; -1 on error.\n" },
1307 { "sched_credit_domain_get",
1308 (PyCFunction)pyxc_sched_credit_domain_get,
1309 METH_VARARGS, "\n"
1310 "Get the scheduling parameters for a domain when running with the\n"
1311 "SMP credit scheduler.\n"
1312 " domid [int]: domain id to get\n"
1313 "Returns: [dict]\n"
1314 " weight [short]: domain's scheduling weight\n"},
1316 { "evtchn_alloc_unbound",
1317 (PyCFunction)pyxc_evtchn_alloc_unbound,
1318 METH_VARARGS | METH_KEYWORDS, "\n"
1319 "Allocate an unbound port that will await a remote connection.\n"
1320 " dom [int]: Domain whose port space to allocate from.\n"
1321 " remote_dom [int]: Remote domain to accept connections from.\n\n"
1322 "Returns: [int] Unbound event-channel port.\n" },
1324 { "evtchn_reset",
1325 (PyCFunction)pyxc_evtchn_reset,
1326 METH_VARARGS | METH_KEYWORDS, "\n"
1327 "Reset all connections.\n"
1328 " dom [int]: Domain to reset.\n" },
1330 { "physdev_pci_access_modify",
1331 (PyCFunction)pyxc_physdev_pci_access_modify,
1332 METH_VARARGS | METH_KEYWORDS, "\n"
1333 "Allow a domain access to a PCI device\n"
1334 " dom [int]: Identifier of domain to be allowed access.\n"
1335 " bus [int]: PCI bus\n"
1336 " dev [int]: PCI slot\n"
1337 " func [int]: PCI function\n"
1338 " enable [int]: Non-zero means enable access; else disable access\n\n"
1339 "Returns: [int] 0 on success; -1 on error.\n" },
1341 { "readconsolering",
1342 (PyCFunction)pyxc_readconsolering,
1343 METH_VARARGS | METH_KEYWORDS, "\n"
1344 "Read Xen's console ring.\n"
1345 " clear [int, 0]: Bool - clear the ring after reading from it?\n\n"
1346 "Returns: [str] string is empty on failure.\n" },
1348 { "physinfo",
1349 (PyCFunction)pyxc_physinfo,
1350 METH_NOARGS, "\n"
1351 "Get information about the physical host machine\n"
1352 "Returns [dict]: information about the hardware"
1353 " [None]: on failure.\n" },
1355 { "xeninfo",
1356 (PyCFunction)pyxc_xeninfo,
1357 METH_NOARGS, "\n"
1358 "Get information about the Xen host\n"
1359 "Returns [dict]: information about Xen"
1360 " [None]: on failure.\n" },
1362 { "shadow_control",
1363 (PyCFunction)pyxc_shadow_control,
1364 METH_VARARGS | METH_KEYWORDS, "\n"
1365 "Set parameter for shadow pagetable interface\n"
1366 " dom [int]: Identifier of domain.\n"
1367 " op [int, 0]: operation\n\n"
1368 "Returns: [int] 0 on success; -1 on error.\n" },
1370 { "shadow_mem_control",
1371 (PyCFunction)pyxc_shadow_mem_control,
1372 METH_VARARGS | METH_KEYWORDS, "\n"
1373 "Set or read shadow pagetable memory use\n"
1374 " dom [int]: Identifier of domain.\n"
1375 " mb [int, -1]: MB of shadow memory this domain should have.\n\n"
1376 "Returns: [int] MB of shadow memory in use by this domain.\n" },
1378 { "domain_setmaxmem",
1379 (PyCFunction)pyxc_domain_setmaxmem,
1380 METH_VARARGS, "\n"
1381 "Set a domain's memory limit\n"
1382 " dom [int]: Identifier of domain.\n"
1383 " maxmem_kb [int]: .\n"
1384 "Returns: [int] 0 on success; -1 on error.\n" },
1386 { "domain_set_memmap_limit",
1387 (PyCFunction)pyxc_domain_set_memmap_limit,
1388 METH_VARARGS, "\n"
1389 "Set a domain's physical memory mappping limit\n"
1390 " dom [int]: Identifier of domain.\n"
1391 " map_limitkb [int]: .\n"
1392 "Returns: [int] 0 on success; -1 on error.\n" },
1394 { "domain_memory_increase_reservation",
1395 (PyCFunction)pyxc_domain_memory_increase_reservation,
1396 METH_VARARGS | METH_KEYWORDS, "\n"
1397 "Increase a domain's memory reservation\n"
1398 " dom [int]: Identifier of domain.\n"
1399 " mem_kb [long]: .\n"
1400 "Returns: [int] 0 on success; -1 on error.\n" },
1402 { "domain_ioport_permission",
1403 (PyCFunction)pyxc_domain_ioport_permission,
1404 METH_VARARGS | METH_KEYWORDS, "\n"
1405 "Allow a domain access to a range of IO ports\n"
1406 " dom [int]: Identifier of domain to be allowed access.\n"
1407 " first_port [int]: First IO port\n"
1408 " nr_ports [int]: Number of IO ports\n"
1409 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1410 "Returns: [int] 0 on success; -1 on error.\n" },
1412 { "domain_irq_permission",
1413 (PyCFunction)pyxc_domain_irq_permission,
1414 METH_VARARGS | METH_KEYWORDS, "\n"
1415 "Allow a domain access to a physical IRQ\n"
1416 " dom [int]: Identifier of domain to be allowed access.\n"
1417 " pirq [int]: The Physical IRQ\n"
1418 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1419 "Returns: [int] 0 on success; -1 on error.\n" },
1421 { "domain_iomem_permission",
1422 (PyCFunction)pyxc_domain_iomem_permission,
1423 METH_VARARGS | METH_KEYWORDS, "\n"
1424 "Allow a domain access to a range of IO memory pages\n"
1425 " dom [int]: Identifier of domain to be allowed access.\n"
1426 " first_pfn [long]: First page of I/O Memory\n"
1427 " nr_pfns [long]: Number of pages of I/O Memory (>0)\n"
1428 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1429 "Returns: [int] 0 on success; -1 on error.\n" },
1431 { "pages_to_kib",
1432 (PyCFunction)pyxc_pages_to_kib,
1433 METH_VARARGS, "\n"
1434 "Returns: [int]: The size in KiB of memory spanning the given number "
1435 "of pages.\n" },
1437 { "domain_set_time_offset",
1438 (PyCFunction)pyxc_domain_set_time_offset,
1439 METH_VARARGS, "\n"
1440 "Set a domain's time offset to Dom0's localtime\n"
1441 " dom [int]: Domain whose time offset is being set.\n"
1442 "Returns: [int] 0 on success; -1 on error.\n" },
1444 { "domain_send_trigger",
1445 (PyCFunction)pyxc_domain_send_trigger,
1446 METH_VARARGS | METH_KEYWORDS, "\n"
1447 "Send trigger to a domain.\n"
1448 " dom [int]: Identifier of domain to be sent trigger.\n"
1449 " trigger [int]: Trigger type number.\n"
1450 " vcpu [int]: VCPU to be sent trigger.\n"
1451 "Returns: [int] 0 on success; -1 on error.\n" },
1453 { "send_debug_keys",
1454 (PyCFunction)pyxc_send_debug_keys,
1455 METH_VARARGS | METH_KEYWORDS, "\n"
1456 "Inject debug keys into Xen.\n"
1457 " keys [str]: String of keys to inject.\n" },
1459 #ifdef __powerpc__
1460 { "arch_alloc_real_mode_area",
1461 (PyCFunction)pyxc_alloc_real_mode_area,
1462 METH_VARARGS | METH_KEYWORDS, "\n"
1463 "Allocate a domain's real mode area.\n"
1464 " dom [int]: Identifier of domain.\n"
1465 " log [int]: Specifies the area's size.\n"
1466 "Returns: [int] 0 on success; -1 on error.\n" },
1468 { "arch_prose_build",
1469 (PyCFunction)pyxc_prose_build,
1470 METH_VARARGS | METH_KEYWORDS, "\n"
1471 "Build a new Linux guest OS.\n"
1472 " dom [int]: Identifier of domain to build into.\n"
1473 " image [str]: Name of kernel image file. May be gzipped.\n"
1474 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
1475 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
1476 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1477 "Returns: [int] 0 on success; -1 on error.\n" },
1478 #endif /* __powerpc */
1480 { NULL, NULL, 0, NULL }
1481 };
1484 static PyObject *PyXc_getattr(PyObject *obj, char *name)
1486 return Py_FindMethod(pyxc_methods, obj, name);
1489 static PyObject *PyXc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1491 XcObject *self = (XcObject *)type->tp_alloc(type, 0);
1493 if (self == NULL)
1494 return NULL;
1496 self->xc_handle = -1;
1498 return (PyObject *)self;
1501 static int
1502 PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
1504 if ((self->xc_handle = xc_interface_open()) == -1) {
1505 pyxc_error_to_exception();
1506 return -1;
1509 return 0;
1512 static void PyXc_dealloc(XcObject *self)
1514 if (self->xc_handle != -1) {
1515 xc_interface_close(self->xc_handle);
1516 self->xc_handle = -1;
1519 self->ob_type->tp_free((PyObject *)self);
1522 static PyTypeObject PyXcType = {
1523 PyObject_HEAD_INIT(NULL)
1524 0,
1525 PKG "." CLS,
1526 sizeof(XcObject),
1527 0,
1528 (destructor)PyXc_dealloc, /* tp_dealloc */
1529 NULL, /* tp_print */
1530 PyXc_getattr, /* tp_getattr */
1531 NULL, /* tp_setattr */
1532 NULL, /* tp_compare */
1533 NULL, /* tp_repr */
1534 NULL, /* tp_as_number */
1535 NULL, /* tp_as_sequence */
1536 NULL, /* tp_as_mapping */
1537 NULL, /* tp_hash */
1538 NULL, /* tp_call */
1539 NULL, /* tp_str */
1540 NULL, /* tp_getattro */
1541 NULL, /* tp_setattro */
1542 NULL, /* tp_as_buffer */
1543 Py_TPFLAGS_DEFAULT, /* tp_flags */
1544 "Xen client connections", /* tp_doc */
1545 NULL, /* tp_traverse */
1546 NULL, /* tp_clear */
1547 NULL, /* tp_richcompare */
1548 0, /* tp_weaklistoffset */
1549 NULL, /* tp_iter */
1550 NULL, /* tp_iternext */
1551 pyxc_methods, /* tp_methods */
1552 NULL, /* tp_members */
1553 NULL, /* tp_getset */
1554 NULL, /* tp_base */
1555 NULL, /* tp_dict */
1556 NULL, /* tp_descr_get */
1557 NULL, /* tp_descr_set */
1558 0, /* tp_dictoffset */
1559 (initproc)PyXc_init, /* tp_init */
1560 NULL, /* tp_alloc */
1561 PyXc_new, /* tp_new */
1562 };
1564 static PyMethodDef xc_methods[] = { { NULL } };
1566 PyMODINIT_FUNC initxc(void)
1568 PyObject *m;
1570 if (PyType_Ready(&PyXcType) < 0)
1571 return;
1573 m = Py_InitModule(PKG, xc_methods);
1575 if (m == NULL)
1576 return;
1578 xc_error_obj = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
1579 zero = PyInt_FromLong(0);
1581 /* KAF: This ensures that we get debug output in a timely manner. */
1582 setbuf(stdout, NULL);
1583 setbuf(stderr, NULL);
1585 Py_INCREF(&PyXcType);
1586 PyModule_AddObject(m, CLS, (PyObject *)&PyXcType);
1588 Py_INCREF(xc_error_obj);
1589 PyModule_AddObject(m, "Error", xc_error_obj);
1591 /* Expose some libxc constants to Python */
1592 PyModule_AddIntConstant(m, "XEN_SCHEDULER_SEDF", XEN_SCHEDULER_SEDF);
1593 PyModule_AddIntConstant(m, "XEN_SCHEDULER_CREDIT", XEN_SCHEDULER_CREDIT);
1598 /*
1599 * Local variables:
1600 * c-indent-level: 4
1601 * c-basic-offset: 4
1602 * End:
1603 */