ia64/xen-unstable

view tools/python/xen/lowlevel/xc/xc.c @ 14173:40dc331c4423

Loop on actual elfnote array size rather than depending on ELFNOTE_MAX
macro.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Wed Feb 28 09:44:59 2007 +0000 (2007-02-28)
parents 270a5e2ead43
children f40b13ed0e05 265e257388b5
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 const *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 PyErr_SetObject(xc_error_obj, pyerr);
65 return NULL;
66 }
68 static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
69 {
70 uint32_t dom;
71 char *corefile;
73 if (!PyArg_ParseTuple(args, "is", &dom, &corefile))
74 return NULL;
76 if ( (corefile == NULL) || (corefile[0] == '\0') )
77 return NULL;
79 if (xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0)
80 return pyxc_error_to_exception();
82 Py_INCREF(zero);
83 return zero;
84 }
86 static PyObject *pyxc_handle(XcObject *self)
87 {
88 return PyInt_FromLong(self->xc_handle);
89 }
91 static PyObject *pyxc_domain_create(XcObject *self,
92 PyObject *args,
93 PyObject *kwds)
94 {
95 uint32_t dom = 0, ssidref = 0, flags = 0;
96 int ret, i, hvm = 0;
97 PyObject *pyhandle = NULL;
98 xen_domain_handle_t handle = {
99 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
100 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef };
102 static char *kwd_list[] = { "domid", "ssidref", "handle", "hvm", NULL };
104 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOi", kwd_list,
105 &dom, &ssidref, &pyhandle, &hvm))
106 return NULL;
108 if ( pyhandle != NULL )
109 {
110 if ( !PyList_Check(pyhandle) ||
111 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
112 goto out_exception;
114 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
115 {
116 PyObject *p = PyList_GetItem(pyhandle, i);
117 if ( !PyInt_Check(p) )
118 goto out_exception;
119 handle[i] = (uint8_t)PyInt_AsLong(p);
120 }
121 }
123 if ( hvm )
124 flags |= XEN_DOMCTL_CDF_hvm_guest;
126 if ( (ret = xc_domain_create(self->xc_handle, ssidref,
127 handle, flags, &dom)) < 0 )
128 return pyxc_error_to_exception();
130 return PyInt_FromLong(dom);
132 out_exception:
133 errno = EINVAL;
134 PyErr_SetFromErrno(xc_error_obj);
135 return NULL;
136 }
138 static PyObject *pyxc_domain_max_vcpus(XcObject *self, PyObject *args)
139 {
140 uint32_t dom, max;
142 if (!PyArg_ParseTuple(args, "ii", &dom, &max))
143 return NULL;
145 if (xc_domain_max_vcpus(self->xc_handle, dom, max) != 0)
146 return pyxc_error_to_exception();
148 Py_INCREF(zero);
149 return zero;
150 }
152 static PyObject *pyxc_domain_pause(XcObject *self, PyObject *args)
153 {
154 return dom_op(self, args, xc_domain_pause);
155 }
157 static PyObject *pyxc_domain_unpause(XcObject *self, PyObject *args)
158 {
159 return dom_op(self, args, xc_domain_unpause);
160 }
162 static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args)
163 {
164 return dom_op(self, args, xc_domain_destroy);
165 }
167 static PyObject *pyxc_domain_shutdown(XcObject *self, PyObject *args)
168 {
169 uint32_t dom, reason;
171 if (!PyArg_ParseTuple(args, "ii", &dom, &reason))
172 return NULL;
174 if (xc_domain_shutdown(self->xc_handle, dom, reason) != 0)
175 return pyxc_error_to_exception();
177 Py_INCREF(zero);
178 return zero;
179 }
181 static PyObject *pyxc_domain_resume(XcObject *self, PyObject *args)
182 {
183 uint32_t dom;
184 int fast;
186 if (!PyArg_ParseTuple(args, "ii", &dom, &fast))
187 return NULL;
189 if (xc_domain_resume(self->xc_handle, dom, fast) != 0)
190 return pyxc_error_to_exception();
192 Py_INCREF(zero);
193 return zero;
194 }
196 static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
197 PyObject *args,
198 PyObject *kwds)
199 {
200 uint32_t dom;
201 int vcpu = 0, i;
202 uint64_t cpumap = ~0ULL;
203 PyObject *cpulist = NULL;
205 static char *kwd_list[] = { "domid", "vcpu", "cpumap", NULL };
207 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|iO", kwd_list,
208 &dom, &vcpu, &cpulist) )
209 return NULL;
211 if ( (cpulist != NULL) && PyList_Check(cpulist) )
212 {
213 cpumap = 0ULL;
214 for ( i = 0; i < PyList_Size(cpulist); i++ )
215 cpumap |= (uint64_t)1 << PyInt_AsLong(PyList_GetItem(cpulist, i));
216 }
218 if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
219 return pyxc_error_to_exception();
221 Py_INCREF(zero);
222 return zero;
223 }
225 static PyObject *pyxc_domain_setcpuweight(XcObject *self,
226 PyObject *args,
227 PyObject *kwds)
228 {
229 uint32_t dom;
230 float cpuweight = 1;
232 static char *kwd_list[] = { "domid", "cpuweight", NULL };
234 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|f", kwd_list,
235 &dom, &cpuweight) )
236 return NULL;
238 if ( xc_domain_setcpuweight(self->xc_handle, dom, cpuweight) != 0 )
239 return pyxc_error_to_exception();
241 Py_INCREF(zero);
242 return zero;
243 }
245 static PyObject *pyxc_domain_sethandle(XcObject *self, PyObject *args)
246 {
247 int i;
248 uint32_t dom;
249 PyObject *pyhandle;
250 xen_domain_handle_t handle;
252 if (!PyArg_ParseTuple(args, "iO", &dom, &pyhandle))
253 return NULL;
255 if ( !PyList_Check(pyhandle) ||
256 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
257 {
258 goto out_exception;
259 }
261 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
262 {
263 PyObject *p = PyList_GetItem(pyhandle, i);
264 if ( !PyInt_Check(p) )
265 goto out_exception;
266 handle[i] = (uint8_t)PyInt_AsLong(p);
267 }
269 if (xc_domain_sethandle(self->xc_handle, dom, handle) < 0)
270 return pyxc_error_to_exception();
272 Py_INCREF(zero);
273 return zero;
275 out_exception:
276 PyErr_SetFromErrno(xc_error_obj);
277 return NULL;
278 }
281 static PyObject *pyxc_domain_getinfo(XcObject *self,
282 PyObject *args,
283 PyObject *kwds)
284 {
285 PyObject *list, *info_dict;
287 uint32_t first_dom = 0;
288 int max_doms = 1024, nr_doms, i, j;
289 xc_dominfo_t *info;
291 static char *kwd_list[] = { "first_dom", "max_doms", NULL };
293 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
294 &first_dom, &max_doms) )
295 return NULL;
297 if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL )
298 return PyErr_NoMemory();
300 nr_doms = xc_domain_getinfo(self->xc_handle, first_dom, max_doms, info);
302 if (nr_doms < 0)
303 {
304 free(info);
305 return pyxc_error_to_exception();
306 }
308 list = PyList_New(nr_doms);
309 for ( i = 0 ; i < nr_doms; i++ )
310 {
311 PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t));
312 for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
313 PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
314 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
315 ",s:l,s:L,s:l,s:i,s:i}",
316 "domid", info[i].domid,
317 "online_vcpus", info[i].nr_online_vcpus,
318 "max_vcpu_id", info[i].max_vcpu_id,
319 "hvm", info[i].hvm,
320 "dying", info[i].dying,
321 "crashed", info[i].crashed,
322 "shutdown", info[i].shutdown,
323 "paused", info[i].paused,
324 "blocked", info[i].blocked,
325 "running", info[i].running,
326 "mem_kb", info[i].nr_pages*(XC_PAGE_SIZE/1024),
327 "cpu_time", info[i].cpu_time,
328 "maxmem_kb", info[i].max_memkb,
329 "ssidref", info[i].ssidref,
330 "shutdown_reason", info[i].shutdown_reason);
331 PyDict_SetItemString(info_dict, "handle", pyhandle);
332 Py_DECREF(pyhandle);
333 PyList_SetItem(list, i, info_dict);
334 }
336 free(info);
338 return list;
339 }
341 static PyObject *pyxc_vcpu_getinfo(XcObject *self,
342 PyObject *args,
343 PyObject *kwds)
344 {
345 PyObject *info_dict, *cpulist;
347 uint32_t dom, vcpu = 0;
348 xc_vcpuinfo_t info;
349 int rc, i;
350 uint64_t cpumap;
352 static char *kwd_list[] = { "domid", "vcpu", NULL };
354 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
355 &dom, &vcpu) )
356 return NULL;
358 rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
359 if ( rc < 0 )
360 return pyxc_error_to_exception();
361 rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, &cpumap);
362 if ( rc < 0 )
363 return pyxc_error_to_exception();
365 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}",
366 "online", info.online,
367 "blocked", info.blocked,
368 "running", info.running,
369 "cpu_time", info.cpu_time,
370 "cpu", info.cpu);
372 cpulist = PyList_New(0);
373 for ( i = 0; cpumap != 0; i++ )
374 {
375 if ( cpumap & 1 )
376 PyList_Append(cpulist, PyInt_FromLong(i));
377 cpumap >>= 1;
378 }
379 PyDict_SetItemString(info_dict, "cpumap", cpulist);
380 Py_DECREF(cpulist);
381 return info_dict;
382 }
384 static PyObject *pyxc_linux_build(XcObject *self,
385 PyObject *args,
386 PyObject *kwds)
387 {
388 uint32_t domid;
389 struct xc_dom_image *dom;
390 char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
391 int flags = 0;
392 int store_evtchn, console_evtchn;
393 unsigned int mem_mb;
394 unsigned long store_mfn = 0;
395 unsigned long console_mfn = 0;
396 PyObject* elfnote_dict;
397 PyObject* elfnote = NULL;
398 int i;
400 static char *kwd_list[] = { "domid", "store_evtchn", "memsize",
401 "console_evtchn", "image",
402 /* optional */
403 "ramdisk", "cmdline", "flags",
404 "features", NULL };
406 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis", kwd_list,
407 &domid, &store_evtchn, &mem_mb,
408 &console_evtchn, &image,
409 /* optional */
410 &ramdisk, &cmdline, &flags,
411 &features) )
412 return NULL;
414 xc_dom_loginit();
415 if (!(dom = xc_dom_allocate(cmdline, features)))
416 return pyxc_error_to_exception();
418 if ( xc_dom_linux_build(self->xc_handle, dom, domid, mem_mb, image,
419 ramdisk, flags, store_evtchn, &store_mfn,
420 console_evtchn, &console_mfn) != 0 ) {
421 goto out;
422 }
424 if ( !(elfnote_dict = PyDict_New()) )
425 goto out;
427 for ( i = 0; i < ARRAY_SIZE(dom->parms.elf_notes); i++ )
428 {
429 switch ( dom->parms.elf_notes[i].type )
430 {
431 case XEN_ENT_NONE:
432 continue;
433 case XEN_ENT_LONG:
434 elfnote = Py_BuildValue("k", dom->parms.elf_notes[i].data.num);
435 break;
436 case XEN_ENT_STR:
437 elfnote = Py_BuildValue("s", dom->parms.elf_notes[i].data.str);
438 break;
439 }
440 PyDict_SetItemString(elfnote_dict,
441 dom->parms.elf_notes[i].name,
442 elfnote);
443 Py_DECREF(elfnote);
444 }
446 xc_dom_release(dom);
448 return Py_BuildValue("{s:i,s:i,s:N}",
449 "store_mfn", store_mfn,
450 "console_mfn", console_mfn,
451 "notes", elfnote_dict);
453 out:
454 xc_dom_release(dom);
455 return pyxc_error_to_exception();
456 }
458 static PyObject *pyxc_hvm_build(XcObject *self,
459 PyObject *args,
460 PyObject *kwds)
461 {
462 uint32_t dom;
463 #if !defined(__ia64__)
464 struct hvm_info_table *va_hvm;
465 uint8_t *va_map, sum;
466 int i;
467 #endif
468 char *image;
469 int store_evtchn, memsize, vcpus = 1, pae = 0, acpi = 0, apic = 1;
470 unsigned long store_mfn;
472 static char *kwd_list[] = { "domid", "store_evtchn",
473 "memsize", "image", "vcpus", "pae", "acpi",
474 "apic", NULL };
475 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|iiii", kwd_list,
476 &dom, &store_evtchn, &memsize,
477 &image, &vcpus, &pae, &acpi, &apic) )
478 return NULL;
480 if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
481 return pyxc_error_to_exception();
483 #if !defined(__ia64__)
484 /* Set up the HVM info table. */
485 va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
486 PROT_READ | PROT_WRITE,
487 HVM_INFO_PFN);
488 if ( va_map == NULL )
489 return PyErr_SetFromErrno(xc_error_obj);
490 va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
491 memset(va_hvm, 0, sizeof(*va_hvm));
492 strncpy(va_hvm->signature, "HVM INFO", 8);
493 va_hvm->length = sizeof(struct hvm_info_table);
494 va_hvm->acpi_enabled = acpi;
495 va_hvm->apic_mode = apic;
496 va_hvm->nr_vcpus = vcpus;
497 for ( i = 0, sum = 0; i < va_hvm->length; i++ )
498 sum += ((uint8_t *)va_hvm)[i];
499 va_hvm->checksum = -sum;
500 munmap(va_map, XC_PAGE_SIZE);
501 #endif
503 xc_get_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_PFN, &store_mfn);
504 #if !defined(__ia64__)
505 xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
506 #endif
507 xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_EVTCHN,
508 store_evtchn);
510 return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
511 }
513 static PyObject *pyxc_evtchn_alloc_unbound(XcObject *self,
514 PyObject *args,
515 PyObject *kwds)
516 {
517 uint32_t dom, remote_dom;
518 int port;
520 static char *kwd_list[] = { "domid", "remote_dom", NULL };
522 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
523 &dom, &remote_dom) )
524 return NULL;
526 if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) < 0 )
527 return pyxc_error_to_exception();
529 return PyInt_FromLong(port);
530 }
532 static PyObject *pyxc_evtchn_reset(XcObject *self,
533 PyObject *args,
534 PyObject *kwds)
535 {
536 uint32_t dom;
538 static char *kwd_list[] = { "dom", NULL };
540 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
541 return NULL;
543 if ( xc_evtchn_reset(self->xc_handle, dom) < 0 )
544 return pyxc_error_to_exception();
546 Py_INCREF(zero);
547 return zero;
548 }
550 static PyObject *pyxc_physdev_pci_access_modify(XcObject *self,
551 PyObject *args,
552 PyObject *kwds)
553 {
554 uint32_t dom;
555 int bus, dev, func, enable, ret;
557 static char *kwd_list[] = { "domid", "bus", "dev", "func", "enable", NULL };
559 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list,
560 &dom, &bus, &dev, &func, &enable) )
561 return NULL;
563 ret = xc_physdev_pci_access_modify(
564 self->xc_handle, dom, bus, dev, func, enable);
565 if ( ret != 0 )
566 return pyxc_error_to_exception();
568 Py_INCREF(zero);
569 return zero;
570 }
572 static PyObject *pyxc_readconsolering(XcObject *self,
573 PyObject *args,
574 PyObject *kwds)
575 {
576 unsigned int clear = 0;
577 char _str[32768], *str = _str;
578 unsigned int count = 32768;
579 int ret;
581 static char *kwd_list[] = { "clear", NULL };
583 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &clear) )
584 return NULL;
586 ret = xc_readconsolering(self->xc_handle, &str, &count, clear);
587 if ( ret < 0 )
588 return pyxc_error_to_exception();
590 return PyString_FromStringAndSize(str, count);
591 }
594 static unsigned long pages_to_kib(unsigned long pages)
595 {
596 return pages * (XC_PAGE_SIZE / 1024);
597 }
600 static PyObject *pyxc_pages_to_kib(XcObject *self, PyObject *args)
601 {
602 unsigned long pages;
604 if (!PyArg_ParseTuple(args, "l", &pages))
605 return NULL;
607 return PyLong_FromUnsignedLong(pages_to_kib(pages));
608 }
611 static PyObject *pyxc_physinfo(XcObject *self)
612 {
613 xc_physinfo_t info;
614 char cpu_cap[128], *p=cpu_cap, *q=cpu_cap;
615 int i;
617 if ( xc_physinfo(self->xc_handle, &info) != 0 )
618 return pyxc_error_to_exception();
620 *q=0;
621 for(i=0;i<sizeof(info.hw_cap)/4;i++)
622 {
623 p+=sprintf(p,"%08x:",info.hw_cap[i]);
624 if(info.hw_cap[i])
625 q=p;
626 }
627 if(q>cpu_cap)
628 *(q-1)=0;
630 return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s}",
631 "threads_per_core", info.threads_per_core,
632 "cores_per_socket", info.cores_per_socket,
633 "sockets_per_node", info.sockets_per_node,
634 "nr_nodes", info.nr_nodes,
635 "total_memory", pages_to_kib(info.total_pages),
636 "free_memory", pages_to_kib(info.free_pages),
637 "scrub_memory", pages_to_kib(info.scrub_pages),
638 "cpu_khz", info.cpu_khz,
639 "hw_caps", cpu_cap);
640 }
642 static PyObject *pyxc_xeninfo(XcObject *self)
643 {
644 xen_extraversion_t xen_extra;
645 xen_compile_info_t xen_cc;
646 xen_changeset_info_t xen_chgset;
647 xen_capabilities_info_t xen_caps;
648 xen_platform_parameters_t p_parms;
649 long xen_version;
650 long xen_pagesize;
651 char str[128];
653 xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
655 if ( xc_version(self->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
656 return pyxc_error_to_exception();
658 if ( xc_version(self->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
659 return pyxc_error_to_exception();
661 if ( xc_version(self->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
662 return pyxc_error_to_exception();
664 if ( xc_version(self->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
665 return pyxc_error_to_exception();
667 if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) != 0 )
668 return pyxc_error_to_exception();
670 sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
672 xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
673 if (xen_pagesize < 0 )
674 return pyxc_error_to_exception();
676 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}",
677 "xen_major", xen_version >> 16,
678 "xen_minor", (xen_version & 0xffff),
679 "xen_extra", xen_extra,
680 "xen_caps", xen_caps,
681 "xen_pagesize", xen_pagesize,
682 "platform_params", str,
683 "xen_changeset", xen_chgset,
684 "cc_compiler", xen_cc.compiler,
685 "cc_compile_by", xen_cc.compile_by,
686 "cc_compile_domain", xen_cc.compile_domain,
687 "cc_compile_date", xen_cc.compile_date);
688 }
691 static PyObject *pyxc_sedf_domain_set(XcObject *self,
692 PyObject *args,
693 PyObject *kwds)
694 {
695 uint32_t domid;
696 uint64_t period, slice, latency;
697 uint16_t extratime, weight;
698 static char *kwd_list[] = { "domid", "period", "slice",
699 "latency", "extratime", "weight",NULL };
701 if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLhh", kwd_list,
702 &domid, &period, &slice,
703 &latency, &extratime, &weight) )
704 return NULL;
705 if ( xc_sedf_domain_set(self->xc_handle, domid, period,
706 slice, latency, extratime,weight) != 0 )
707 return pyxc_error_to_exception();
709 Py_INCREF(zero);
710 return zero;
711 }
713 static PyObject *pyxc_sedf_domain_get(XcObject *self, PyObject *args)
714 {
715 uint32_t domid;
716 uint64_t period, slice,latency;
717 uint16_t weight, extratime;
719 if(!PyArg_ParseTuple(args, "i", &domid))
720 return NULL;
722 if (xc_sedf_domain_get(self->xc_handle, domid, &period,
723 &slice,&latency,&extratime,&weight))
724 return pyxc_error_to_exception();
726 return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
727 "domid", domid,
728 "period", period,
729 "slice", slice,
730 "latency", latency,
731 "extratime", extratime,
732 "weight", weight);
733 }
735 static PyObject *pyxc_shadow_control(PyObject *self,
736 PyObject *args,
737 PyObject *kwds)
738 {
739 XcObject *xc = (XcObject *)self;
741 uint32_t dom;
742 int op=0;
744 static char *kwd_list[] = { "dom", "op", NULL };
746 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
747 &dom, &op) )
748 return NULL;
750 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL, 0, NULL)
751 < 0 )
752 return pyxc_error_to_exception();
754 Py_INCREF(zero);
755 return zero;
756 }
758 static PyObject *pyxc_shadow_mem_control(PyObject *self,
759 PyObject *args,
760 PyObject *kwds)
761 {
762 XcObject *xc = (XcObject *)self;
763 int op;
764 uint32_t dom;
765 int mbarg = -1;
766 unsigned long mb;
768 static char *kwd_list[] = { "dom", "mb", NULL };
770 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
771 &dom, &mbarg) )
772 return NULL;
774 if ( mbarg < 0 )
775 op = XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION;
776 else
777 {
778 mb = mbarg;
779 op = XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION;
780 }
781 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, &mb, 0, NULL) < 0 )
782 return pyxc_error_to_exception();
784 mbarg = mb;
785 return Py_BuildValue("i", mbarg);
786 }
788 static PyObject *pyxc_sched_id_get(XcObject *self) {
790 int sched_id;
791 if (xc_sched_id(self->xc_handle, &sched_id) != 0)
792 return PyErr_SetFromErrno(xc_error_obj);
794 return Py_BuildValue("i", sched_id);
795 }
797 static PyObject *pyxc_sched_credit_domain_set(XcObject *self,
798 PyObject *args,
799 PyObject *kwds)
800 {
801 uint32_t domid;
802 uint16_t weight;
803 uint16_t cap;
804 static char *kwd_list[] = { "domid", "weight", "cap", NULL };
805 static char kwd_type[] = "I|HH";
806 struct xen_domctl_sched_credit sdom;
808 weight = 0;
809 cap = (uint16_t)~0U;
810 if( !PyArg_ParseTupleAndKeywords(args, kwds, kwd_type, kwd_list,
811 &domid, &weight, &cap) )
812 return NULL;
814 sdom.weight = weight;
815 sdom.cap = cap;
817 if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 )
818 return pyxc_error_to_exception();
820 Py_INCREF(zero);
821 return zero;
822 }
824 static PyObject *pyxc_sched_credit_domain_get(XcObject *self, PyObject *args)
825 {
826 uint32_t domid;
827 struct xen_domctl_sched_credit sdom;
829 if( !PyArg_ParseTuple(args, "I", &domid) )
830 return NULL;
832 if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 )
833 return pyxc_error_to_exception();
835 return Py_BuildValue("{s:H,s:H}",
836 "weight", sdom.weight,
837 "cap", sdom.cap);
838 }
840 static PyObject *pyxc_domain_setmaxmem(XcObject *self, PyObject *args)
841 {
842 uint32_t dom;
843 unsigned int maxmem_kb;
845 if (!PyArg_ParseTuple(args, "ii", &dom, &maxmem_kb))
846 return NULL;
848 if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0)
849 return pyxc_error_to_exception();
851 Py_INCREF(zero);
852 return zero;
853 }
855 static PyObject *pyxc_domain_set_memmap_limit(XcObject *self, PyObject *args)
856 {
857 uint32_t dom;
858 unsigned int maplimit_kb;
860 if ( !PyArg_ParseTuple(args, "ii", &dom, &maplimit_kb) )
861 return NULL;
863 if ( xc_domain_set_memmap_limit(self->xc_handle, dom, maplimit_kb) != 0 )
864 return pyxc_error_to_exception();
866 Py_INCREF(zero);
867 return zero;
868 }
870 static PyObject *pyxc_domain_memory_increase_reservation(XcObject *self,
871 PyObject *args,
872 PyObject *kwds)
873 {
874 uint32_t dom;
875 unsigned long mem_kb;
876 unsigned int extent_order = 0 , address_bits = 0;
877 unsigned long nr_extents;
879 static char *kwd_list[] = { "domid", "mem_kb", "extent_order", "address_bits", NULL };
881 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "il|ii", kwd_list,
882 &dom, &mem_kb, &extent_order, &address_bits) )
883 return NULL;
885 /* round down to nearest power of 2. Assume callers using extent_order>0
886 know what they are doing */
887 nr_extents = (mem_kb / (XC_PAGE_SIZE/1024)) >> extent_order;
888 if ( xc_domain_memory_increase_reservation(self->xc_handle, dom,
889 nr_extents, extent_order,
890 address_bits, NULL) )
891 return pyxc_error_to_exception();
893 Py_INCREF(zero);
894 return zero;
895 }
897 static PyObject *pyxc_domain_ioport_permission(XcObject *self,
898 PyObject *args,
899 PyObject *kwds)
900 {
901 uint32_t dom;
902 int first_port, nr_ports, allow_access, ret;
904 static char *kwd_list[] = { "domid", "first_port", "nr_ports", "allow_access", NULL };
906 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiii", kwd_list,
907 &dom, &first_port, &nr_ports, &allow_access) )
908 return NULL;
910 ret = xc_domain_ioport_permission(
911 self->xc_handle, dom, first_port, nr_ports, allow_access);
912 if ( ret != 0 )
913 return pyxc_error_to_exception();
915 Py_INCREF(zero);
916 return zero;
917 }
919 static PyObject *pyxc_domain_irq_permission(PyObject *self,
920 PyObject *args,
921 PyObject *kwds)
922 {
923 XcObject *xc = (XcObject *)self;
924 uint32_t dom;
925 int pirq, allow_access, ret;
927 static char *kwd_list[] = { "domid", "pirq", "allow_access", NULL };
929 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list,
930 &dom, &pirq, &allow_access) )
931 return NULL;
933 ret = xc_domain_irq_permission(
934 xc->xc_handle, dom, pirq, allow_access);
935 if ( ret != 0 )
936 return pyxc_error_to_exception();
938 Py_INCREF(zero);
939 return zero;
940 }
942 static PyObject *pyxc_domain_iomem_permission(PyObject *self,
943 PyObject *args,
944 PyObject *kwds)
945 {
946 XcObject *xc = (XcObject *)self;
947 uint32_t dom;
948 unsigned long first_pfn, nr_pfns, allow_access, ret;
950 static char *kwd_list[] = { "domid", "first_pfn", "nr_pfns", "allow_access", NULL };
952 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illi", kwd_list,
953 &dom, &first_pfn, &nr_pfns, &allow_access) )
954 return NULL;
956 ret = xc_domain_iomem_permission(
957 xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
958 if ( ret != 0 )
959 return pyxc_error_to_exception();
961 Py_INCREF(zero);
962 return zero;
963 }
965 static PyObject *pyxc_domain_set_time_offset(XcObject *self, PyObject *args)
966 {
967 uint32_t dom;
968 int32_t time_offset_seconds;
969 time_t calendar_time;
970 struct tm local_time;
971 struct tm utc_time;
973 if (!PyArg_ParseTuple(args, "i", &dom))
974 return NULL;
976 calendar_time = time(NULL);
977 localtime_r(&calendar_time, &local_time);
978 gmtime_r(&calendar_time, &utc_time);
979 /* set up to get calendar time based on utc_time, with local dst setting */
980 utc_time.tm_isdst = local_time.tm_isdst;
981 time_offset_seconds = (int32_t)difftime(calendar_time, mktime(&utc_time));
983 if (xc_domain_set_time_offset(self->xc_handle, dom, time_offset_seconds) != 0)
984 return NULL;
986 Py_INCREF(zero);
987 return zero;
988 }
990 static PyObject *pyxc_domain_send_trigger(XcObject *self,
991 PyObject *args,
992 PyObject *kwds)
993 {
994 uint32_t dom;
995 int trigger, vcpu = 0;
997 static char *kwd_list[] = { "domid", "trigger", "vcpu", NULL };
999 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii|i", kwd_list,
1000 &dom, &trigger, &vcpu) )
1001 return NULL;
1003 if (xc_domain_send_trigger(self->xc_handle, dom, trigger, vcpu) != 0)
1004 return pyxc_error_to_exception();
1006 Py_INCREF(zero);
1007 return zero;
1010 static PyObject *dom_op(XcObject *self, PyObject *args,
1011 int (*fn)(int, uint32_t))
1013 uint32_t dom;
1015 if (!PyArg_ParseTuple(args, "i", &dom))
1016 return NULL;
1018 if (fn(self->xc_handle, dom) != 0)
1019 return pyxc_error_to_exception();
1021 Py_INCREF(zero);
1022 return zero;
1025 #ifdef __powerpc__
1026 static PyObject *pyxc_alloc_real_mode_area(XcObject *self,
1027 PyObject *args,
1028 PyObject *kwds)
1030 uint32_t dom;
1031 unsigned int log;
1033 static char *kwd_list[] = { "dom", "log", NULL };
1035 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
1036 &dom, &log) )
1037 return NULL;
1039 if ( xc_alloc_real_mode_area(self->xc_handle, dom, log) )
1040 return pyxc_error_to_exception();
1042 Py_INCREF(zero);
1043 return zero;
1046 static PyObject *pyxc_prose_build(XcObject *self,
1047 PyObject *args,
1048 PyObject *kwds)
1050 uint32_t dom;
1051 char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
1052 int flags = 0;
1053 int store_evtchn, console_evtchn;
1054 unsigned int mem_mb;
1055 unsigned long store_mfn = 0;
1056 unsigned long console_mfn = 0;
1057 int unused;
1059 static char *kwd_list[] = { "dom", "store_evtchn",
1060 "console_evtchn", "image", "memsize",
1061 /* optional */
1062 "ramdisk", "cmdline", "flags",
1063 "features", NULL };
1065 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis#", kwd_list,
1066 &dom, &store_evtchn, &mem_mb,
1067 &console_evtchn, &image,
1068 /* optional */
1069 &ramdisk, &cmdline, &flags,
1070 &features, &unused) )
1071 return NULL;
1073 if ( xc_prose_build(self->xc_handle, dom, mem_mb, image,
1074 ramdisk, cmdline, features, flags,
1075 store_evtchn, &store_mfn,
1076 console_evtchn, &console_mfn) != 0 ) {
1077 if (!errno)
1078 errno = EINVAL;
1079 return pyxc_error_to_exception();
1081 return Py_BuildValue("{s:i,s:i}",
1082 "store_mfn", store_mfn,
1083 "console_mfn", console_mfn);
1085 #endif /* powerpc */
1087 static PyMethodDef pyxc_methods[] = {
1088 { "handle",
1089 (PyCFunction)pyxc_handle,
1090 METH_NOARGS, "\n"
1091 "Query the xc control interface file descriptor.\n\n"
1092 "Returns: [int] file descriptor\n" },
1094 { "domain_create",
1095 (PyCFunction)pyxc_domain_create,
1096 METH_VARARGS | METH_KEYWORDS, "\n"
1097 "Create a new domain.\n"
1098 " dom [int, 0]: Domain identifier to use (allocated if zero).\n"
1099 "Returns: [int] new domain identifier; -1 on error.\n" },
1101 { "domain_max_vcpus",
1102 (PyCFunction)pyxc_domain_max_vcpus,
1103 METH_VARARGS, "\n"
1104 "Set the maximum number of VCPUs a domain may create.\n"
1105 " dom [int, 0]: Domain identifier to use.\n"
1106 " max [int, 0]: New maximum number of VCPUs in domain.\n"
1107 "Returns: [int] 0 on success; -1 on error.\n" },
1109 { "domain_dumpcore",
1110 (PyCFunction)pyxc_domain_dumpcore,
1111 METH_VARARGS, "\n"
1112 "Dump core of a domain.\n"
1113 " dom [int]: Identifier of domain to dump core of.\n"
1114 " corefile [string]: Name of corefile to be created.\n\n"
1115 "Returns: [int] 0 on success; -1 on error.\n" },
1117 { "domain_pause",
1118 (PyCFunction)pyxc_domain_pause,
1119 METH_VARARGS, "\n"
1120 "Temporarily pause execution of a domain.\n"
1121 " dom [int]: Identifier of domain to be paused.\n\n"
1122 "Returns: [int] 0 on success; -1 on error.\n" },
1124 { "domain_unpause",
1125 (PyCFunction)pyxc_domain_unpause,
1126 METH_VARARGS, "\n"
1127 "(Re)start execution of a domain.\n"
1128 " dom [int]: Identifier of domain to be unpaused.\n\n"
1129 "Returns: [int] 0 on success; -1 on error.\n" },
1131 { "domain_destroy",
1132 (PyCFunction)pyxc_domain_destroy,
1133 METH_VARARGS, "\n"
1134 "Destroy a domain.\n"
1135 " dom [int]: Identifier of domain to be destroyed.\n\n"
1136 "Returns: [int] 0 on success; -1 on error.\n" },
1138 { "domain_resume",
1139 (PyCFunction)pyxc_domain_resume,
1140 METH_VARARGS, "\n"
1141 "Resume execution of a suspended domain.\n"
1142 " dom [int]: Identifier of domain to be resumed.\n"
1143 " fast [int]: Use cooperative resume.\n\n"
1144 "Returns: [int] 0 on success; -1 on error.\n" },
1146 { "domain_shutdown",
1147 (PyCFunction)pyxc_domain_shutdown,
1148 METH_VARARGS, "\n"
1149 "Shutdown a domain.\n"
1150 " dom [int, 0]: Domain identifier to use.\n"
1151 " reason [int, 0]: Reason for shutdown.\n"
1152 "Returns: [int] 0 on success; -1 on error.\n" },
1154 { "vcpu_setaffinity",
1155 (PyCFunction)pyxc_vcpu_setaffinity,
1156 METH_VARARGS | METH_KEYWORDS, "\n"
1157 "Pin a VCPU to a specified set CPUs.\n"
1158 " dom [int]: Identifier of domain to which VCPU belongs.\n"
1159 " vcpu [int, 0]: VCPU being pinned.\n"
1160 " cpumap [list, []]: list of usable CPUs.\n\n"
1161 "Returns: [int] 0 on success; -1 on error.\n" },
1163 { "domain_setcpuweight",
1164 (PyCFunction)pyxc_domain_setcpuweight,
1165 METH_VARARGS | METH_KEYWORDS, "\n"
1166 "Set cpuweight scheduler parameter for domain.\n"
1167 " dom [int]: Identifier of domain to be changed.\n"
1168 " cpuweight [float, 1]: VCPU being pinned.\n"
1169 "Returns: [int] 0 on success; -1 on error.\n" },
1171 { "domain_sethandle",
1172 (PyCFunction)pyxc_domain_sethandle,
1173 METH_VARARGS, "\n"
1174 "Set domain's opaque handle.\n"
1175 " dom [int]: Identifier of domain.\n"
1176 " handle [list of 16 ints]: New opaque handle.\n"
1177 "Returns: [int] 0 on success; -1 on error.\n" },
1179 { "domain_getinfo",
1180 (PyCFunction)pyxc_domain_getinfo,
1181 METH_VARARGS | METH_KEYWORDS, "\n"
1182 "Get information regarding a set of domains, in increasing id order.\n"
1183 " first_dom [int, 0]: First domain to retrieve info about.\n"
1184 " max_doms [int, 1024]: Maximum number of domains to retrieve info"
1185 " about.\n\n"
1186 "Returns: [list of dicts] if list length is less than 'max_doms'\n"
1187 " parameter then there was an error, or the end of the\n"
1188 " domain-id space was reached.\n"
1189 " dom [int]: Identifier of domain to which this info pertains\n"
1190 " cpu [int]: CPU to which this domain is bound\n"
1191 " vcpus [int]: Number of Virtual CPUS in this domain\n"
1192 " dying [int]: Bool - is the domain dying?\n"
1193 " crashed [int]: Bool - has the domain crashed?\n"
1194 " shutdown [int]: Bool - has the domain shut itself down?\n"
1195 " paused [int]: Bool - is the domain paused by control software?\n"
1196 " blocked [int]: Bool - is the domain blocked waiting for an event?\n"
1197 " running [int]: Bool - is the domain currently running?\n"
1198 " mem_kb [int]: Memory reservation, in kilobytes\n"
1199 " maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
1200 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1201 " shutdown_reason [int]: Numeric code from guest OS, explaining "
1202 "reason why it shut itself down.\n" },
1204 { "vcpu_getinfo",
1205 (PyCFunction)pyxc_vcpu_getinfo,
1206 METH_VARARGS | METH_KEYWORDS, "\n"
1207 "Get information regarding a VCPU.\n"
1208 " dom [int]: Domain to retrieve info about.\n"
1209 " vcpu [int, 0]: VCPU to retrieve info about.\n\n"
1210 "Returns: [dict]\n"
1211 " online [int]: Bool - Is this VCPU currently online?\n"
1212 " blocked [int]: Bool - Is this VCPU blocked waiting for an event?\n"
1213 " running [int]: Bool - Is this VCPU currently running on a CPU?\n"
1214 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1215 " cpumap [int]: Bitmap of CPUs this VCPU can run on\n"
1216 " cpu [int]: CPU that this VCPU is currently bound to\n" },
1218 { "linux_build",
1219 (PyCFunction)pyxc_linux_build,
1220 METH_VARARGS | METH_KEYWORDS, "\n"
1221 "Build a new Linux guest OS.\n"
1222 " dom [int]: Identifier of domain to build into.\n"
1223 " image [str]: Name of kernel image file. May be gzipped.\n"
1224 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
1225 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
1226 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1227 "Returns: [int] 0 on success; -1 on error.\n" },
1229 { "hvm_build",
1230 (PyCFunction)pyxc_hvm_build,
1231 METH_VARARGS | METH_KEYWORDS, "\n"
1232 "Build a new HVM guest OS.\n"
1233 " dom [int]: Identifier of domain to build into.\n"
1234 " image [str]: Name of HVM loader image file.\n"
1235 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1236 "Returns: [int] 0 on success; -1 on error.\n" },
1238 { "sched_id_get",
1239 (PyCFunction)pyxc_sched_id_get,
1240 METH_NOARGS, "\n"
1241 "Get the current scheduler type in use.\n"
1242 "Returns: [int] sched_id.\n" },
1244 { "sedf_domain_set",
1245 (PyCFunction)pyxc_sedf_domain_set,
1246 METH_KEYWORDS, "\n"
1247 "Set the scheduling parameters for a domain when running with Atropos.\n"
1248 " dom [int]: domain to set\n"
1249 " period [long]: domain's scheduling period\n"
1250 " slice [long]: domain's slice per period\n"
1251 " latency [long]: domain's wakeup latency hint\n"
1252 " extratime [int]: domain aware of extratime?\n"
1253 "Returns: [int] 0 on success; -1 on error.\n" },
1255 { "sedf_domain_get",
1256 (PyCFunction)pyxc_sedf_domain_get,
1257 METH_VARARGS, "\n"
1258 "Get the current scheduling parameters for a domain when running with\n"
1259 "the Atropos scheduler."
1260 " dom [int]: domain to query\n"
1261 "Returns: [dict]\n"
1262 " domain [int]: domain ID\n"
1263 " period [long]: scheduler period\n"
1264 " slice [long]: CPU reservation per period\n"
1265 " latency [long]: domain's wakeup latency hint\n"
1266 " extratime [int]: domain aware of extratime?\n"},
1268 { "sched_credit_domain_set",
1269 (PyCFunction)pyxc_sched_credit_domain_set,
1270 METH_KEYWORDS, "\n"
1271 "Set the scheduling parameters for a domain when running with the\n"
1272 "SMP credit scheduler.\n"
1273 " domid [int]: domain id to set\n"
1274 " weight [short]: domain's scheduling weight\n"
1275 "Returns: [int] 0 on success; -1 on error.\n" },
1277 { "sched_credit_domain_get",
1278 (PyCFunction)pyxc_sched_credit_domain_get,
1279 METH_VARARGS, "\n"
1280 "Get the scheduling parameters for a domain when running with the\n"
1281 "SMP credit scheduler.\n"
1282 " domid [int]: domain id to get\n"
1283 "Returns: [dict]\n"
1284 " weight [short]: domain's scheduling weight\n"},
1286 { "evtchn_alloc_unbound",
1287 (PyCFunction)pyxc_evtchn_alloc_unbound,
1288 METH_VARARGS | METH_KEYWORDS, "\n"
1289 "Allocate an unbound port that will await a remote connection.\n"
1290 " dom [int]: Domain whose port space to allocate from.\n"
1291 " remote_dom [int]: Remote domain to accept connections from.\n\n"
1292 "Returns: [int] Unbound event-channel port.\n" },
1294 { "evtchn_reset",
1295 (PyCFunction)pyxc_evtchn_reset,
1296 METH_VARARGS | METH_KEYWORDS, "\n"
1297 "Reset all connections.\n"
1298 " dom [int]: Domain to reset.\n" },
1300 { "physdev_pci_access_modify",
1301 (PyCFunction)pyxc_physdev_pci_access_modify,
1302 METH_VARARGS | METH_KEYWORDS, "\n"
1303 "Allow a domain access to a PCI device\n"
1304 " dom [int]: Identifier of domain to be allowed access.\n"
1305 " bus [int]: PCI bus\n"
1306 " dev [int]: PCI slot\n"
1307 " func [int]: PCI function\n"
1308 " enable [int]: Non-zero means enable access; else disable access\n\n"
1309 "Returns: [int] 0 on success; -1 on error.\n" },
1311 { "readconsolering",
1312 (PyCFunction)pyxc_readconsolering,
1313 METH_VARARGS | METH_KEYWORDS, "\n"
1314 "Read Xen's console ring.\n"
1315 " clear [int, 0]: Bool - clear the ring after reading from it?\n\n"
1316 "Returns: [str] string is empty on failure.\n" },
1318 { "physinfo",
1319 (PyCFunction)pyxc_physinfo,
1320 METH_NOARGS, "\n"
1321 "Get information about the physical host machine\n"
1322 "Returns [dict]: information about the hardware"
1323 " [None]: on failure.\n" },
1325 { "xeninfo",
1326 (PyCFunction)pyxc_xeninfo,
1327 METH_NOARGS, "\n"
1328 "Get information about the Xen host\n"
1329 "Returns [dict]: information about Xen"
1330 " [None]: on failure.\n" },
1332 { "shadow_control",
1333 (PyCFunction)pyxc_shadow_control,
1334 METH_VARARGS | METH_KEYWORDS, "\n"
1335 "Set parameter for shadow pagetable interface\n"
1336 " dom [int]: Identifier of domain.\n"
1337 " op [int, 0]: operation\n\n"
1338 "Returns: [int] 0 on success; -1 on error.\n" },
1340 { "shadow_mem_control",
1341 (PyCFunction)pyxc_shadow_mem_control,
1342 METH_VARARGS | METH_KEYWORDS, "\n"
1343 "Set or read shadow pagetable memory use\n"
1344 " dom [int]: Identifier of domain.\n"
1345 " mb [int, -1]: MB of shadow memory this domain should have.\n\n"
1346 "Returns: [int] MB of shadow memory in use by this domain.\n" },
1348 { "domain_setmaxmem",
1349 (PyCFunction)pyxc_domain_setmaxmem,
1350 METH_VARARGS, "\n"
1351 "Set a domain's memory limit\n"
1352 " dom [int]: Identifier of domain.\n"
1353 " maxmem_kb [int]: .\n"
1354 "Returns: [int] 0 on success; -1 on error.\n" },
1356 { "domain_set_memmap_limit",
1357 (PyCFunction)pyxc_domain_set_memmap_limit,
1358 METH_VARARGS, "\n"
1359 "Set a domain's physical memory mappping limit\n"
1360 " dom [int]: Identifier of domain.\n"
1361 " map_limitkb [int]: .\n"
1362 "Returns: [int] 0 on success; -1 on error.\n" },
1364 { "domain_memory_increase_reservation",
1365 (PyCFunction)pyxc_domain_memory_increase_reservation,
1366 METH_VARARGS | METH_KEYWORDS, "\n"
1367 "Increase a domain's memory reservation\n"
1368 " dom [int]: Identifier of domain.\n"
1369 " mem_kb [long]: .\n"
1370 "Returns: [int] 0 on success; -1 on error.\n" },
1372 { "domain_ioport_permission",
1373 (PyCFunction)pyxc_domain_ioport_permission,
1374 METH_VARARGS | METH_KEYWORDS, "\n"
1375 "Allow a domain access to a range of IO ports\n"
1376 " dom [int]: Identifier of domain to be allowed access.\n"
1377 " first_port [int]: First IO port\n"
1378 " nr_ports [int]: Number of IO ports\n"
1379 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1380 "Returns: [int] 0 on success; -1 on error.\n" },
1382 { "domain_irq_permission",
1383 (PyCFunction)pyxc_domain_irq_permission,
1384 METH_VARARGS | METH_KEYWORDS, "\n"
1385 "Allow a domain access to a physical IRQ\n"
1386 " dom [int]: Identifier of domain to be allowed access.\n"
1387 " pirq [int]: The Physical IRQ\n"
1388 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1389 "Returns: [int] 0 on success; -1 on error.\n" },
1391 { "domain_iomem_permission",
1392 (PyCFunction)pyxc_domain_iomem_permission,
1393 METH_VARARGS | METH_KEYWORDS, "\n"
1394 "Allow a domain access to a range of IO memory pages\n"
1395 " dom [int]: Identifier of domain to be allowed access.\n"
1396 " first_pfn [long]: First page of I/O Memory\n"
1397 " nr_pfns [long]: Number of pages of I/O Memory (>0)\n"
1398 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1399 "Returns: [int] 0 on success; -1 on error.\n" },
1401 { "pages_to_kib",
1402 (PyCFunction)pyxc_pages_to_kib,
1403 METH_VARARGS, "\n"
1404 "Returns: [int]: The size in KiB of memory spanning the given number "
1405 "of pages.\n" },
1407 { "domain_set_time_offset",
1408 (PyCFunction)pyxc_domain_set_time_offset,
1409 METH_VARARGS, "\n"
1410 "Set a domain's time offset to Dom0's localtime\n"
1411 " dom [int]: Domain whose time offset is being set.\n"
1412 "Returns: [int] 0 on success; -1 on error.\n" },
1414 { "domain_send_trigger",
1415 (PyCFunction)pyxc_domain_send_trigger,
1416 METH_VARARGS | METH_KEYWORDS, "\n"
1417 "Send trigger to a domain.\n"
1418 " dom [int]: Identifier of domain to be sent trigger.\n"
1419 " trigger [int]: Trigger type number.\n"
1420 " vcpu [int]: VCPU to be sent trigger.\n"
1421 "Returns: [int] 0 on success; -1 on error.\n" },
1423 #ifdef __powerpc__
1424 { "arch_alloc_real_mode_area",
1425 (PyCFunction)pyxc_alloc_real_mode_area,
1426 METH_VARARGS | METH_KEYWORDS, "\n"
1427 "Allocate a domain's real mode area.\n"
1428 " dom [int]: Identifier of domain.\n"
1429 " log [int]: Specifies the area's size.\n"
1430 "Returns: [int] 0 on success; -1 on error.\n" },
1432 { "arch_prose_build",
1433 (PyCFunction)pyxc_prose_build,
1434 METH_VARARGS | METH_KEYWORDS, "\n"
1435 "Build a new Linux guest OS.\n"
1436 " dom [int]: Identifier of domain to build into.\n"
1437 " image [str]: Name of kernel image file. May be gzipped.\n"
1438 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
1439 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
1440 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1441 "Returns: [int] 0 on success; -1 on error.\n" },
1442 #endif /* __powerpc */
1444 { NULL, NULL, 0, NULL }
1445 };
1448 static PyObject *PyXc_getattr(PyObject *obj, char *name)
1450 return Py_FindMethod(pyxc_methods, obj, name);
1453 static PyObject *PyXc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1455 XcObject *self = (XcObject *)type->tp_alloc(type, 0);
1457 if (self == NULL)
1458 return NULL;
1460 self->xc_handle = -1;
1462 return (PyObject *)self;
1465 static int
1466 PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
1468 if ((self->xc_handle = xc_interface_open()) == -1) {
1469 pyxc_error_to_exception();
1470 return -1;
1473 return 0;
1476 static void PyXc_dealloc(XcObject *self)
1478 if (self->xc_handle != -1) {
1479 xc_interface_close(self->xc_handle);
1480 self->xc_handle = -1;
1483 self->ob_type->tp_free((PyObject *)self);
1486 static PyTypeObject PyXcType = {
1487 PyObject_HEAD_INIT(NULL)
1488 0,
1489 PKG "." CLS,
1490 sizeof(XcObject),
1491 0,
1492 (destructor)PyXc_dealloc, /* tp_dealloc */
1493 NULL, /* tp_print */
1494 PyXc_getattr, /* tp_getattr */
1495 NULL, /* tp_setattr */
1496 NULL, /* tp_compare */
1497 NULL, /* tp_repr */
1498 NULL, /* tp_as_number */
1499 NULL, /* tp_as_sequence */
1500 NULL, /* tp_as_mapping */
1501 NULL, /* tp_hash */
1502 NULL, /* tp_call */
1503 NULL, /* tp_str */
1504 NULL, /* tp_getattro */
1505 NULL, /* tp_setattro */
1506 NULL, /* tp_as_buffer */
1507 Py_TPFLAGS_DEFAULT, /* tp_flags */
1508 "Xen client connections", /* tp_doc */
1509 NULL, /* tp_traverse */
1510 NULL, /* tp_clear */
1511 NULL, /* tp_richcompare */
1512 0, /* tp_weaklistoffset */
1513 NULL, /* tp_iter */
1514 NULL, /* tp_iternext */
1515 pyxc_methods, /* tp_methods */
1516 NULL, /* tp_members */
1517 NULL, /* tp_getset */
1518 NULL, /* tp_base */
1519 NULL, /* tp_dict */
1520 NULL, /* tp_descr_get */
1521 NULL, /* tp_descr_set */
1522 0, /* tp_dictoffset */
1523 (initproc)PyXc_init, /* tp_init */
1524 NULL, /* tp_alloc */
1525 PyXc_new, /* tp_new */
1526 };
1528 static PyMethodDef xc_methods[] = { { NULL } };
1530 PyMODINIT_FUNC initxc(void)
1532 PyObject *m;
1534 if (PyType_Ready(&PyXcType) < 0)
1535 return;
1537 m = Py_InitModule(PKG, xc_methods);
1539 if (m == NULL)
1540 return;
1542 xc_error_obj = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
1543 zero = PyInt_FromLong(0);
1545 /* KAF: This ensures that we get debug output in a timely manner. */
1546 setbuf(stdout, NULL);
1547 setbuf(stderr, NULL);
1549 Py_INCREF(&PyXcType);
1550 PyModule_AddObject(m, CLS, (PyObject *)&PyXcType);
1552 Py_INCREF(xc_error_obj);
1553 PyModule_AddObject(m, "Error", xc_error_obj);
1555 /* Expose some libxc constants to Python */
1556 PyModule_AddIntConstant(m, "XEN_SCHEDULER_SEDF", XEN_SCHEDULER_SEDF);
1557 PyModule_AddIntConstant(m, "XEN_SCHEDULER_CREDIT", XEN_SCHEDULER_CREDIT);
1562 /*
1563 * Local variables:
1564 * c-indent-level: 4
1565 * c-basic-offset: 4
1566 * End:
1567 */