ia64/xen-unstable

view tools/python/xen/lowlevel/xc/xc.c @ 14169:8939316a0735

Fix off-by-one preventing the last elfnote from being read in xc.c.

Signed-off-by: Brendan Cully <brendan@cs.ubc.ca>
author kfraser@localhost.localdomain
date Wed Feb 28 09:38:14 2007 +0000 (2007-02-28)
parents a20ec270998b
children 270a5e2ead43
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 /* Needed for Python versions earlier than 2.3. */
27 #ifndef PyMODINIT_FUNC
28 #define PyMODINIT_FUNC DL_EXPORT(void)
29 #endif
31 #define PKG "xen.lowlevel.xc"
32 #define CLS "xc"
34 static PyObject *xc_error_obj, *zero;
36 typedef struct {
37 PyObject_HEAD;
38 int xc_handle;
39 } XcObject;
42 static PyObject *dom_op(XcObject *self, PyObject *args,
43 int (*fn)(int, uint32_t));
45 static PyObject *pyxc_error_to_exception(void)
46 {
47 PyObject *pyerr;
48 const xc_error const *err = xc_get_last_error();
49 const char *desc = xc_error_code_to_desc(err->code);
51 if (err->code == XC_ERROR_NONE)
52 return PyErr_SetFromErrno(xc_error_obj);
54 if (err->message[0] != '\0')
55 pyerr = Py_BuildValue("(iss)", err->code, desc, err->message);
56 else
57 pyerr = Py_BuildValue("(is)", err->code, desc);
59 xc_clear_last_error();
61 PyErr_SetObject(xc_error_obj, pyerr);
63 return NULL;
64 }
66 static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
67 {
68 uint32_t dom;
69 char *corefile;
71 if (!PyArg_ParseTuple(args, "is", &dom, &corefile))
72 return NULL;
74 if ( (corefile == NULL) || (corefile[0] == '\0') )
75 return NULL;
77 if (xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0)
78 return pyxc_error_to_exception();
80 Py_INCREF(zero);
81 return zero;
82 }
84 static PyObject *pyxc_handle(XcObject *self)
85 {
86 return PyInt_FromLong(self->xc_handle);
87 }
89 static PyObject *pyxc_domain_create(XcObject *self,
90 PyObject *args,
91 PyObject *kwds)
92 {
93 uint32_t dom = 0, ssidref = 0, flags = 0;
94 int ret, i, hvm = 0;
95 PyObject *pyhandle = NULL;
96 xen_domain_handle_t handle = {
97 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
98 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef };
100 static char *kwd_list[] = { "domid", "ssidref", "handle", "hvm", NULL };
102 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOi", kwd_list,
103 &dom, &ssidref, &pyhandle, &hvm))
104 return NULL;
106 if ( pyhandle != NULL )
107 {
108 if ( !PyList_Check(pyhandle) ||
109 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
110 goto out_exception;
112 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
113 {
114 PyObject *p = PyList_GetItem(pyhandle, i);
115 if ( !PyInt_Check(p) )
116 goto out_exception;
117 handle[i] = (uint8_t)PyInt_AsLong(p);
118 }
119 }
121 if ( hvm )
122 flags |= XEN_DOMCTL_CDF_hvm_guest;
124 if ( (ret = xc_domain_create(self->xc_handle, ssidref,
125 handle, flags, &dom)) < 0 )
126 return pyxc_error_to_exception();
128 return PyInt_FromLong(dom);
130 out_exception:
131 errno = EINVAL;
132 PyErr_SetFromErrno(xc_error_obj);
133 return NULL;
134 }
136 static PyObject *pyxc_domain_max_vcpus(XcObject *self, PyObject *args)
137 {
138 uint32_t dom, max;
140 if (!PyArg_ParseTuple(args, "ii", &dom, &max))
141 return NULL;
143 if (xc_domain_max_vcpus(self->xc_handle, dom, max) != 0)
144 return pyxc_error_to_exception();
146 Py_INCREF(zero);
147 return zero;
148 }
150 static PyObject *pyxc_domain_pause(XcObject *self, PyObject *args)
151 {
152 return dom_op(self, args, xc_domain_pause);
153 }
155 static PyObject *pyxc_domain_unpause(XcObject *self, PyObject *args)
156 {
157 return dom_op(self, args, xc_domain_unpause);
158 }
160 static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args)
161 {
162 return dom_op(self, args, xc_domain_destroy);
163 }
165 static PyObject *pyxc_domain_shutdown(XcObject *self, PyObject *args)
166 {
167 uint32_t dom, reason;
169 if (!PyArg_ParseTuple(args, "ii", &dom, &reason))
170 return NULL;
172 if (xc_domain_shutdown(self->xc_handle, dom, reason) != 0)
173 return pyxc_error_to_exception();
175 Py_INCREF(zero);
176 return zero;
177 }
179 static PyObject *pyxc_domain_resume(XcObject *self, PyObject *args)
180 {
181 return dom_op(self, args, xc_domain_resume);
182 }
184 static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
185 PyObject *args,
186 PyObject *kwds)
187 {
188 uint32_t dom;
189 int vcpu = 0, i;
190 uint64_t cpumap = ~0ULL;
191 PyObject *cpulist = NULL;
193 static char *kwd_list[] = { "domid", "vcpu", "cpumap", NULL };
195 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|iO", kwd_list,
196 &dom, &vcpu, &cpulist) )
197 return NULL;
199 if ( (cpulist != NULL) && PyList_Check(cpulist) )
200 {
201 cpumap = 0ULL;
202 for ( i = 0; i < PyList_Size(cpulist); i++ )
203 cpumap |= (uint64_t)1 << PyInt_AsLong(PyList_GetItem(cpulist, i));
204 }
206 if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
207 return pyxc_error_to_exception();
209 Py_INCREF(zero);
210 return zero;
211 }
213 static PyObject *pyxc_domain_setcpuweight(XcObject *self,
214 PyObject *args,
215 PyObject *kwds)
216 {
217 uint32_t dom;
218 float cpuweight = 1;
220 static char *kwd_list[] = { "domid", "cpuweight", NULL };
222 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|f", kwd_list,
223 &dom, &cpuweight) )
224 return NULL;
226 if ( xc_domain_setcpuweight(self->xc_handle, dom, cpuweight) != 0 )
227 return pyxc_error_to_exception();
229 Py_INCREF(zero);
230 return zero;
231 }
233 static PyObject *pyxc_domain_sethandle(XcObject *self, PyObject *args)
234 {
235 int i;
236 uint32_t dom;
237 PyObject *pyhandle;
238 xen_domain_handle_t handle;
240 if (!PyArg_ParseTuple(args, "iO", &dom, &pyhandle))
241 return NULL;
243 if ( !PyList_Check(pyhandle) ||
244 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
245 {
246 goto out_exception;
247 }
249 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
250 {
251 PyObject *p = PyList_GetItem(pyhandle, i);
252 if ( !PyInt_Check(p) )
253 goto out_exception;
254 handle[i] = (uint8_t)PyInt_AsLong(p);
255 }
257 if (xc_domain_sethandle(self->xc_handle, dom, handle) < 0)
258 return pyxc_error_to_exception();
260 Py_INCREF(zero);
261 return zero;
263 out_exception:
264 PyErr_SetFromErrno(xc_error_obj);
265 return NULL;
266 }
269 static PyObject *pyxc_domain_getinfo(XcObject *self,
270 PyObject *args,
271 PyObject *kwds)
272 {
273 PyObject *list, *info_dict;
275 uint32_t first_dom = 0;
276 int max_doms = 1024, nr_doms, i, j;
277 xc_dominfo_t *info;
279 static char *kwd_list[] = { "first_dom", "max_doms", NULL };
281 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
282 &first_dom, &max_doms) )
283 return NULL;
285 if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL )
286 return PyErr_NoMemory();
288 nr_doms = xc_domain_getinfo(self->xc_handle, first_dom, max_doms, info);
290 if (nr_doms < 0)
291 {
292 free(info);
293 return pyxc_error_to_exception();
294 }
296 list = PyList_New(nr_doms);
297 for ( i = 0 ; i < nr_doms; i++ )
298 {
299 PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t));
300 for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
301 PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
302 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
303 ",s:l,s:L,s:l,s:i,s:i}",
304 "domid", info[i].domid,
305 "online_vcpus", info[i].nr_online_vcpus,
306 "max_vcpu_id", info[i].max_vcpu_id,
307 "hvm", info[i].hvm,
308 "dying", info[i].dying,
309 "crashed", info[i].crashed,
310 "shutdown", info[i].shutdown,
311 "paused", info[i].paused,
312 "blocked", info[i].blocked,
313 "running", info[i].running,
314 "mem_kb", info[i].nr_pages*(XC_PAGE_SIZE/1024),
315 "cpu_time", info[i].cpu_time,
316 "maxmem_kb", info[i].max_memkb,
317 "ssidref", info[i].ssidref,
318 "shutdown_reason", info[i].shutdown_reason);
319 PyDict_SetItemString(info_dict, "handle", pyhandle);
320 Py_DECREF(pyhandle);
321 PyList_SetItem(list, i, info_dict);
322 }
324 free(info);
326 return list;
327 }
329 static PyObject *pyxc_vcpu_getinfo(XcObject *self,
330 PyObject *args,
331 PyObject *kwds)
332 {
333 PyObject *info_dict, *cpulist;
335 uint32_t dom, vcpu = 0;
336 xc_vcpuinfo_t info;
337 int rc, i;
338 uint64_t cpumap;
340 static char *kwd_list[] = { "domid", "vcpu", NULL };
342 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
343 &dom, &vcpu) )
344 return NULL;
346 rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
347 if ( rc < 0 )
348 return pyxc_error_to_exception();
349 rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, &cpumap);
350 if ( rc < 0 )
351 return pyxc_error_to_exception();
353 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}",
354 "online", info.online,
355 "blocked", info.blocked,
356 "running", info.running,
357 "cpu_time", info.cpu_time,
358 "cpu", info.cpu);
360 cpulist = PyList_New(0);
361 for ( i = 0; cpumap != 0; i++ )
362 {
363 if ( cpumap & 1 )
364 PyList_Append(cpulist, PyInt_FromLong(i));
365 cpumap >>= 1;
366 }
367 PyDict_SetItemString(info_dict, "cpumap", cpulist);
368 Py_DECREF(cpulist);
369 return info_dict;
370 }
372 static PyObject *pyxc_linux_build(XcObject *self,
373 PyObject *args,
374 PyObject *kwds)
375 {
376 uint32_t domid;
377 struct xc_dom_image *dom;
378 char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
379 int flags = 0;
380 int store_evtchn, console_evtchn;
381 unsigned int mem_mb;
382 unsigned long store_mfn = 0;
383 unsigned long console_mfn = 0;
384 PyObject* elfnote_dict;
385 PyObject* elfnote = NULL;
386 int i;
388 static char *kwd_list[] = { "domid", "store_evtchn", "memsize",
389 "console_evtchn", "image",
390 /* optional */
391 "ramdisk", "cmdline", "flags",
392 "features", NULL };
394 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis", kwd_list,
395 &domid, &store_evtchn, &mem_mb,
396 &console_evtchn, &image,
397 /* optional */
398 &ramdisk, &cmdline, &flags,
399 &features) )
400 return NULL;
402 xc_dom_loginit();
403 if (!(dom = xc_dom_allocate(cmdline, features)))
404 return pyxc_error_to_exception();
406 if ( xc_dom_linux_build(self->xc_handle, dom, domid, mem_mb, image,
407 ramdisk, flags, store_evtchn, &store_mfn,
408 console_evtchn, &console_mfn) != 0 ) {
409 goto out;
410 }
412 if (!(elfnote_dict = PyDict_New()))
413 goto out;
414 for (i = 0; i <= XEN_ELFNOTE_MAX; i++) {
415 switch (dom->parms.elf_notes[i].type) {
416 case XEN_ENT_NONE:
417 continue;
418 case XEN_ENT_LONG:
419 elfnote = Py_BuildValue("k", dom->parms.elf_notes[i].data.num);
420 break;
421 case XEN_ENT_STR:
422 elfnote = Py_BuildValue("s", dom->parms.elf_notes[i].data.str);
423 break;
424 }
425 PyDict_SetItemString(elfnote_dict,
426 dom->parms.elf_notes[i].name,
427 elfnote);
428 Py_DECREF(elfnote);
429 }
431 xc_dom_release(dom);
433 return Py_BuildValue("{s:i,s:i,s:N}",
434 "store_mfn", store_mfn,
435 "console_mfn", console_mfn,
436 "notes", elfnote_dict);
438 out:
439 xc_dom_release(dom);
440 return pyxc_error_to_exception();
441 }
443 static PyObject *pyxc_hvm_build(XcObject *self,
444 PyObject *args,
445 PyObject *kwds)
446 {
447 uint32_t dom;
448 #if !defined(__ia64__)
449 struct hvm_info_table *va_hvm;
450 uint8_t *va_map, sum;
451 int i;
452 #endif
453 char *image;
454 int store_evtchn, memsize, vcpus = 1, pae = 0, acpi = 0, apic = 1;
455 unsigned long store_mfn;
457 static char *kwd_list[] = { "domid", "store_evtchn",
458 "memsize", "image", "vcpus", "pae", "acpi",
459 "apic", NULL };
460 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|iiii", kwd_list,
461 &dom, &store_evtchn, &memsize,
462 &image, &vcpus, &pae, &acpi, &apic) )
463 return NULL;
465 if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
466 return pyxc_error_to_exception();
468 #if !defined(__ia64__)
469 /* Set up the HVM info table. */
470 va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
471 PROT_READ | PROT_WRITE,
472 HVM_INFO_PFN);
473 if ( va_map == NULL )
474 return PyErr_SetFromErrno(xc_error_obj);
475 va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
476 memset(va_hvm, 0, sizeof(*va_hvm));
477 strncpy(va_hvm->signature, "HVM INFO", 8);
478 va_hvm->length = sizeof(struct hvm_info_table);
479 va_hvm->acpi_enabled = acpi;
480 va_hvm->apic_mode = apic;
481 va_hvm->nr_vcpus = vcpus;
482 for ( i = 0, sum = 0; i < va_hvm->length; i++ )
483 sum += ((uint8_t *)va_hvm)[i];
484 va_hvm->checksum = -sum;
485 munmap(va_map, XC_PAGE_SIZE);
486 #endif
488 xc_get_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_PFN, &store_mfn);
489 #if !defined(__ia64__)
490 xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
491 #endif
492 xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_EVTCHN,
493 store_evtchn);
495 return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
496 }
498 static PyObject *pyxc_evtchn_alloc_unbound(XcObject *self,
499 PyObject *args,
500 PyObject *kwds)
501 {
502 uint32_t dom, remote_dom;
503 int port;
505 static char *kwd_list[] = { "domid", "remote_dom", NULL };
507 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
508 &dom, &remote_dom) )
509 return NULL;
511 if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) < 0 )
512 return pyxc_error_to_exception();
514 return PyInt_FromLong(port);
515 }
517 static PyObject *pyxc_evtchn_reset(XcObject *self,
518 PyObject *args,
519 PyObject *kwds)
520 {
521 uint32_t dom;
523 static char *kwd_list[] = { "dom", NULL };
525 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
526 return NULL;
528 if ( xc_evtchn_reset(self->xc_handle, dom) < 0 )
529 return pyxc_error_to_exception();
531 Py_INCREF(zero);
532 return zero;
533 }
535 static PyObject *pyxc_physdev_pci_access_modify(XcObject *self,
536 PyObject *args,
537 PyObject *kwds)
538 {
539 uint32_t dom;
540 int bus, dev, func, enable, ret;
542 static char *kwd_list[] = { "domid", "bus", "dev", "func", "enable", NULL };
544 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list,
545 &dom, &bus, &dev, &func, &enable) )
546 return NULL;
548 ret = xc_physdev_pci_access_modify(
549 self->xc_handle, dom, bus, dev, func, enable);
550 if ( ret != 0 )
551 return pyxc_error_to_exception();
553 Py_INCREF(zero);
554 return zero;
555 }
557 static PyObject *pyxc_readconsolering(XcObject *self,
558 PyObject *args,
559 PyObject *kwds)
560 {
561 unsigned int clear = 0;
562 char _str[32768], *str = _str;
563 unsigned int count = 32768;
564 int ret;
566 static char *kwd_list[] = { "clear", NULL };
568 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &clear) )
569 return NULL;
571 ret = xc_readconsolering(self->xc_handle, &str, &count, clear);
572 if ( ret < 0 )
573 return pyxc_error_to_exception();
575 return PyString_FromStringAndSize(str, count);
576 }
579 static unsigned long pages_to_kib(unsigned long pages)
580 {
581 return pages * (XC_PAGE_SIZE / 1024);
582 }
585 static PyObject *pyxc_pages_to_kib(XcObject *self, PyObject *args)
586 {
587 unsigned long pages;
589 if (!PyArg_ParseTuple(args, "l", &pages))
590 return NULL;
592 return PyLong_FromUnsignedLong(pages_to_kib(pages));
593 }
596 static PyObject *pyxc_physinfo(XcObject *self)
597 {
598 xc_physinfo_t info;
599 char cpu_cap[128], *p=cpu_cap, *q=cpu_cap;
600 int i;
602 if ( xc_physinfo(self->xc_handle, &info) != 0 )
603 return pyxc_error_to_exception();
605 *q=0;
606 for(i=0;i<sizeof(info.hw_cap)/4;i++)
607 {
608 p+=sprintf(p,"%08x:",info.hw_cap[i]);
609 if(info.hw_cap[i])
610 q=p;
611 }
612 if(q>cpu_cap)
613 *(q-1)=0;
615 return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s}",
616 "threads_per_core", info.threads_per_core,
617 "cores_per_socket", info.cores_per_socket,
618 "sockets_per_node", info.sockets_per_node,
619 "nr_nodes", info.nr_nodes,
620 "total_memory", pages_to_kib(info.total_pages),
621 "free_memory", pages_to_kib(info.free_pages),
622 "scrub_memory", pages_to_kib(info.scrub_pages),
623 "cpu_khz", info.cpu_khz,
624 "hw_caps", cpu_cap);
625 }
627 static PyObject *pyxc_xeninfo(XcObject *self)
628 {
629 xen_extraversion_t xen_extra;
630 xen_compile_info_t xen_cc;
631 xen_changeset_info_t xen_chgset;
632 xen_capabilities_info_t xen_caps;
633 xen_platform_parameters_t p_parms;
634 long xen_version;
635 long xen_pagesize;
636 char str[128];
638 xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
640 if ( xc_version(self->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
641 return pyxc_error_to_exception();
643 if ( xc_version(self->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
644 return pyxc_error_to_exception();
646 if ( xc_version(self->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
647 return pyxc_error_to_exception();
649 if ( xc_version(self->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
650 return pyxc_error_to_exception();
652 if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) != 0 )
653 return pyxc_error_to_exception();
655 sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
657 xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
658 if (xen_pagesize < 0 )
659 return pyxc_error_to_exception();
661 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}",
662 "xen_major", xen_version >> 16,
663 "xen_minor", (xen_version & 0xffff),
664 "xen_extra", xen_extra,
665 "xen_caps", xen_caps,
666 "xen_pagesize", xen_pagesize,
667 "platform_params", str,
668 "xen_changeset", xen_chgset,
669 "cc_compiler", xen_cc.compiler,
670 "cc_compile_by", xen_cc.compile_by,
671 "cc_compile_domain", xen_cc.compile_domain,
672 "cc_compile_date", xen_cc.compile_date);
673 }
676 static PyObject *pyxc_sedf_domain_set(XcObject *self,
677 PyObject *args,
678 PyObject *kwds)
679 {
680 uint32_t domid;
681 uint64_t period, slice, latency;
682 uint16_t extratime, weight;
683 static char *kwd_list[] = { "domid", "period", "slice",
684 "latency", "extratime", "weight",NULL };
686 if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLhh", kwd_list,
687 &domid, &period, &slice,
688 &latency, &extratime, &weight) )
689 return NULL;
690 if ( xc_sedf_domain_set(self->xc_handle, domid, period,
691 slice, latency, extratime,weight) != 0 )
692 return pyxc_error_to_exception();
694 Py_INCREF(zero);
695 return zero;
696 }
698 static PyObject *pyxc_sedf_domain_get(XcObject *self, PyObject *args)
699 {
700 uint32_t domid;
701 uint64_t period, slice,latency;
702 uint16_t weight, extratime;
704 if(!PyArg_ParseTuple(args, "i", &domid))
705 return NULL;
707 if (xc_sedf_domain_get(self->xc_handle, domid, &period,
708 &slice,&latency,&extratime,&weight))
709 return pyxc_error_to_exception();
711 return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
712 "domid", domid,
713 "period", period,
714 "slice", slice,
715 "latency", latency,
716 "extratime", extratime,
717 "weight", weight);
718 }
720 static PyObject *pyxc_shadow_control(PyObject *self,
721 PyObject *args,
722 PyObject *kwds)
723 {
724 XcObject *xc = (XcObject *)self;
726 uint32_t dom;
727 int op=0;
729 static char *kwd_list[] = { "dom", "op", NULL };
731 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
732 &dom, &op) )
733 return NULL;
735 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL, 0, NULL)
736 < 0 )
737 return pyxc_error_to_exception();
739 Py_INCREF(zero);
740 return zero;
741 }
743 static PyObject *pyxc_shadow_mem_control(PyObject *self,
744 PyObject *args,
745 PyObject *kwds)
746 {
747 XcObject *xc = (XcObject *)self;
748 int op;
749 uint32_t dom;
750 int mbarg = -1;
751 unsigned long mb;
753 static char *kwd_list[] = { "dom", "mb", NULL };
755 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
756 &dom, &mbarg) )
757 return NULL;
759 if ( mbarg < 0 )
760 op = XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION;
761 else
762 {
763 mb = mbarg;
764 op = XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION;
765 }
766 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, &mb, 0, NULL) < 0 )
767 return pyxc_error_to_exception();
769 mbarg = mb;
770 return Py_BuildValue("i", mbarg);
771 }
773 static PyObject *pyxc_sched_id_get(XcObject *self) {
775 int sched_id;
776 if (xc_sched_id(self->xc_handle, &sched_id) != 0)
777 return PyErr_SetFromErrno(xc_error_obj);
779 return Py_BuildValue("i", sched_id);
780 }
782 static PyObject *pyxc_sched_credit_domain_set(XcObject *self,
783 PyObject *args,
784 PyObject *kwds)
785 {
786 uint32_t domid;
787 uint16_t weight;
788 uint16_t cap;
789 static char *kwd_list[] = { "domid", "weight", "cap", NULL };
790 static char kwd_type[] = "I|HH";
791 struct xen_domctl_sched_credit sdom;
793 weight = 0;
794 cap = (uint16_t)~0U;
795 if( !PyArg_ParseTupleAndKeywords(args, kwds, kwd_type, kwd_list,
796 &domid, &weight, &cap) )
797 return NULL;
799 sdom.weight = weight;
800 sdom.cap = cap;
802 if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 )
803 return pyxc_error_to_exception();
805 Py_INCREF(zero);
806 return zero;
807 }
809 static PyObject *pyxc_sched_credit_domain_get(XcObject *self, PyObject *args)
810 {
811 uint32_t domid;
812 struct xen_domctl_sched_credit sdom;
814 if( !PyArg_ParseTuple(args, "I", &domid) )
815 return NULL;
817 if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 )
818 return pyxc_error_to_exception();
820 return Py_BuildValue("{s:H,s:H}",
821 "weight", sdom.weight,
822 "cap", sdom.cap);
823 }
825 static PyObject *pyxc_domain_setmaxmem(XcObject *self, PyObject *args)
826 {
827 uint32_t dom;
828 unsigned int maxmem_kb;
830 if (!PyArg_ParseTuple(args, "ii", &dom, &maxmem_kb))
831 return NULL;
833 if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0)
834 return pyxc_error_to_exception();
836 Py_INCREF(zero);
837 return zero;
838 }
840 static PyObject *pyxc_domain_set_memmap_limit(XcObject *self, PyObject *args)
841 {
842 uint32_t dom;
843 unsigned int maplimit_kb;
845 if ( !PyArg_ParseTuple(args, "ii", &dom, &maplimit_kb) )
846 return NULL;
848 if ( xc_domain_set_memmap_limit(self->xc_handle, dom, maplimit_kb) != 0 )
849 return pyxc_error_to_exception();
851 Py_INCREF(zero);
852 return zero;
853 }
855 static PyObject *pyxc_domain_memory_increase_reservation(XcObject *self,
856 PyObject *args,
857 PyObject *kwds)
858 {
859 uint32_t dom;
860 unsigned long mem_kb;
861 unsigned int extent_order = 0 , address_bits = 0;
862 unsigned long nr_extents;
864 static char *kwd_list[] = { "domid", "mem_kb", "extent_order", "address_bits", NULL };
866 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "il|ii", kwd_list,
867 &dom, &mem_kb, &extent_order, &address_bits) )
868 return NULL;
870 /* round down to nearest power of 2. Assume callers using extent_order>0
871 know what they are doing */
872 nr_extents = (mem_kb / (XC_PAGE_SIZE/1024)) >> extent_order;
873 if ( xc_domain_memory_increase_reservation(self->xc_handle, dom,
874 nr_extents, extent_order,
875 address_bits, NULL) )
876 return pyxc_error_to_exception();
878 Py_INCREF(zero);
879 return zero;
880 }
882 static PyObject *pyxc_domain_ioport_permission(XcObject *self,
883 PyObject *args,
884 PyObject *kwds)
885 {
886 uint32_t dom;
887 int first_port, nr_ports, allow_access, ret;
889 static char *kwd_list[] = { "domid", "first_port", "nr_ports", "allow_access", NULL };
891 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiii", kwd_list,
892 &dom, &first_port, &nr_ports, &allow_access) )
893 return NULL;
895 ret = xc_domain_ioport_permission(
896 self->xc_handle, dom, first_port, nr_ports, allow_access);
897 if ( ret != 0 )
898 return pyxc_error_to_exception();
900 Py_INCREF(zero);
901 return zero;
902 }
904 static PyObject *pyxc_domain_irq_permission(PyObject *self,
905 PyObject *args,
906 PyObject *kwds)
907 {
908 XcObject *xc = (XcObject *)self;
909 uint32_t dom;
910 int pirq, allow_access, ret;
912 static char *kwd_list[] = { "domid", "pirq", "allow_access", NULL };
914 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list,
915 &dom, &pirq, &allow_access) )
916 return NULL;
918 ret = xc_domain_irq_permission(
919 xc->xc_handle, dom, pirq, allow_access);
920 if ( ret != 0 )
921 return pyxc_error_to_exception();
923 Py_INCREF(zero);
924 return zero;
925 }
927 static PyObject *pyxc_domain_iomem_permission(PyObject *self,
928 PyObject *args,
929 PyObject *kwds)
930 {
931 XcObject *xc = (XcObject *)self;
932 uint32_t dom;
933 unsigned long first_pfn, nr_pfns, allow_access, ret;
935 static char *kwd_list[] = { "domid", "first_pfn", "nr_pfns", "allow_access", NULL };
937 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illi", kwd_list,
938 &dom, &first_pfn, &nr_pfns, &allow_access) )
939 return NULL;
941 ret = xc_domain_iomem_permission(
942 xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
943 if ( ret != 0 )
944 return pyxc_error_to_exception();
946 Py_INCREF(zero);
947 return zero;
948 }
950 static PyObject *pyxc_domain_set_time_offset(XcObject *self, PyObject *args)
951 {
952 uint32_t dom;
953 int32_t time_offset_seconds;
954 time_t calendar_time;
955 struct tm local_time;
956 struct tm utc_time;
958 if (!PyArg_ParseTuple(args, "i", &dom))
959 return NULL;
961 calendar_time = time(NULL);
962 localtime_r(&calendar_time, &local_time);
963 gmtime_r(&calendar_time, &utc_time);
964 /* set up to get calendar time based on utc_time, with local dst setting */
965 utc_time.tm_isdst = local_time.tm_isdst;
966 time_offset_seconds = (int32_t)difftime(calendar_time, mktime(&utc_time));
968 if (xc_domain_set_time_offset(self->xc_handle, dom, time_offset_seconds) != 0)
969 return NULL;
971 Py_INCREF(zero);
972 return zero;
973 }
975 static PyObject *pyxc_domain_send_trigger(XcObject *self,
976 PyObject *args,
977 PyObject *kwds)
978 {
979 uint32_t dom;
980 int trigger, vcpu = 0;
982 static char *kwd_list[] = { "domid", "trigger", "vcpu", NULL };
984 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii|i", kwd_list,
985 &dom, &trigger, &vcpu) )
986 return NULL;
988 if (xc_domain_send_trigger(self->xc_handle, dom, trigger, vcpu) != 0)
989 return pyxc_error_to_exception();
991 Py_INCREF(zero);
992 return zero;
993 }
995 static PyObject *dom_op(XcObject *self, PyObject *args,
996 int (*fn)(int, uint32_t))
997 {
998 uint32_t dom;
1000 if (!PyArg_ParseTuple(args, "i", &dom))
1001 return NULL;
1003 if (fn(self->xc_handle, dom) != 0)
1004 return pyxc_error_to_exception();
1006 Py_INCREF(zero);
1007 return zero;
1010 #ifdef __powerpc__
1011 static PyObject *pyxc_alloc_real_mode_area(XcObject *self,
1012 PyObject *args,
1013 PyObject *kwds)
1015 uint32_t dom;
1016 unsigned int log;
1018 static char *kwd_list[] = { "dom", "log", NULL };
1020 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
1021 &dom, &log) )
1022 return NULL;
1024 if ( xc_alloc_real_mode_area(self->xc_handle, dom, log) )
1025 return pyxc_error_to_exception();
1027 Py_INCREF(zero);
1028 return zero;
1031 static PyObject *pyxc_prose_build(XcObject *self,
1032 PyObject *args,
1033 PyObject *kwds)
1035 uint32_t dom;
1036 char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
1037 int flags = 0;
1038 int store_evtchn, console_evtchn;
1039 unsigned int mem_mb;
1040 unsigned long store_mfn = 0;
1041 unsigned long console_mfn = 0;
1042 int unused;
1044 static char *kwd_list[] = { "dom", "store_evtchn",
1045 "console_evtchn", "image", "memsize",
1046 /* optional */
1047 "ramdisk", "cmdline", "flags",
1048 "features", NULL };
1050 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis#", kwd_list,
1051 &dom, &store_evtchn, &mem_mb,
1052 &console_evtchn, &image,
1053 /* optional */
1054 &ramdisk, &cmdline, &flags,
1055 &features, &unused) )
1056 return NULL;
1058 if ( xc_prose_build(self->xc_handle, dom, mem_mb, image,
1059 ramdisk, cmdline, features, flags,
1060 store_evtchn, &store_mfn,
1061 console_evtchn, &console_mfn) != 0 ) {
1062 if (!errno)
1063 errno = EINVAL;
1064 return pyxc_error_to_exception();
1066 return Py_BuildValue("{s:i,s:i}",
1067 "store_mfn", store_mfn,
1068 "console_mfn", console_mfn);
1070 #endif /* powerpc */
1072 static PyMethodDef pyxc_methods[] = {
1073 { "handle",
1074 (PyCFunction)pyxc_handle,
1075 METH_NOARGS, "\n"
1076 "Query the xc control interface file descriptor.\n\n"
1077 "Returns: [int] file descriptor\n" },
1079 { "domain_create",
1080 (PyCFunction)pyxc_domain_create,
1081 METH_VARARGS | METH_KEYWORDS, "\n"
1082 "Create a new domain.\n"
1083 " dom [int, 0]: Domain identifier to use (allocated if zero).\n"
1084 "Returns: [int] new domain identifier; -1 on error.\n" },
1086 { "domain_max_vcpus",
1087 (PyCFunction)pyxc_domain_max_vcpus,
1088 METH_VARARGS, "\n"
1089 "Set the maximum number of VCPUs a domain may create.\n"
1090 " dom [int, 0]: Domain identifier to use.\n"
1091 " max [int, 0]: New maximum number of VCPUs in domain.\n"
1092 "Returns: [int] 0 on success; -1 on error.\n" },
1094 { "domain_dumpcore",
1095 (PyCFunction)pyxc_domain_dumpcore,
1096 METH_VARARGS, "\n"
1097 "Dump core of a domain.\n"
1098 " dom [int]: Identifier of domain to dump core of.\n"
1099 " corefile [string]: Name of corefile to be created.\n\n"
1100 "Returns: [int] 0 on success; -1 on error.\n" },
1102 { "domain_pause",
1103 (PyCFunction)pyxc_domain_pause,
1104 METH_VARARGS, "\n"
1105 "Temporarily pause execution of a domain.\n"
1106 " dom [int]: Identifier of domain to be paused.\n\n"
1107 "Returns: [int] 0 on success; -1 on error.\n" },
1109 { "domain_unpause",
1110 (PyCFunction)pyxc_domain_unpause,
1111 METH_VARARGS, "\n"
1112 "(Re)start execution of a domain.\n"
1113 " dom [int]: Identifier of domain to be unpaused.\n\n"
1114 "Returns: [int] 0 on success; -1 on error.\n" },
1116 { "domain_destroy",
1117 (PyCFunction)pyxc_domain_destroy,
1118 METH_VARARGS, "\n"
1119 "Destroy a domain.\n"
1120 " dom [int]: Identifier of domain to be destroyed.\n\n"
1121 "Returns: [int] 0 on success; -1 on error.\n" },
1123 { "domain_resume",
1124 (PyCFunction)pyxc_domain_resume,
1125 METH_VARARGS, "\n"
1126 "Resume execution of a suspended domain.\n"
1127 " dom [int]: Identifier of domain to be resumed.\n\n"
1128 "Returns: [int] 0 on success; -1 on error.\n" },
1130 { "domain_shutdown",
1131 (PyCFunction)pyxc_domain_shutdown,
1132 METH_VARARGS, "\n"
1133 "Shutdown a domain.\n"
1134 " dom [int, 0]: Domain identifier to use.\n"
1135 " reason [int, 0]: Reason for shutdown.\n"
1136 "Returns: [int] 0 on success; -1 on error.\n" },
1138 { "vcpu_setaffinity",
1139 (PyCFunction)pyxc_vcpu_setaffinity,
1140 METH_VARARGS | METH_KEYWORDS, "\n"
1141 "Pin a VCPU to a specified set CPUs.\n"
1142 " dom [int]: Identifier of domain to which VCPU belongs.\n"
1143 " vcpu [int, 0]: VCPU being pinned.\n"
1144 " cpumap [list, []]: list of usable CPUs.\n\n"
1145 "Returns: [int] 0 on success; -1 on error.\n" },
1147 { "domain_setcpuweight",
1148 (PyCFunction)pyxc_domain_setcpuweight,
1149 METH_VARARGS | METH_KEYWORDS, "\n"
1150 "Set cpuweight scheduler parameter for domain.\n"
1151 " dom [int]: Identifier of domain to be changed.\n"
1152 " cpuweight [float, 1]: VCPU being pinned.\n"
1153 "Returns: [int] 0 on success; -1 on error.\n" },
1155 { "domain_sethandle",
1156 (PyCFunction)pyxc_domain_sethandle,
1157 METH_VARARGS, "\n"
1158 "Set domain's opaque handle.\n"
1159 " dom [int]: Identifier of domain.\n"
1160 " handle [list of 16 ints]: New opaque handle.\n"
1161 "Returns: [int] 0 on success; -1 on error.\n" },
1163 { "domain_getinfo",
1164 (PyCFunction)pyxc_domain_getinfo,
1165 METH_VARARGS | METH_KEYWORDS, "\n"
1166 "Get information regarding a set of domains, in increasing id order.\n"
1167 " first_dom [int, 0]: First domain to retrieve info about.\n"
1168 " max_doms [int, 1024]: Maximum number of domains to retrieve info"
1169 " about.\n\n"
1170 "Returns: [list of dicts] if list length is less than 'max_doms'\n"
1171 " parameter then there was an error, or the end of the\n"
1172 " domain-id space was reached.\n"
1173 " dom [int]: Identifier of domain to which this info pertains\n"
1174 " cpu [int]: CPU to which this domain is bound\n"
1175 " vcpus [int]: Number of Virtual CPUS in this domain\n"
1176 " dying [int]: Bool - is the domain dying?\n"
1177 " crashed [int]: Bool - has the domain crashed?\n"
1178 " shutdown [int]: Bool - has the domain shut itself down?\n"
1179 " paused [int]: Bool - is the domain paused by control software?\n"
1180 " blocked [int]: Bool - is the domain blocked waiting for an event?\n"
1181 " running [int]: Bool - is the domain currently running?\n"
1182 " mem_kb [int]: Memory reservation, in kilobytes\n"
1183 " maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
1184 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1185 " shutdown_reason [int]: Numeric code from guest OS, explaining "
1186 "reason why it shut itself down.\n" },
1188 { "vcpu_getinfo",
1189 (PyCFunction)pyxc_vcpu_getinfo,
1190 METH_VARARGS | METH_KEYWORDS, "\n"
1191 "Get information regarding a VCPU.\n"
1192 " dom [int]: Domain to retrieve info about.\n"
1193 " vcpu [int, 0]: VCPU to retrieve info about.\n\n"
1194 "Returns: [dict]\n"
1195 " online [int]: Bool - Is this VCPU currently online?\n"
1196 " blocked [int]: Bool - Is this VCPU blocked waiting for an event?\n"
1197 " running [int]: Bool - Is this VCPU currently running on a CPU?\n"
1198 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1199 " cpumap [int]: Bitmap of CPUs this VCPU can run on\n"
1200 " cpu [int]: CPU that this VCPU is currently bound to\n" },
1202 { "linux_build",
1203 (PyCFunction)pyxc_linux_build,
1204 METH_VARARGS | METH_KEYWORDS, "\n"
1205 "Build a new Linux guest OS.\n"
1206 " dom [int]: Identifier of domain to build into.\n"
1207 " image [str]: Name of kernel image file. May be gzipped.\n"
1208 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
1209 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
1210 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1211 "Returns: [int] 0 on success; -1 on error.\n" },
1213 { "hvm_build",
1214 (PyCFunction)pyxc_hvm_build,
1215 METH_VARARGS | METH_KEYWORDS, "\n"
1216 "Build a new HVM guest OS.\n"
1217 " dom [int]: Identifier of domain to build into.\n"
1218 " image [str]: Name of HVM loader image file.\n"
1219 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1220 "Returns: [int] 0 on success; -1 on error.\n" },
1222 { "sched_id_get",
1223 (PyCFunction)pyxc_sched_id_get,
1224 METH_NOARGS, "\n"
1225 "Get the current scheduler type in use.\n"
1226 "Returns: [int] sched_id.\n" },
1228 { "sedf_domain_set",
1229 (PyCFunction)pyxc_sedf_domain_set,
1230 METH_KEYWORDS, "\n"
1231 "Set the scheduling parameters for a domain when running with Atropos.\n"
1232 " dom [int]: domain to set\n"
1233 " period [long]: domain's scheduling period\n"
1234 " slice [long]: domain's slice per period\n"
1235 " latency [long]: domain's wakeup latency hint\n"
1236 " extratime [int]: domain aware of extratime?\n"
1237 "Returns: [int] 0 on success; -1 on error.\n" },
1239 { "sedf_domain_get",
1240 (PyCFunction)pyxc_sedf_domain_get,
1241 METH_VARARGS, "\n"
1242 "Get the current scheduling parameters for a domain when running with\n"
1243 "the Atropos scheduler."
1244 " dom [int]: domain to query\n"
1245 "Returns: [dict]\n"
1246 " domain [int]: domain ID\n"
1247 " period [long]: scheduler period\n"
1248 " slice [long]: CPU reservation per period\n"
1249 " latency [long]: domain's wakeup latency hint\n"
1250 " extratime [int]: domain aware of extratime?\n"},
1252 { "sched_credit_domain_set",
1253 (PyCFunction)pyxc_sched_credit_domain_set,
1254 METH_KEYWORDS, "\n"
1255 "Set the scheduling parameters for a domain when running with the\n"
1256 "SMP credit scheduler.\n"
1257 " domid [int]: domain id to set\n"
1258 " weight [short]: domain's scheduling weight\n"
1259 "Returns: [int] 0 on success; -1 on error.\n" },
1261 { "sched_credit_domain_get",
1262 (PyCFunction)pyxc_sched_credit_domain_get,
1263 METH_VARARGS, "\n"
1264 "Get the scheduling parameters for a domain when running with the\n"
1265 "SMP credit scheduler.\n"
1266 " domid [int]: domain id to get\n"
1267 "Returns: [dict]\n"
1268 " weight [short]: domain's scheduling weight\n"},
1270 { "evtchn_alloc_unbound",
1271 (PyCFunction)pyxc_evtchn_alloc_unbound,
1272 METH_VARARGS | METH_KEYWORDS, "\n"
1273 "Allocate an unbound port that will await a remote connection.\n"
1274 " dom [int]: Domain whose port space to allocate from.\n"
1275 " remote_dom [int]: Remote domain to accept connections from.\n\n"
1276 "Returns: [int] Unbound event-channel port.\n" },
1278 { "evtchn_reset",
1279 (PyCFunction)pyxc_evtchn_reset,
1280 METH_VARARGS | METH_KEYWORDS, "\n"
1281 "Reset all connections.\n"
1282 " dom [int]: Domain to reset.\n" },
1284 { "physdev_pci_access_modify",
1285 (PyCFunction)pyxc_physdev_pci_access_modify,
1286 METH_VARARGS | METH_KEYWORDS, "\n"
1287 "Allow a domain access to a PCI device\n"
1288 " dom [int]: Identifier of domain to be allowed access.\n"
1289 " bus [int]: PCI bus\n"
1290 " dev [int]: PCI slot\n"
1291 " func [int]: PCI function\n"
1292 " enable [int]: Non-zero means enable access; else disable access\n\n"
1293 "Returns: [int] 0 on success; -1 on error.\n" },
1295 { "readconsolering",
1296 (PyCFunction)pyxc_readconsolering,
1297 METH_VARARGS | METH_KEYWORDS, "\n"
1298 "Read Xen's console ring.\n"
1299 " clear [int, 0]: Bool - clear the ring after reading from it?\n\n"
1300 "Returns: [str] string is empty on failure.\n" },
1302 { "physinfo",
1303 (PyCFunction)pyxc_physinfo,
1304 METH_NOARGS, "\n"
1305 "Get information about the physical host machine\n"
1306 "Returns [dict]: information about the hardware"
1307 " [None]: on failure.\n" },
1309 { "xeninfo",
1310 (PyCFunction)pyxc_xeninfo,
1311 METH_NOARGS, "\n"
1312 "Get information about the Xen host\n"
1313 "Returns [dict]: information about Xen"
1314 " [None]: on failure.\n" },
1316 { "shadow_control",
1317 (PyCFunction)pyxc_shadow_control,
1318 METH_VARARGS | METH_KEYWORDS, "\n"
1319 "Set parameter for shadow pagetable interface\n"
1320 " dom [int]: Identifier of domain.\n"
1321 " op [int, 0]: operation\n\n"
1322 "Returns: [int] 0 on success; -1 on error.\n" },
1324 { "shadow_mem_control",
1325 (PyCFunction)pyxc_shadow_mem_control,
1326 METH_VARARGS | METH_KEYWORDS, "\n"
1327 "Set or read shadow pagetable memory use\n"
1328 " dom [int]: Identifier of domain.\n"
1329 " mb [int, -1]: MB of shadow memory this domain should have.\n\n"
1330 "Returns: [int] MB of shadow memory in use by this domain.\n" },
1332 { "domain_setmaxmem",
1333 (PyCFunction)pyxc_domain_setmaxmem,
1334 METH_VARARGS, "\n"
1335 "Set a domain's memory limit\n"
1336 " dom [int]: Identifier of domain.\n"
1337 " maxmem_kb [int]: .\n"
1338 "Returns: [int] 0 on success; -1 on error.\n" },
1340 { "domain_set_memmap_limit",
1341 (PyCFunction)pyxc_domain_set_memmap_limit,
1342 METH_VARARGS, "\n"
1343 "Set a domain's physical memory mappping limit\n"
1344 " dom [int]: Identifier of domain.\n"
1345 " map_limitkb [int]: .\n"
1346 "Returns: [int] 0 on success; -1 on error.\n" },
1348 { "domain_memory_increase_reservation",
1349 (PyCFunction)pyxc_domain_memory_increase_reservation,
1350 METH_VARARGS | METH_KEYWORDS, "\n"
1351 "Increase a domain's memory reservation\n"
1352 " dom [int]: Identifier of domain.\n"
1353 " mem_kb [long]: .\n"
1354 "Returns: [int] 0 on success; -1 on error.\n" },
1356 { "domain_ioport_permission",
1357 (PyCFunction)pyxc_domain_ioport_permission,
1358 METH_VARARGS | METH_KEYWORDS, "\n"
1359 "Allow a domain access to a range of IO ports\n"
1360 " dom [int]: Identifier of domain to be allowed access.\n"
1361 " first_port [int]: First IO port\n"
1362 " nr_ports [int]: Number of IO ports\n"
1363 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1364 "Returns: [int] 0 on success; -1 on error.\n" },
1366 { "domain_irq_permission",
1367 (PyCFunction)pyxc_domain_irq_permission,
1368 METH_VARARGS | METH_KEYWORDS, "\n"
1369 "Allow a domain access to a physical IRQ\n"
1370 " dom [int]: Identifier of domain to be allowed access.\n"
1371 " pirq [int]: The Physical IRQ\n"
1372 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1373 "Returns: [int] 0 on success; -1 on error.\n" },
1375 { "domain_iomem_permission",
1376 (PyCFunction)pyxc_domain_iomem_permission,
1377 METH_VARARGS | METH_KEYWORDS, "\n"
1378 "Allow a domain access to a range of IO memory pages\n"
1379 " dom [int]: Identifier of domain to be allowed access.\n"
1380 " first_pfn [long]: First page of I/O Memory\n"
1381 " nr_pfns [long]: Number of pages of I/O Memory (>0)\n"
1382 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1383 "Returns: [int] 0 on success; -1 on error.\n" },
1385 { "pages_to_kib",
1386 (PyCFunction)pyxc_pages_to_kib,
1387 METH_VARARGS, "\n"
1388 "Returns: [int]: The size in KiB of memory spanning the given number "
1389 "of pages.\n" },
1391 { "domain_set_time_offset",
1392 (PyCFunction)pyxc_domain_set_time_offset,
1393 METH_VARARGS, "\n"
1394 "Set a domain's time offset to Dom0's localtime\n"
1395 " dom [int]: Domain whose time offset is being set.\n"
1396 "Returns: [int] 0 on success; -1 on error.\n" },
1398 { "domain_send_trigger",
1399 (PyCFunction)pyxc_domain_send_trigger,
1400 METH_VARARGS | METH_KEYWORDS, "\n"
1401 "Send trigger to a domain.\n"
1402 " dom [int]: Identifier of domain to be sent trigger.\n"
1403 " trigger [int]: Trigger type number.\n"
1404 " vcpu [int]: VCPU to be sent trigger.\n"
1405 "Returns: [int] 0 on success; -1 on error.\n" },
1407 #ifdef __powerpc__
1408 { "arch_alloc_real_mode_area",
1409 (PyCFunction)pyxc_alloc_real_mode_area,
1410 METH_VARARGS | METH_KEYWORDS, "\n"
1411 "Allocate a domain's real mode area.\n"
1412 " dom [int]: Identifier of domain.\n"
1413 " log [int]: Specifies the area's size.\n"
1414 "Returns: [int] 0 on success; -1 on error.\n" },
1416 { "arch_prose_build",
1417 (PyCFunction)pyxc_prose_build,
1418 METH_VARARGS | METH_KEYWORDS, "\n"
1419 "Build a new Linux guest OS.\n"
1420 " dom [int]: Identifier of domain to build into.\n"
1421 " image [str]: Name of kernel image file. May be gzipped.\n"
1422 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
1423 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
1424 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1425 "Returns: [int] 0 on success; -1 on error.\n" },
1426 #endif /* __powerpc */
1428 { NULL, NULL, 0, NULL }
1429 };
1432 static PyObject *PyXc_getattr(PyObject *obj, char *name)
1434 return Py_FindMethod(pyxc_methods, obj, name);
1437 static PyObject *PyXc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1439 XcObject *self = (XcObject *)type->tp_alloc(type, 0);
1441 if (self == NULL)
1442 return NULL;
1444 self->xc_handle = -1;
1446 return (PyObject *)self;
1449 static int
1450 PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
1452 if ((self->xc_handle = xc_interface_open()) == -1) {
1453 pyxc_error_to_exception();
1454 return -1;
1457 return 0;
1460 static void PyXc_dealloc(XcObject *self)
1462 if (self->xc_handle != -1) {
1463 xc_interface_close(self->xc_handle);
1464 self->xc_handle = -1;
1467 self->ob_type->tp_free((PyObject *)self);
1470 static PyTypeObject PyXcType = {
1471 PyObject_HEAD_INIT(NULL)
1472 0,
1473 PKG "." CLS,
1474 sizeof(XcObject),
1475 0,
1476 (destructor)PyXc_dealloc, /* tp_dealloc */
1477 NULL, /* tp_print */
1478 PyXc_getattr, /* tp_getattr */
1479 NULL, /* tp_setattr */
1480 NULL, /* tp_compare */
1481 NULL, /* tp_repr */
1482 NULL, /* tp_as_number */
1483 NULL, /* tp_as_sequence */
1484 NULL, /* tp_as_mapping */
1485 NULL, /* tp_hash */
1486 NULL, /* tp_call */
1487 NULL, /* tp_str */
1488 NULL, /* tp_getattro */
1489 NULL, /* tp_setattro */
1490 NULL, /* tp_as_buffer */
1491 Py_TPFLAGS_DEFAULT, /* tp_flags */
1492 "Xen client connections", /* tp_doc */
1493 NULL, /* tp_traverse */
1494 NULL, /* tp_clear */
1495 NULL, /* tp_richcompare */
1496 0, /* tp_weaklistoffset */
1497 NULL, /* tp_iter */
1498 NULL, /* tp_iternext */
1499 pyxc_methods, /* tp_methods */
1500 NULL, /* tp_members */
1501 NULL, /* tp_getset */
1502 NULL, /* tp_base */
1503 NULL, /* tp_dict */
1504 NULL, /* tp_descr_get */
1505 NULL, /* tp_descr_set */
1506 0, /* tp_dictoffset */
1507 (initproc)PyXc_init, /* tp_init */
1508 NULL, /* tp_alloc */
1509 PyXc_new, /* tp_new */
1510 };
1512 static PyMethodDef xc_methods[] = { { NULL } };
1514 PyMODINIT_FUNC initxc(void)
1516 PyObject *m;
1518 if (PyType_Ready(&PyXcType) < 0)
1519 return;
1521 m = Py_InitModule(PKG, xc_methods);
1523 if (m == NULL)
1524 return;
1526 xc_error_obj = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
1527 zero = PyInt_FromLong(0);
1529 /* KAF: This ensures that we get debug output in a timely manner. */
1530 setbuf(stdout, NULL);
1531 setbuf(stderr, NULL);
1533 Py_INCREF(&PyXcType);
1534 PyModule_AddObject(m, CLS, (PyObject *)&PyXcType);
1536 Py_INCREF(xc_error_obj);
1537 PyModule_AddObject(m, "Error", xc_error_obj);
1539 /* Expose some libxc constants to Python */
1540 PyModule_AddIntConstant(m, "XEN_SCHEDULER_SEDF", XEN_SCHEDULER_SEDF);
1541 PyModule_AddIntConstant(m, "XEN_SCHEDULER_CREDIT", XEN_SCHEDULER_CREDIT);
1546 /*
1547 * Local variables:
1548 * c-indent-level: 4
1549 * c-basic-offset: 4
1550 * End:
1551 */