direct-io.hg

view tools/python/xen/lowlevel/xc/xc.c @ 5695:0694fda4dbd5

python wrapper arg fix from aq.
author kaf24@firebug.cl.cam.ac.uk
date Fri Jul 08 08:02:45 2005 +0000 (2005-07-08)
parents 4b052d8a9a2f
children 579d1e771025
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 <xc.h>
9 #include <zlib.h>
10 #include <fcntl.h>
11 #include <netinet/in.h>
12 #include <netinet/tcp.h>
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <netdb.h>
16 #include <arpa/inet.h>
18 #include "xc_private.h"
19 #include "linux_boot_params.h"
21 /* Needed for Python versions earlier than 2.3. */
22 #ifndef PyMODINIT_FUNC
23 #define PyMODINIT_FUNC DL_EXPORT(void)
24 #endif
26 #define XENPKG "xen.lowlevel.xc"
28 static PyObject *xc_error, *zero;
30 typedef struct {
31 PyObject_HEAD;
32 int xc_handle;
33 } XcObject;
35 /*
36 * Definitions for the 'xc' object type.
37 */
39 static PyObject *pyxc_domain_dumpcore(PyObject *self,
40 PyObject *args,
41 PyObject *kwds)
42 {
43 XcObject *xc = (XcObject *)self;
45 u32 dom;
46 char *corefile;
48 static char *kwd_list[] = { "dom", "corefile", NULL };
50 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is", kwd_list,
51 &dom, &corefile) )
52 goto exit;
54 if ( (corefile == NULL) || (corefile[0] == '\0') )
55 goto exit;
57 if ( xc_domain_dumpcore(xc->xc_handle, dom, corefile) != 0 )
58 return PyErr_SetFromErrno(xc_error);
60 Py_INCREF(zero);
61 return zero;
63 exit:
64 return NULL;
65 }
67 static PyObject *pyxc_handle(PyObject *self)
68 {
69 XcObject *xc = (XcObject *)self;
71 return PyInt_FromLong(xc->xc_handle);
72 }
74 static PyObject *pyxc_domain_create(PyObject *self,
75 PyObject *args,
76 PyObject *kwds)
77 {
78 XcObject *xc = (XcObject *)self;
80 u32 dom = 0;
81 int ret;
82 u32 ssidref = 0x0;
84 static char *kwd_list[] = { "dom", "ssidref", NULL };
86 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
87 &dom, &ssidref))
88 return NULL;
90 if ( (ret = xc_domain_create(xc->xc_handle, ssidref, &dom)) < 0 )
91 return PyErr_SetFromErrno(xc_error);
93 return PyInt_FromLong(dom);
94 }
96 static PyObject *pyxc_domain_pause(PyObject *self,
97 PyObject *args,
98 PyObject *kwds)
99 {
100 XcObject *xc = (XcObject *)self;
102 u32 dom;
104 static char *kwd_list[] = { "dom", NULL };
106 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
107 return NULL;
109 if ( xc_domain_pause(xc->xc_handle, dom) != 0 )
110 return PyErr_SetFromErrno(xc_error);
112 Py_INCREF(zero);
113 return zero;
114 }
116 static PyObject *pyxc_domain_unpause(PyObject *self,
117 PyObject *args,
118 PyObject *kwds)
119 {
120 XcObject *xc = (XcObject *)self;
122 u32 dom;
124 static char *kwd_list[] = { "dom", NULL };
126 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
127 return NULL;
129 if ( xc_domain_unpause(xc->xc_handle, dom) != 0 )
130 return PyErr_SetFromErrno(xc_error);
132 Py_INCREF(zero);
133 return zero;
134 }
136 static PyObject *pyxc_domain_destroy(PyObject *self,
137 PyObject *args,
138 PyObject *kwds)
139 {
140 XcObject *xc = (XcObject *)self;
142 u32 dom;
144 static char *kwd_list[] = { "dom", NULL };
146 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
147 return NULL;
149 if ( xc_domain_destroy(xc->xc_handle, dom) != 0 )
150 return PyErr_SetFromErrno(xc_error);
152 Py_INCREF(zero);
153 return zero;
154 }
156 static PyObject *pyxc_domain_pincpu(PyObject *self,
157 PyObject *args,
158 PyObject *kwds)
159 {
160 XcObject *xc = (XcObject *)self;
162 u32 dom;
163 int vcpu = 0;
164 cpumap_t cpumap = 0xFFFFFFFF;
166 static char *kwd_list[] = { "dom", "vcpu", "cpumap", NULL };
168 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|ii", kwd_list,
169 &dom, &vcpu, &cpumap) )
170 return NULL;
172 if ( xc_domain_pincpu(xc->xc_handle, dom, vcpu, &cpumap) != 0 )
173 return PyErr_SetFromErrno(xc_error);
175 Py_INCREF(zero);
176 return zero;
177 }
179 static PyObject *pyxc_domain_setcpuweight(PyObject *self,
180 PyObject *args,
181 PyObject *kwds)
182 {
183 XcObject *xc = (XcObject *)self;
185 u32 dom;
186 float cpuweight = 1;
188 static char *kwd_list[] = { "dom", "cpuweight", NULL };
190 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|f", kwd_list,
191 &dom, &cpuweight) )
192 return NULL;
194 if ( xc_domain_setcpuweight(xc->xc_handle, dom, cpuweight) != 0 )
195 return PyErr_SetFromErrno(xc_error);
197 Py_INCREF(zero);
198 return zero;
199 }
201 static PyObject *pyxc_domain_getinfo(PyObject *self,
202 PyObject *args,
203 PyObject *kwds)
204 {
205 XcObject *xc = (XcObject *)self;
206 PyObject *list, *vcpu_list, *cpumap_list, *info_dict;
208 u32 first_dom = 0;
209 int max_doms = 1024, nr_doms, i, j;
210 xc_dominfo_t *info;
212 static char *kwd_list[] = { "first_dom", "max_doms", NULL };
214 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
215 &first_dom, &max_doms) )
216 return NULL;
218 if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL )
219 return PyErr_NoMemory();
221 nr_doms = xc_domain_getinfo(xc->xc_handle, first_dom, max_doms, info);
223 list = PyList_New(nr_doms);
224 for ( i = 0 ; i < nr_doms; i++ )
225 {
226 vcpu_list = PyList_New(MAX_VIRT_CPUS);
227 cpumap_list = PyList_New(MAX_VIRT_CPUS);
228 for ( j = 0; j < MAX_VIRT_CPUS; j++ ) {
229 PyList_SetItem( vcpu_list, j,
230 Py_BuildValue("i", info[i].vcpu_to_cpu[j]));
231 PyList_SetItem( cpumap_list, j,
232 Py_BuildValue("i", info[i].cpumap[j]));
233 }
235 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
236 ",s:l,s:L,s:l,s:i,s:i}",
237 "dom", info[i].domid,
238 "vcpus", info[i].vcpus,
239 "dying", info[i].dying,
240 "crashed", info[i].crashed,
241 "shutdown", info[i].shutdown,
242 "paused", info[i].paused,
243 "blocked", info[i].blocked,
244 "running", info[i].running,
245 "mem_kb", info[i].nr_pages*4,
246 "cpu_time", info[i].cpu_time,
247 "maxmem_kb", info[i].max_memkb,
248 "ssidref", info[i].ssidref,
249 "shutdown_reason", info[i].shutdown_reason);
250 PyDict_SetItemString( info_dict, "vcpu_to_cpu", vcpu_list );
251 PyDict_SetItemString( info_dict, "cpumap", cpumap_list );
252 PyList_SetItem( list, i, info_dict);
254 }
256 free(info);
258 return list;
259 }
261 static PyObject *pyxc_linux_build(PyObject *self,
262 PyObject *args,
263 PyObject *kwds)
264 {
265 XcObject *xc = (XcObject *)self;
267 u32 dom;
268 char *image, *ramdisk = NULL, *cmdline = "";
269 int flags = 0, vcpus = 1;
270 int control_evtchn, store_evtchn;
271 unsigned long store_mfn = 0;
273 static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn",
274 "image", "ramdisk", "cmdline", "flags",
275 "vcpus", NULL };
277 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssii", kwd_list,
278 &dom, &control_evtchn, &store_evtchn,
279 &image, &ramdisk, &cmdline, &flags,
280 &vcpus) )
281 return NULL;
283 if ( xc_linux_build(xc->xc_handle, dom, image,
284 ramdisk, cmdline, control_evtchn, flags, vcpus,
285 store_evtchn, &store_mfn) != 0 )
286 return PyErr_SetFromErrno(xc_error);
288 return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
289 }
291 static PyObject *pyxc_vmx_build(PyObject *self,
292 PyObject *args,
293 PyObject *kwds)
294 {
295 XcObject *xc = (XcObject *)self;
297 u32 dom;
298 char *image, *ramdisk = NULL, *cmdline = "";
299 PyObject *memmap;
300 int control_evtchn, flags = 0;
301 int numItems, i;
302 int memsize;
303 struct mem_map mem_map;
305 static char *kwd_list[] = { "dom", "control_evtchn",
306 "memsize",
307 "image", "memmap",
308 "ramdisk", "cmdline", "flags",
309 NULL };
311 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiisO!|ssi", kwd_list,
312 &dom, &control_evtchn,
313 &memsize,
314 &image, &PyList_Type, &memmap,
315 &ramdisk, &cmdline, &flags) )
316 return NULL;
318 memset(&mem_map, 0, sizeof(mem_map));
319 /* Parse memmap */
321 /* get the number of lines passed to us */
322 numItems = PyList_Size(memmap) - 1; /* removing the line
323 containing "memmap" */
324 printf ("numItems: %d\n", numItems);
325 mem_map.nr_map = numItems;
327 /* should raise an error here. */
328 if (numItems < 0) return NULL; /* Not a list */
330 /* iterate over items of the list, grabbing ranges and parsing them */
331 for (i = 1; i <= numItems; i++) { // skip over "memmap"
332 PyObject *item, *f1, *f2, *f3, *f4;
333 int numFields;
334 unsigned long lf1, lf2, lf3, lf4;
335 char *sf1, *sf2;
337 /* grab the string object from the next element of the list */
338 item = PyList_GetItem(memmap, i); /* Can't fail */
340 /* get the number of lines passed to us */
341 numFields = PyList_Size(item);
343 if (numFields != 4)
344 return NULL;
346 f1 = PyList_GetItem(item, 0);
347 f2 = PyList_GetItem(item, 1);
348 f3 = PyList_GetItem(item, 2);
349 f4 = PyList_GetItem(item, 3);
351 /* Convert objects to strings/longs */
352 sf1 = PyString_AsString(f1);
353 sf2 = PyString_AsString(f2);
354 lf3 = PyLong_AsLong(f3);
355 lf4 = PyLong_AsLong(f4);
356 if ( sscanf(sf1, "%lx", &lf1) != 1 )
357 return NULL;
358 if ( sscanf(sf2, "%lx", &lf2) != 1 )
359 return NULL;
361 mem_map.map[i-1].addr = lf1;
362 mem_map.map[i-1].size = lf2 - lf1;
363 mem_map.map[i-1].type = lf3;
364 mem_map.map[i-1].caching_attr = lf4;
365 }
367 if ( xc_vmx_build(xc->xc_handle, dom, memsize, image, &mem_map,
368 ramdisk, cmdline, control_evtchn, flags) != 0 )
369 return PyErr_SetFromErrno(xc_error);
371 Py_INCREF(zero);
372 return zero;
373 }
375 static PyObject *pyxc_bvtsched_global_set(PyObject *self,
376 PyObject *args,
377 PyObject *kwds)
378 {
379 XcObject *xc = (XcObject *)self;
381 unsigned long ctx_allow;
383 static char *kwd_list[] = { "ctx_allow", NULL };
385 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "l", kwd_list, &ctx_allow) )
386 return NULL;
388 if ( xc_bvtsched_global_set(xc->xc_handle, ctx_allow) != 0 )
389 return PyErr_SetFromErrno(xc_error);
391 Py_INCREF(zero);
392 return zero;
393 }
395 static PyObject *pyxc_bvtsched_global_get(PyObject *self,
396 PyObject *args,
397 PyObject *kwds)
398 {
399 XcObject *xc = (XcObject *)self;
401 unsigned long ctx_allow;
403 if ( !PyArg_ParseTuple(args, "") )
404 return NULL;
406 if ( xc_bvtsched_global_get(xc->xc_handle, &ctx_allow) != 0 )
407 return PyErr_SetFromErrno(xc_error);
409 return Py_BuildValue("s:l", "ctx_allow", ctx_allow);
410 }
412 static PyObject *pyxc_bvtsched_domain_set(PyObject *self,
413 PyObject *args,
414 PyObject *kwds)
415 {
416 XcObject *xc = (XcObject *)self;
418 u32 dom;
419 u32 mcuadv;
420 int warpback;
421 s32 warpvalue;
422 long long warpl;
423 long long warpu;
425 static char *kwd_list[] = { "dom", "mcuadv", "warpback", "warpvalue",
426 "warpl", "warpu", NULL };
428 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiiLL", kwd_list,
429 &dom, &mcuadv, &warpback, &warpvalue,
430 &warpl, &warpu) )
431 return NULL;
433 if ( xc_bvtsched_domain_set(xc->xc_handle, dom, mcuadv,
434 warpback, warpvalue, warpl, warpu) != 0 )
435 return PyErr_SetFromErrno(xc_error);
437 Py_INCREF(zero);
438 return zero;
439 }
441 static PyObject *pyxc_bvtsched_domain_get(PyObject *self,
442 PyObject *args,
443 PyObject *kwds)
444 {
445 XcObject *xc = (XcObject *)self;
446 u32 dom;
447 u32 mcuadv;
448 int warpback;
449 s32 warpvalue;
450 long long warpl;
451 long long warpu;
453 static char *kwd_list[] = { "dom", NULL };
455 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
456 return NULL;
458 if ( xc_bvtsched_domain_get(xc->xc_handle, dom, &mcuadv, &warpback,
459 &warpvalue, &warpl, &warpu) != 0 )
460 return PyErr_SetFromErrno(xc_error);
462 return Py_BuildValue("{s:i,s:l,s:l,s:l,s:l}",
463 "domain", dom,
464 "mcuadv", mcuadv,
465 "warpback", warpback,
466 "warpvalue", warpvalue,
467 "warpl", warpl,
468 "warpu", warpu);
469 }
471 static PyObject *pyxc_evtchn_alloc_unbound(PyObject *self,
472 PyObject *args,
473 PyObject *kwds)
474 {
475 XcObject *xc = (XcObject *)self;
477 u32 dom;
478 int port = 0;
480 static char *kwd_list[] = { "dom", "port", NULL };
482 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
483 &dom, &port) )
484 return NULL;
486 if ( xc_evtchn_alloc_unbound(xc->xc_handle, dom, &port) != 0 )
487 return PyErr_SetFromErrno(xc_error);
489 return PyInt_FromLong(port);
490 }
492 static PyObject *pyxc_evtchn_bind_interdomain(PyObject *self,
493 PyObject *args,
494 PyObject *kwds)
495 {
496 XcObject *xc = (XcObject *)self;
498 u32 dom1 = DOMID_SELF, dom2 = DOMID_SELF;
499 int port1 = 0, port2 = 0;
501 static char *kwd_list[] = { "dom1", "dom2", "port1", "port2", NULL };
503 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiii", kwd_list,
504 &dom1, &dom2, &port1, &port2) )
505 return NULL;
507 if ( xc_evtchn_bind_interdomain(xc->xc_handle, dom1,
508 dom2, &port1, &port2) != 0 )
509 return PyErr_SetFromErrno(xc_error);
511 return Py_BuildValue("{s:i,s:i}",
512 "port1", port1,
513 "port2", port2);
514 }
516 static PyObject *pyxc_evtchn_bind_virq(PyObject *self,
517 PyObject *args,
518 PyObject *kwds)
519 {
520 XcObject *xc = (XcObject *)self;
522 int virq, port;
524 static char *kwd_list[] = { "virq", NULL };
526 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &virq) )
527 return NULL;
529 if ( xc_evtchn_bind_virq(xc->xc_handle, virq, &port) != 0 )
530 return PyErr_SetFromErrno(xc_error);
532 return PyInt_FromLong(port);
533 }
535 static PyObject *pyxc_evtchn_close(PyObject *self,
536 PyObject *args,
537 PyObject *kwds)
538 {
539 XcObject *xc = (XcObject *)self;
541 u32 dom = DOMID_SELF;
542 int port;
544 static char *kwd_list[] = { "port", "dom", NULL };
546 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
547 &port, &dom) )
548 return NULL;
550 if ( xc_evtchn_close(xc->xc_handle, dom, port) != 0 )
551 return PyErr_SetFromErrno(xc_error);
553 Py_INCREF(zero);
554 return zero;
555 }
557 static PyObject *pyxc_evtchn_send(PyObject *self,
558 PyObject *args,
559 PyObject *kwds)
560 {
561 XcObject *xc = (XcObject *)self;
563 int port;
565 static char *kwd_list[] = { "port", NULL };
567 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &port) )
568 return NULL;
570 if ( xc_evtchn_send(xc->xc_handle, port) != 0 )
571 return PyErr_SetFromErrno(xc_error);
573 Py_INCREF(zero);
574 return zero;
575 }
577 static PyObject *pyxc_evtchn_status(PyObject *self,
578 PyObject *args,
579 PyObject *kwds)
580 {
581 XcObject *xc = (XcObject *)self;
582 PyObject *dict;
584 u32 dom = DOMID_SELF;
585 int port, ret;
586 xc_evtchn_status_t status;
588 static char *kwd_list[] = { "port", "dom", NULL };
590 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
591 &port, &dom) )
592 return NULL;
594 ret = xc_evtchn_status(xc->xc_handle, dom, port, &status);
595 if ( ret != 0 )
596 return PyErr_SetFromErrno(xc_error);
598 switch ( status.status )
599 {
600 case EVTCHNSTAT_closed:
601 dict = Py_BuildValue("{s:s}",
602 "status", "closed");
603 break;
604 case EVTCHNSTAT_unbound:
605 dict = Py_BuildValue("{s:s}",
606 "status", "unbound");
607 break;
608 case EVTCHNSTAT_interdomain:
609 dict = Py_BuildValue("{s:s,s:i,s:i}",
610 "status", "interdomain",
611 "dom", status.u.interdomain.dom,
612 "port", status.u.interdomain.port);
613 break;
614 case EVTCHNSTAT_pirq:
615 dict = Py_BuildValue("{s:s,s:i}",
616 "status", "pirq",
617 "irq", status.u.pirq);
618 break;
619 case EVTCHNSTAT_virq:
620 dict = Py_BuildValue("{s:s,s:i}",
621 "status", "virq",
622 "irq", status.u.virq);
623 break;
624 default:
625 dict = Py_BuildValue("{}");
626 break;
627 }
629 return dict;
630 }
632 static PyObject *pyxc_physdev_pci_access_modify(PyObject *self,
633 PyObject *args,
634 PyObject *kwds)
635 {
636 XcObject *xc = (XcObject *)self;
637 u32 dom;
638 int bus, dev, func, enable, ret;
640 static char *kwd_list[] = { "dom", "bus", "dev", "func", "enable", NULL };
642 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list,
643 &dom, &bus, &dev, &func, &enable) )
644 return NULL;
646 ret = xc_physdev_pci_access_modify(
647 xc->xc_handle, dom, bus, dev, func, enable);
648 if ( ret != 0 )
649 return PyErr_SetFromErrno(xc_error);
651 Py_INCREF(zero);
652 return zero;
653 }
655 static PyObject *pyxc_readconsolering(PyObject *self,
656 PyObject *args,
657 PyObject *kwds)
658 {
659 XcObject *xc = (XcObject *)self;
661 unsigned int clear = 0;
662 char _str[32768], *str = _str;
663 unsigned int count = 32768;
664 int ret;
666 static char *kwd_list[] = { "clear", NULL };
668 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &clear) )
669 return NULL;
671 ret = xc_readconsolering(xc->xc_handle, &str, &count, clear);
672 if ( ret < 0 )
673 return PyErr_SetFromErrno(xc_error);
675 return PyString_FromStringAndSize(str, count);
676 }
678 static PyObject *pyxc_physinfo(PyObject *self,
679 PyObject *args,
680 PyObject *kwds)
681 {
682 XcObject *xc = (XcObject *)self;
683 xc_physinfo_t info;
685 if ( !PyArg_ParseTuple(args, "") )
686 return NULL;
688 if ( xc_physinfo(xc->xc_handle, &info) != 0 )
689 return PyErr_SetFromErrno(xc_error);
691 return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:i}",
692 "threads_per_core", info.threads_per_core,
693 "cores_per_socket", info.cores_per_socket,
694 "sockets_per_node", info.sockets_per_node,
695 "nr_nodes", info.nr_nodes,
696 "total_pages", info.total_pages,
697 "free_pages", info.free_pages,
698 "cpu_khz", info.cpu_khz);
699 }
701 static PyObject *pyxc_sedf_domain_set(PyObject *self,
702 PyObject *args,
703 PyObject *kwds)
704 {
705 XcObject *xc = (XcObject *)self;
706 u32 domid;
707 u64 period, slice, latency;
708 u16 extratime, weight;
709 static char *kwd_list[] = { "dom", "period", "slice",
710 "latency", "extratime", "weight",NULL };
712 if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLhh", kwd_list,
713 &domid, &period, &slice,
714 &latency, &extratime, &weight) )
715 return NULL;
716 if ( xc_sedf_domain_set(xc->xc_handle, domid, period,
717 slice, latency, extratime,weight) != 0 )
718 return PyErr_SetFromErrno(xc_error);
720 Py_INCREF(zero);
721 return zero;
722 }
724 static PyObject *pyxc_sedf_domain_get(PyObject *self,
725 PyObject *args,
726 PyObject *kwds)
727 {
728 XcObject *xc = (XcObject *)self;
729 u32 domid;
730 u64 period, slice,latency;
731 u16 weight, extratime;
733 static char *kwd_list[] = { "dom", NULL };
735 if( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &domid) )
736 return NULL;
738 if ( xc_sedf_domain_get( xc->xc_handle, domid, &period,
739 &slice,&latency,&extratime,&weight) )
740 return PyErr_SetFromErrno(xc_error);
742 return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i}",
743 "domain", domid,
744 "period", period,
745 "slice", slice,
746 "latency", latency,
747 "extratime", extratime);
748 }
750 static PyObject *pyxc_shadow_control(PyObject *self,
751 PyObject *args,
752 PyObject *kwds)
753 {
754 XcObject *xc = (XcObject *)self;
756 u32 dom;
757 int op=0;
759 static char *kwd_list[] = { "dom", "op", NULL };
761 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
762 &dom, &op) )
763 return NULL;
765 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL) < 0 )
766 return PyErr_SetFromErrno(xc_error);
768 Py_INCREF(zero);
769 return zero;
770 }
772 static PyObject *pyxc_domain_setmaxmem(PyObject *self,
773 PyObject *args,
774 PyObject *kwds)
775 {
776 XcObject *xc = (XcObject *)self;
778 u32 dom;
779 unsigned long maxmem_kb;
781 static char *kwd_list[] = { "dom", "maxmem_kb", NULL };
783 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
784 &dom, &maxmem_kb) )
785 return NULL;
787 if ( xc_domain_setmaxmem(xc->xc_handle, dom, maxmem_kb) != 0 )
788 return PyErr_SetFromErrno(xc_error);
790 Py_INCREF(zero);
791 return zero;
792 }
794 static PyObject *pyxc_domain_memory_increase_reservation(PyObject *self,
795 PyObject *args,
796 PyObject *kwds)
797 {
798 XcObject *xc = (XcObject *)self;
800 u32 dom;
801 unsigned long mem_kb;
803 static char *kwd_list[] = { "dom", "mem_kb", NULL };
805 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
806 &dom, &mem_kb) )
807 return NULL;
809 if ( xc_domain_memory_increase_reservation(xc->xc_handle, dom, mem_kb) )
810 return PyErr_SetFromErrno(xc_error);
812 Py_INCREF(zero);
813 return zero;
814 }
817 static PyMethodDef pyxc_methods[] = {
818 { "handle",
819 (PyCFunction)pyxc_handle,
820 0, "\n"
821 "Query the xc control interface file descriptor.\n\n"
822 "Returns: [int] file descriptor\n" },
824 { "domain_create",
825 (PyCFunction)pyxc_domain_create,
826 METH_VARARGS | METH_KEYWORDS, "\n"
827 "Create a new domain.\n"
828 " dom [int, 0]: Domain identifier to use (allocated if zero).\n"
829 "Returns: [int] new domain identifier; -1 on error.\n" },
831 { "domain_dumpcore",
832 (PyCFunction)pyxc_domain_dumpcore,
833 METH_VARARGS | METH_KEYWORDS, "\n"
834 "Dump core of a domain.\n"
835 " dom [int]: Identifier of domain to dump core of.\n"
836 " corefile [string]: Name of corefile to be created.\n\n"
837 "Returns: [int] 0 on success; -1 on error.\n" },
839 { "domain_pause",
840 (PyCFunction)pyxc_domain_pause,
841 METH_VARARGS | METH_KEYWORDS, "\n"
842 "Temporarily pause execution of a domain.\n"
843 " dom [int]: Identifier of domain to be paused.\n\n"
844 "Returns: [int] 0 on success; -1 on error.\n" },
846 { "domain_unpause",
847 (PyCFunction)pyxc_domain_unpause,
848 METH_VARARGS | METH_KEYWORDS, "\n"
849 "(Re)start execution of a domain.\n"
850 " dom [int]: Identifier of domain to be unpaused.\n\n"
851 "Returns: [int] 0 on success; -1 on error.\n" },
853 { "domain_destroy",
854 (PyCFunction)pyxc_domain_destroy,
855 METH_VARARGS | METH_KEYWORDS, "\n"
856 "Destroy a domain.\n"
857 " dom [int]: Identifier of domain to be destroyed.\n\n"
858 "Returns: [int] 0 on success; -1 on error.\n" },
860 { "domain_pincpu",
861 (PyCFunction)pyxc_domain_pincpu,
862 METH_VARARGS | METH_KEYWORDS, "\n"
863 "Pin a VCPU to a specified set CPUs.\n"
864 " dom [int]: Identifier of domain to which VCPU belongs.\n"
865 " vcpu [int, 0]: VCPU being pinned.\n"
866 " cpumap [int, -1]: Bitmap of usable CPUs.\n\n"
867 "Returns: [int] 0 on success; -1 on error.\n" },
869 { "domain_setcpuweight",
870 (PyCFunction)pyxc_domain_setcpuweight,
871 METH_VARARGS | METH_KEYWORDS, "\n"
872 "Set cpuweight scheduler parameter for domain.\n"
873 " dom [int]: Identifier of domain to be changed.\n"
874 " cpuweight [float, 1]: VCPU being pinned.\n"
875 "Returns: [int] 0 on success; -1 on error.\n" },
877 { "domain_getinfo",
878 (PyCFunction)pyxc_domain_getinfo,
879 METH_VARARGS | METH_KEYWORDS, "\n"
880 "Get information regarding a set of domains, in increasing id order.\n"
881 " first_dom [int, 0]: First domain to retrieve info about.\n"
882 " max_doms [int, 1024]: Maximum number of domains to retrieve info"
883 " about.\n\n"
884 "Returns: [list of dicts] if list length is less than 'max_doms'\n"
885 " parameter then there was an error, or the end of the\n"
886 " domain-id space was reached.\n"
887 " dom [int]: Identifier of domain to which this info pertains\n"
888 " cpu [int]: CPU to which this domain is bound\n"
889 " vcpus [int]: Number of Virtual CPUS in this domain\n"
890 " dying [int]: Bool - is the domain dying?\n"
891 " crashed [int]: Bool - has the domain crashed?\n"
892 " shutdown [int]: Bool - has the domain shut itself down?\n"
893 " paused [int]: Bool - is the domain paused by control software?\n"
894 " blocked [int]: Bool - is the domain blocked waiting for an event?\n"
895 " running [int]: Bool - is the domain currently running?\n"
896 " mem_kb [int]: Memory reservation, in kilobytes\n"
897 " maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
898 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
899 " shutdown_reason [int]: Numeric code from guest OS, explaining "
900 "reason why it shut itself down.\n"
901 " vcpu_to_cpu [[int]]: List that maps VCPUS to CPUS\n" },
903 { "linux_build",
904 (PyCFunction)pyxc_linux_build,
905 METH_VARARGS | METH_KEYWORDS, "\n"
906 "Build a new Linux guest OS.\n"
907 " dom [int]: Identifier of domain to build into.\n"
908 " image [str]: Name of kernel image file. May be gzipped.\n"
909 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
910 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
911 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
912 "Returns: [int] 0 on success; -1 on error.\n" },
914 { "vmx_build",
915 (PyCFunction)pyxc_vmx_build,
916 METH_VARARGS | METH_KEYWORDS, "\n"
917 "Build a new Linux guest OS.\n"
918 " dom [int]: Identifier of domain to build into.\n"
919 " image [str]: Name of kernel image file. May be gzipped.\n"
920 " memmap [str]: Memory map.\n\n"
921 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
922 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
923 "Returns: [int] 0 on success; -1 on error.\n" },
925 { "bvtsched_global_set",
926 (PyCFunction)pyxc_bvtsched_global_set,
927 METH_VARARGS | METH_KEYWORDS, "\n"
928 "Set global tuning parameters for Borrowed Virtual Time scheduler.\n"
929 " ctx_allow [int]: Minimal guaranteed quantum.\n\n"
930 "Returns: [int] 0 on success; -1 on error.\n" },
932 { "bvtsched_global_get",
933 (PyCFunction)pyxc_bvtsched_global_get,
934 METH_KEYWORDS, "\n"
935 "Get global tuning parameters for BVT scheduler.\n"
936 "Returns: [dict]:\n"
937 " ctx_allow [int]: context switch allowance\n" },
939 { "bvtsched_domain_set",
940 (PyCFunction)pyxc_bvtsched_domain_set,
941 METH_VARARGS | METH_KEYWORDS, "\n"
942 "Set per-domain tuning parameters for Borrowed Virtual Time scheduler.\n"
943 " dom [int]: Identifier of domain to be tuned.\n"
944 " mcuadv [int]: Proportional to the inverse of the domain's weight.\n"
945 " warpback [int]: Warp ? \n"
946 " warpvalue [int]: How far to warp domain's EVT on unblock.\n"
947 " warpl [int]: How long the domain can run warped.\n"
948 " warpu [int]: How long before the domain can warp again.\n\n"
949 "Returns: [int] 0 on success; -1 on error.\n" },
951 { "bvtsched_domain_get",
952 (PyCFunction)pyxc_bvtsched_domain_get,
953 METH_KEYWORDS, "\n"
954 "Get per-domain tuning parameters under the BVT scheduler.\n"
955 " dom [int]: Identifier of domain to be queried.\n"
956 "Returns [dict]:\n"
957 " domain [int]: Domain ID.\n"
958 " mcuadv [long]: MCU Advance.\n"
959 " warp [long]: Warp.\n"
960 " warpu [long]: Unwarp requirement.\n"
961 " warpl [long]: Warp limit,\n"
962 },
964 { "sedf_domain_set",
965 (PyCFunction)pyxc_sedf_domain_set,
966 METH_KEYWORDS, "\n"
967 "Set the scheduling parameters for a domain when running with Atropos.\n"
968 " dom [int]: domain to set\n"
969 " period [long]: domain's scheduling period\n"
970 " slice [long]: domain's slice per period\n"
971 " latency [long]: domain's wakeup latency hint\n"
972 " extratime [int]: domain aware of extratime?\n"
973 "Returns: [int] 0 on success; -1 on error.\n" },
975 { "sedf_domain_get",
976 (PyCFunction)pyxc_sedf_domain_get,
977 METH_KEYWORDS, "\n"
978 "Get the current scheduling parameters for a domain when running with\n"
979 "the Atropos scheduler."
980 " dom [int]: domain to query\n"
981 "Returns: [dict]\n"
982 " domain [int]: domain ID\n"
983 " period [long]: scheduler period\n"
984 " slice [long]: CPU reservation per period\n"
985 " latency [long]: domain's wakeup latency hint\n"
986 " extratime [int]: domain aware of extratime?\n"},
988 { "evtchn_alloc_unbound",
989 (PyCFunction)pyxc_evtchn_alloc_unbound,
990 METH_VARARGS | METH_KEYWORDS, "\n"
991 "Allocate an unbound local port that will await a remote connection.\n"
992 " dom [int]: Remote domain to accept connections from.\n\n"
993 "Returns: [int] Unbound event-channel port.\n" },
995 { "evtchn_bind_interdomain",
996 (PyCFunction)pyxc_evtchn_bind_interdomain,
997 METH_VARARGS | METH_KEYWORDS, "\n"
998 "Open an event channel between two domains.\n"
999 " dom1 [int, SELF]: First domain to be connected.\n"
1000 " dom2 [int, SELF]: Second domain to be connected.\n\n"
1001 "Returns: [dict] dictionary is empty on failure.\n"
1002 " port1 [int]: Port-id for endpoint at dom1.\n"
1003 " port2 [int]: Port-id for endpoint at dom2.\n" },
1005 { "evtchn_bind_virq",
1006 (PyCFunction)pyxc_evtchn_bind_virq,
1007 METH_VARARGS | METH_KEYWORDS, "\n"
1008 "Bind an event channel to the specified VIRQ.\n"
1009 " virq [int]: VIRQ to bind.\n\n"
1010 "Returns: [int] Bound event-channel port.\n" },
1012 { "evtchn_close",
1013 (PyCFunction)pyxc_evtchn_close,
1014 METH_VARARGS | METH_KEYWORDS, "\n"
1015 "Close an event channel. If interdomain, sets remote end to 'unbound'.\n"
1016 " dom [int, SELF]: Dom-id of one endpoint of the channel.\n"
1017 " port [int]: Port-id of one endpoint of the channel.\n\n"
1018 "Returns: [int] 0 on success; -1 on error.\n" },
1020 { "evtchn_send",
1021 (PyCFunction)pyxc_evtchn_send,
1022 METH_VARARGS | METH_KEYWORDS, "\n"
1023 "Send an event along a locally-connected event channel.\n"
1024 " port [int]: Port-id of a local channel endpoint.\n\n"
1025 "Returns: [int] 0 on success; -1 on error.\n" },
1027 { "evtchn_status",
1028 (PyCFunction)pyxc_evtchn_status,
1029 METH_VARARGS | METH_KEYWORDS, "\n"
1030 "Query the status of an event channel.\n"
1031 " dom [int, SELF]: Dom-id of one endpoint of the channel.\n"
1032 " port [int]: Port-id of one endpoint of the channel.\n\n"
1033 "Returns: [dict] dictionary is empty on failure.\n"
1034 " status [str]: 'closed', 'unbound', 'interdomain', 'pirq',"
1035 " or 'virq'.\n"
1036 "The following are returned if 'status' is 'interdomain':\n"
1037 " dom [int]: Dom-id of remote endpoint.\n"
1038 " port [int]: Port-id of remote endpoint.\n"
1039 "The following are returned if 'status' is 'pirq' or 'virq':\n"
1040 " irq [int]: IRQ number.\n" },
1042 { "physdev_pci_access_modify",
1043 (PyCFunction)pyxc_physdev_pci_access_modify,
1044 METH_VARARGS | METH_KEYWORDS, "\n"
1045 "Allow a domain access to a PCI device\n"
1046 " dom [int]: Identifier of domain to be allowed access.\n"
1047 " bus [int]: PCI bus\n"
1048 " dev [int]: PCI slot\n"
1049 " func [int]: PCI function\n"
1050 " enable [int]: Non-zero means enable access; else disable access\n\n"
1051 "Returns: [int] 0 on success; -1 on error.\n" },
1053 { "readconsolering",
1054 (PyCFunction)pyxc_readconsolering,
1055 METH_VARARGS | METH_KEYWORDS, "\n"
1056 "Read Xen's console ring.\n"
1057 " clear [int, 0]: Bool - clear the ring after reading from it?\n\n"
1058 "Returns: [str] string is empty on failure.\n" },
1060 { "physinfo",
1061 (PyCFunction)pyxc_physinfo,
1062 METH_VARARGS, "\n"
1063 "Get information about the physical host machine\n"
1064 "Returns [dict]: information about the hardware"
1065 " [None]: on failure.\n" },
1067 { "shadow_control",
1068 (PyCFunction)pyxc_shadow_control,
1069 METH_VARARGS | METH_KEYWORDS, "\n"
1070 "Set parameter for shadow pagetable interface\n"
1071 " dom [int]: Identifier of domain.\n"
1072 " op [int, 0]: operation\n\n"
1073 "Returns: [int] 0 on success; -1 on error.\n" },
1075 { "domain_setmaxmem",
1076 (PyCFunction)pyxc_domain_setmaxmem,
1077 METH_VARARGS | METH_KEYWORDS, "\n"
1078 "Set a domain's memory limit\n"
1079 " dom [int]: Identifier of domain.\n"
1080 " maxmem_kb [long]: .\n"
1081 "Returns: [int] 0 on success; -1 on error.\n" },
1083 { "domain_memory_increase_reservation",
1084 (PyCFunction)pyxc_domain_memory_increase_reservation,
1085 METH_VARARGS | METH_KEYWORDS, "\n"
1086 "Increase a domain's memory reservation\n"
1087 " dom [int]: Identifier of domain.\n"
1088 " mem_kb [long]: .\n"
1089 "Returns: [int] 0 on success; -1 on error.\n" },
1091 { NULL, NULL, 0, NULL }
1092 };
1095 /*
1096 * Definitions for the 'Xc' module wrapper.
1097 */
1099 staticforward PyTypeObject PyXcType;
1101 static PyObject *PyXc_new(PyObject *self, PyObject *args)
1103 XcObject *xc;
1105 if ( !PyArg_ParseTuple(args, ":new") )
1106 return NULL;
1108 xc = PyObject_New(XcObject, &PyXcType);
1110 if ( (xc->xc_handle = xc_interface_open()) == -1 )
1112 PyObject_Del((PyObject *)xc);
1113 return PyErr_SetFromErrno(xc_error);
1116 return (PyObject *)xc;
1119 static PyObject *PyXc_getattr(PyObject *obj, char *name)
1121 return Py_FindMethod(pyxc_methods, obj, name);
1124 static void PyXc_dealloc(PyObject *self)
1126 XcObject *xc = (XcObject *)self;
1127 (void)xc_interface_close(xc->xc_handle);
1128 PyObject_Del(self);
1131 static PyTypeObject PyXcType = {
1132 PyObject_HEAD_INIT(&PyType_Type)
1133 0,
1134 "Xc",
1135 sizeof(XcObject),
1136 0,
1137 PyXc_dealloc, /* tp_dealloc */
1138 NULL, /* tp_print */
1139 PyXc_getattr, /* tp_getattr */
1140 NULL, /* tp_setattr */
1141 NULL, /* tp_compare */
1142 NULL, /* tp_repr */
1143 NULL, /* tp_as_number */
1144 NULL, /* tp_as_sequence */
1145 NULL, /* tp_as_mapping */
1146 NULL /* tp_hash */
1147 };
1149 static PyMethodDef PyXc_methods[] = {
1150 { "new", PyXc_new, METH_VARARGS, "Create a new " XENPKG " object." },
1151 { NULL, NULL, 0, NULL }
1152 };
1154 PyMODINIT_FUNC initxc(void)
1156 PyObject *m, *d;
1158 m = Py_InitModule(XENPKG, PyXc_methods);
1160 d = PyModule_GetDict(m);
1161 xc_error = PyErr_NewException(XENPKG ".error", NULL, NULL);
1162 PyDict_SetItemString(d, "error", xc_error);
1163 PyDict_SetItemString(d, "VIRQ_DOM_EXC", PyInt_FromLong(VIRQ_DOM_EXC));
1165 zero = PyInt_FromLong(0);
1167 /* KAF: This ensures that we get debug output in a timely manner. */
1168 setbuf(stdout, NULL);
1169 setbuf(stderr, NULL);