ia64/xen-unstable

view tools/python/xen/lowlevel/xc/xc.c @ 6435:b4b3f6be5226

merge?
author cl349@firebug.cl.cam.ac.uk
date Thu Aug 25 17:27:49 2005 +0000 (2005-08-25)
parents 0610add7c3fe fdfd511768a3
children 8799d14bef77 9312a3e8a6f8 112d44270733
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 <netdb.h>
17 #include <arpa/inet.h>
19 #include "xc_private.h"
20 #include "linux_boot_params.h"
22 /* Needed for Python versions earlier than 2.3. */
23 #ifndef PyMODINIT_FUNC
24 #define PyMODINIT_FUNC DL_EXPORT(void)
25 #endif
27 #define XENPKG "xen.lowlevel.xc"
29 static PyObject *xc_error, *zero;
31 typedef struct {
32 PyObject_HEAD;
33 int xc_handle;
34 } XcObject;
36 /*
37 * Definitions for the 'xc' object type.
38 */
40 static PyObject *pyxc_domain_dumpcore(PyObject *self,
41 PyObject *args,
42 PyObject *kwds)
43 {
44 XcObject *xc = (XcObject *)self;
46 u32 dom;
47 char *corefile;
49 static char *kwd_list[] = { "dom", "corefile", NULL };
51 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is", kwd_list,
52 &dom, &corefile) )
53 goto exit;
55 if ( (corefile == NULL) || (corefile[0] == '\0') )
56 goto exit;
58 if ( xc_domain_dumpcore(xc->xc_handle, dom, corefile) != 0 )
59 return PyErr_SetFromErrno(xc_error);
61 Py_INCREF(zero);
62 return zero;
64 exit:
65 return NULL;
66 }
68 static PyObject *pyxc_handle(PyObject *self)
69 {
70 XcObject *xc = (XcObject *)self;
72 return PyInt_FromLong(xc->xc_handle);
73 }
75 static PyObject *pyxc_domain_create(PyObject *self,
76 PyObject *args,
77 PyObject *kwds)
78 {
79 XcObject *xc = (XcObject *)self;
81 u32 dom = 0;
82 int ret;
83 u32 ssidref = 0x0;
85 static char *kwd_list[] = { "dom", "ssidref", NULL };
87 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
88 &dom, &ssidref))
89 return NULL;
91 if ( (ret = xc_domain_create(xc->xc_handle, ssidref, &dom)) < 0 )
92 return PyErr_SetFromErrno(xc_error);
94 return PyInt_FromLong(dom);
95 }
97 static PyObject *pyxc_domain_pause(PyObject *self,
98 PyObject *args,
99 PyObject *kwds)
100 {
101 XcObject *xc = (XcObject *)self;
103 u32 dom;
105 static char *kwd_list[] = { "dom", NULL };
107 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
108 return NULL;
110 if ( xc_domain_pause(xc->xc_handle, dom) != 0 )
111 return PyErr_SetFromErrno(xc_error);
113 Py_INCREF(zero);
114 return zero;
115 }
117 static PyObject *pyxc_domain_unpause(PyObject *self,
118 PyObject *args,
119 PyObject *kwds)
120 {
121 XcObject *xc = (XcObject *)self;
123 u32 dom;
125 static char *kwd_list[] = { "dom", NULL };
127 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
128 return NULL;
130 if ( xc_domain_unpause(xc->xc_handle, dom) != 0 )
131 return PyErr_SetFromErrno(xc_error);
133 Py_INCREF(zero);
134 return zero;
135 }
137 static PyObject *pyxc_domain_destroy(PyObject *self,
138 PyObject *args,
139 PyObject *kwds)
140 {
141 XcObject *xc = (XcObject *)self;
143 u32 dom;
145 static char *kwd_list[] = { "dom", NULL };
147 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
148 return NULL;
150 if ( xc_domain_destroy(xc->xc_handle, dom) != 0 )
151 return PyErr_SetFromErrno(xc_error);
153 Py_INCREF(zero);
154 return zero;
155 }
157 static PyObject *pyxc_domain_pincpu(PyObject *self,
158 PyObject *args,
159 PyObject *kwds)
160 {
161 XcObject *xc = (XcObject *)self;
163 u32 dom;
164 int vcpu = 0;
165 cpumap_t cpumap = 0xFFFFFFFF;
167 static char *kwd_list[] = { "dom", "vcpu", "cpumap", NULL };
169 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|ii", kwd_list,
170 &dom, &vcpu, &cpumap) )
171 return NULL;
173 if ( xc_domain_pincpu(xc->xc_handle, dom, vcpu, &cpumap) != 0 )
174 return PyErr_SetFromErrno(xc_error);
176 Py_INCREF(zero);
177 return zero;
178 }
180 static PyObject *pyxc_domain_setcpuweight(PyObject *self,
181 PyObject *args,
182 PyObject *kwds)
183 {
184 XcObject *xc = (XcObject *)self;
186 u32 dom;
187 float cpuweight = 1;
189 static char *kwd_list[] = { "dom", "cpuweight", NULL };
191 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|f", kwd_list,
192 &dom, &cpuweight) )
193 return NULL;
195 if ( xc_domain_setcpuweight(xc->xc_handle, dom, cpuweight) != 0 )
196 return PyErr_SetFromErrno(xc_error);
198 Py_INCREF(zero);
199 return zero;
200 }
202 static PyObject *pyxc_domain_getinfo(PyObject *self,
203 PyObject *args,
204 PyObject *kwds)
205 {
206 XcObject *xc = (XcObject *)self;
207 PyObject *list, *vcpu_list, *cpumap_list, *info_dict;
209 u32 first_dom = 0;
210 int max_doms = 1024, nr_doms, i, j;
211 xc_dominfo_t *info;
213 static char *kwd_list[] = { "first_dom", "max_doms", NULL };
215 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
216 &first_dom, &max_doms) )
217 return NULL;
219 if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL )
220 return PyErr_NoMemory();
222 nr_doms = xc_domain_getinfo(xc->xc_handle, first_dom, max_doms, info);
224 list = PyList_New(nr_doms);
225 for ( i = 0 ; i < nr_doms; i++ )
226 {
227 vcpu_list = PyList_New(MAX_VIRT_CPUS);
228 cpumap_list = PyList_New(MAX_VIRT_CPUS);
229 for ( j = 0; j < MAX_VIRT_CPUS; j++ ) {
230 PyList_SetItem( vcpu_list, j,
231 Py_BuildValue("i", info[i].vcpu_to_cpu[j]));
232 PyList_SetItem( cpumap_list, j,
233 Py_BuildValue("i", info[i].cpumap[j]));
234 }
236 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
237 ",s:l,s:L,s:l,s:i,s:i}",
238 "dom", info[i].domid,
239 "vcpus", info[i].vcpus,
240 "dying", info[i].dying,
241 "crashed", info[i].crashed,
242 "shutdown", info[i].shutdown,
243 "paused", info[i].paused,
244 "blocked", info[i].blocked,
245 "running", info[i].running,
246 "mem_kb", info[i].nr_pages*(XC_PAGE_SIZE/1024),
247 "cpu_time", info[i].cpu_time,
248 "maxmem_kb", info[i].max_memkb,
249 "ssidref", info[i].ssidref,
250 "shutdown_reason", info[i].shutdown_reason);
251 PyDict_SetItemString( info_dict, "vcpu_to_cpu", vcpu_list );
252 PyDict_SetItemString( info_dict, "cpumap", cpumap_list );
253 PyList_SetItem( list, i, info_dict);
255 }
257 free(info);
259 return list;
260 }
262 static PyObject *pyxc_linux_build(PyObject *self,
263 PyObject *args,
264 PyObject *kwds)
265 {
266 XcObject *xc = (XcObject *)self;
268 u32 dom;
269 char *image, *ramdisk = NULL, *cmdline = "";
270 int flags = 0, vcpus = 1;
271 int control_evtchn, store_evtchn;
272 unsigned long store_mfn = 0;
274 static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn",
275 "image", "ramdisk", "cmdline", "flags",
276 "vcpus", NULL };
278 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssii", kwd_list,
279 &dom, &control_evtchn, &store_evtchn,
280 &image, &ramdisk, &cmdline, &flags,
281 &vcpus) )
282 return NULL;
284 if ( xc_linux_build(xc->xc_handle, dom, image,
285 ramdisk, cmdline, control_evtchn, flags, vcpus,
286 store_evtchn, &store_mfn) != 0 )
287 return PyErr_SetFromErrno(xc_error);
289 return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
290 }
292 static PyObject *pyxc_vmx_build(PyObject *self,
293 PyObject *args,
294 PyObject *kwds)
295 {
296 XcObject *xc = (XcObject *)self;
298 u32 dom;
299 char *image, *ramdisk = NULL, *cmdline = "";
300 PyObject *memmap;
301 int control_evtchn, store_evtchn;
302 int flags = 0, vcpus = 1;
303 int numItems, i;
304 int memsize;
305 struct mem_map mem_map;
306 unsigned long store_mfn = 0;
308 static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn",
309 "memsize", "image", "memmap",
310 "ramdisk", "cmdline", "flags",
311 "vcpus", NULL };
313 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisO!|ssii", kwd_list,
314 &dom, &control_evtchn, &store_evtchn,
315 &memsize,
316 &image, &PyList_Type, &memmap,
317 &ramdisk, &cmdline, &flags, &vcpus) )
318 return NULL;
320 memset(&mem_map, 0, sizeof(mem_map));
321 /* Parse memmap */
323 /* get the number of lines passed to us */
324 numItems = PyList_Size(memmap) - 1; /* removing the line
325 containing "memmap" */
326 mem_map.nr_map = numItems;
328 /* should raise an error here. */
329 if (numItems < 0) return NULL; /* Not a list */
331 /* iterate over items of the list, grabbing ranges and parsing them */
332 for (i = 1; i <= numItems; i++) { // skip over "memmap"
333 PyObject *item, *f1, *f2, *f3, *f4;
334 int numFields;
335 unsigned long lf1, lf2, lf3, lf4;
336 char *sf1, *sf2;
338 /* grab the string object from the next element of the list */
339 item = PyList_GetItem(memmap, i); /* Can't fail */
341 /* get the number of lines passed to us */
342 numFields = PyList_Size(item);
344 if (numFields != 4)
345 return NULL;
347 f1 = PyList_GetItem(item, 0);
348 f2 = PyList_GetItem(item, 1);
349 f3 = PyList_GetItem(item, 2);
350 f4 = PyList_GetItem(item, 3);
352 /* Convert objects to strings/longs */
353 sf1 = PyString_AsString(f1);
354 sf2 = PyString_AsString(f2);
355 lf3 = PyLong_AsLong(f3);
356 lf4 = PyLong_AsLong(f4);
357 if ( sscanf(sf1, "%lx", &lf1) != 1 )
358 return NULL;
359 if ( sscanf(sf2, "%lx", &lf2) != 1 )
360 return NULL;
362 mem_map.map[i-1].addr = lf1;
363 mem_map.map[i-1].size = lf2 - lf1;
364 mem_map.map[i-1].type = lf3;
365 mem_map.map[i-1].caching_attr = lf4;
366 }
368 if ( xc_vmx_build(xc->xc_handle, dom, memsize, image, &mem_map,
369 ramdisk, cmdline, control_evtchn, flags,
370 vcpus, store_evtchn, &store_mfn) != 0 )
371 return PyErr_SetFromErrno(xc_error);
373 return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
374 }
376 static PyObject *pyxc_bvtsched_global_set(PyObject *self,
377 PyObject *args,
378 PyObject *kwds)
379 {
380 XcObject *xc = (XcObject *)self;
382 unsigned long ctx_allow;
384 static char *kwd_list[] = { "ctx_allow", NULL };
386 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "l", kwd_list, &ctx_allow) )
387 return NULL;
389 if ( xc_bvtsched_global_set(xc->xc_handle, ctx_allow) != 0 )
390 return PyErr_SetFromErrno(xc_error);
392 Py_INCREF(zero);
393 return zero;
394 }
396 static PyObject *pyxc_bvtsched_global_get(PyObject *self,
397 PyObject *args,
398 PyObject *kwds)
399 {
400 XcObject *xc = (XcObject *)self;
402 unsigned long ctx_allow;
404 if ( !PyArg_ParseTuple(args, "") )
405 return NULL;
407 if ( xc_bvtsched_global_get(xc->xc_handle, &ctx_allow) != 0 )
408 return PyErr_SetFromErrno(xc_error);
410 return Py_BuildValue("s:l", "ctx_allow", ctx_allow);
411 }
413 static PyObject *pyxc_bvtsched_domain_set(PyObject *self,
414 PyObject *args,
415 PyObject *kwds)
416 {
417 XcObject *xc = (XcObject *)self;
419 u32 dom;
420 u32 mcuadv;
421 int warpback;
422 s32 warpvalue;
423 long long warpl;
424 long long warpu;
426 static char *kwd_list[] = { "dom", "mcuadv", "warpback", "warpvalue",
427 "warpl", "warpu", NULL };
429 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiiLL", kwd_list,
430 &dom, &mcuadv, &warpback, &warpvalue,
431 &warpl, &warpu) )
432 return NULL;
434 if ( xc_bvtsched_domain_set(xc->xc_handle, dom, mcuadv,
435 warpback, warpvalue, warpl, warpu) != 0 )
436 return PyErr_SetFromErrno(xc_error);
438 Py_INCREF(zero);
439 return zero;
440 }
442 static PyObject *pyxc_bvtsched_domain_get(PyObject *self,
443 PyObject *args,
444 PyObject *kwds)
445 {
446 XcObject *xc = (XcObject *)self;
447 u32 dom;
448 u32 mcuadv;
449 int warpback;
450 s32 warpvalue;
451 long long warpl;
452 long long warpu;
454 static char *kwd_list[] = { "dom", NULL };
456 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
457 return NULL;
459 if ( xc_bvtsched_domain_get(xc->xc_handle, dom, &mcuadv, &warpback,
460 &warpvalue, &warpl, &warpu) != 0 )
461 return PyErr_SetFromErrno(xc_error);
463 return Py_BuildValue("{s:i,s:l,s:l,s:l,s:l}",
464 "domain", dom,
465 "mcuadv", mcuadv,
466 "warpback", warpback,
467 "warpvalue", warpvalue,
468 "warpl", warpl,
469 "warpu", warpu);
470 }
472 static PyObject *pyxc_evtchn_alloc_unbound(PyObject *self,
473 PyObject *args,
474 PyObject *kwds)
475 {
476 XcObject *xc = (XcObject *)self;
478 u32 dom;
479 int port = 0;
481 static char *kwd_list[] = { "dom", "port", NULL };
483 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
484 &dom, &port) )
485 return NULL;
487 if ( xc_evtchn_alloc_unbound(xc->xc_handle, dom, &port) != 0 )
488 return PyErr_SetFromErrno(xc_error);
490 return PyInt_FromLong(port);
491 }
493 static PyObject *pyxc_evtchn_bind_interdomain(PyObject *self,
494 PyObject *args,
495 PyObject *kwds)
496 {
497 XcObject *xc = (XcObject *)self;
499 u32 dom1 = DOMID_SELF, dom2 = DOMID_SELF;
500 int port1 = 0, port2 = 0;
502 static char *kwd_list[] = { "dom1", "dom2", "port1", "port2", NULL };
504 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiii", kwd_list,
505 &dom1, &dom2, &port1, &port2) )
506 return NULL;
508 if ( xc_evtchn_bind_interdomain(xc->xc_handle, dom1,
509 dom2, &port1, &port2) != 0 )
510 return PyErr_SetFromErrno(xc_error);
512 return Py_BuildValue("{s:i,s:i}",
513 "port1", port1,
514 "port2", port2);
515 }
517 static PyObject *pyxc_evtchn_bind_virq(PyObject *self,
518 PyObject *args,
519 PyObject *kwds)
520 {
521 XcObject *xc = (XcObject *)self;
523 int virq, port;
525 static char *kwd_list[] = { "virq", NULL };
527 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &virq) )
528 return NULL;
530 if ( xc_evtchn_bind_virq(xc->xc_handle, virq, &port) != 0 )
531 return PyErr_SetFromErrno(xc_error);
533 return PyInt_FromLong(port);
534 }
536 static PyObject *pyxc_evtchn_close(PyObject *self,
537 PyObject *args,
538 PyObject *kwds)
539 {
540 XcObject *xc = (XcObject *)self;
542 u32 dom = DOMID_SELF;
543 int port;
545 static char *kwd_list[] = { "port", "dom", NULL };
547 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
548 &port, &dom) )
549 return NULL;
551 if ( xc_evtchn_close(xc->xc_handle, dom, port) != 0 )
552 return PyErr_SetFromErrno(xc_error);
554 Py_INCREF(zero);
555 return zero;
556 }
558 static PyObject *pyxc_evtchn_send(PyObject *self,
559 PyObject *args,
560 PyObject *kwds)
561 {
562 XcObject *xc = (XcObject *)self;
564 int port;
566 static char *kwd_list[] = { "port", NULL };
568 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &port) )
569 return NULL;
571 if ( xc_evtchn_send(xc->xc_handle, port) != 0 )
572 return PyErr_SetFromErrno(xc_error);
574 Py_INCREF(zero);
575 return zero;
576 }
578 static PyObject *pyxc_evtchn_status(PyObject *self,
579 PyObject *args,
580 PyObject *kwds)
581 {
582 XcObject *xc = (XcObject *)self;
583 PyObject *dict;
585 u32 dom = DOMID_SELF;
586 int port, ret;
587 xc_evtchn_status_t status;
589 static char *kwd_list[] = { "port", "dom", NULL };
591 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
592 &port, &dom) )
593 return NULL;
595 ret = xc_evtchn_status(xc->xc_handle, dom, port, &status);
596 if ( ret != 0 )
597 return PyErr_SetFromErrno(xc_error);
599 switch ( status.status )
600 {
601 case EVTCHNSTAT_closed:
602 dict = Py_BuildValue("{s:s}",
603 "status", "closed");
604 break;
605 case EVTCHNSTAT_unbound:
606 dict = Py_BuildValue("{s:s}",
607 "status", "unbound");
608 break;
609 case EVTCHNSTAT_interdomain:
610 dict = Py_BuildValue("{s:s,s:i,s:i}",
611 "status", "interdomain",
612 "dom", status.u.interdomain.dom,
613 "port", status.u.interdomain.port);
614 break;
615 case EVTCHNSTAT_pirq:
616 dict = Py_BuildValue("{s:s,s:i}",
617 "status", "pirq",
618 "irq", status.u.pirq);
619 break;
620 case EVTCHNSTAT_virq:
621 dict = Py_BuildValue("{s:s,s:i}",
622 "status", "virq",
623 "irq", status.u.virq);
624 break;
625 default:
626 dict = Py_BuildValue("{}");
627 break;
628 }
630 return dict;
631 }
633 static PyObject *pyxc_physdev_pci_access_modify(PyObject *self,
634 PyObject *args,
635 PyObject *kwds)
636 {
637 XcObject *xc = (XcObject *)self;
638 u32 dom;
639 int bus, dev, func, enable, ret;
641 static char *kwd_list[] = { "dom", "bus", "dev", "func", "enable", NULL };
643 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list,
644 &dom, &bus, &dev, &func, &enable) )
645 return NULL;
647 ret = xc_physdev_pci_access_modify(
648 xc->xc_handle, dom, bus, dev, func, enable);
649 if ( ret != 0 )
650 return PyErr_SetFromErrno(xc_error);
652 Py_INCREF(zero);
653 return zero;
654 }
656 static PyObject *pyxc_readconsolering(PyObject *self,
657 PyObject *args,
658 PyObject *kwds)
659 {
660 XcObject *xc = (XcObject *)self;
662 unsigned int clear = 0;
663 char _str[32768], *str = _str;
664 unsigned int count = 32768;
665 int ret;
667 static char *kwd_list[] = { "clear", NULL };
669 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &clear) )
670 return NULL;
672 ret = xc_readconsolering(xc->xc_handle, &str, &count, clear);
673 if ( ret < 0 )
674 return PyErr_SetFromErrno(xc_error);
676 return PyString_FromStringAndSize(str, count);
677 }
679 static PyObject *pyxc_physinfo(PyObject *self,
680 PyObject *args,
681 PyObject *kwds)
682 {
683 XcObject *xc = (XcObject *)self;
684 xc_physinfo_t info;
686 if ( !PyArg_ParseTuple(args, "") )
687 return NULL;
689 if ( xc_physinfo(xc->xc_handle, &info) != 0 )
690 return PyErr_SetFromErrno(xc_error);
692 return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:i}",
693 "threads_per_core", info.threads_per_core,
694 "cores_per_socket", info.cores_per_socket,
695 "sockets_per_node", info.sockets_per_node,
696 "nr_nodes", info.nr_nodes,
697 "total_pages", info.total_pages,
698 "free_pages", info.free_pages,
699 "cpu_khz", info.cpu_khz);
700 }
702 static PyObject *pyxc_sedf_domain_set(PyObject *self,
703 PyObject *args,
704 PyObject *kwds)
705 {
706 XcObject *xc = (XcObject *)self;
707 u32 domid;
708 u64 period, slice, latency;
709 u16 extratime, weight;
710 static char *kwd_list[] = { "dom", "period", "slice",
711 "latency", "extratime", "weight",NULL };
713 if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLhh", kwd_list,
714 &domid, &period, &slice,
715 &latency, &extratime, &weight) )
716 return NULL;
717 if ( xc_sedf_domain_set(xc->xc_handle, domid, period,
718 slice, latency, extratime,weight) != 0 )
719 return PyErr_SetFromErrno(xc_error);
721 Py_INCREF(zero);
722 return zero;
723 }
725 static PyObject *pyxc_sedf_domain_get(PyObject *self,
726 PyObject *args,
727 PyObject *kwds)
728 {
729 XcObject *xc = (XcObject *)self;
730 u32 domid;
731 u64 period, slice,latency;
732 u16 weight, extratime;
734 static char *kwd_list[] = { "dom", NULL };
736 if( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &domid) )
737 return NULL;
739 if ( xc_sedf_domain_get( xc->xc_handle, domid, &period,
740 &slice,&latency,&extratime,&weight) )
741 return PyErr_SetFromErrno(xc_error);
743 return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i}",
744 "domain", domid,
745 "period", period,
746 "slice", slice,
747 "latency", latency,
748 "extratime", extratime);
749 }
751 static PyObject *pyxc_shadow_control(PyObject *self,
752 PyObject *args,
753 PyObject *kwds)
754 {
755 XcObject *xc = (XcObject *)self;
757 u32 dom;
758 int op=0;
760 static char *kwd_list[] = { "dom", "op", NULL };
762 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
763 &dom, &op) )
764 return NULL;
766 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL) < 0 )
767 return PyErr_SetFromErrno(xc_error);
769 Py_INCREF(zero);
770 return zero;
771 }
773 static PyObject *pyxc_domain_setmaxmem(PyObject *self,
774 PyObject *args,
775 PyObject *kwds)
776 {
777 XcObject *xc = (XcObject *)self;
779 u32 dom;
780 unsigned long maxmem_kb;
782 static char *kwd_list[] = { "dom", "maxmem_kb", NULL };
784 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
785 &dom, &maxmem_kb) )
786 return NULL;
788 if ( xc_domain_setmaxmem(xc->xc_handle, dom, maxmem_kb) != 0 )
789 return PyErr_SetFromErrno(xc_error);
791 Py_INCREF(zero);
792 return zero;
793 }
795 static PyObject *pyxc_domain_memory_increase_reservation(PyObject *self,
796 PyObject *args,
797 PyObject *kwds)
798 {
799 XcObject *xc = (XcObject *)self;
801 u32 dom;
802 unsigned long mem_kb;
804 static char *kwd_list[] = { "dom", "mem_kb", NULL };
806 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
807 &dom, &mem_kb) )
808 return NULL;
810 if ( xc_domain_memory_increase_reservation(xc->xc_handle, dom, mem_kb) )
811 return PyErr_SetFromErrno(xc_error);
813 Py_INCREF(zero);
814 return zero;
815 }
817 static PyObject *pyxc_init_store(PyObject *self, PyObject *args,
818 PyObject *kwds)
819 {
820 XcObject *xc = (XcObject *)self;
822 int remote_port;
824 static char *kwd_list[] = { "remote_port", NULL };
826 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list,
827 &remote_port) )
828 return NULL;
830 return PyInt_FromLong(xc_init_store(xc->xc_handle, remote_port));
831 }
834 static PyMethodDef pyxc_methods[] = {
835 { "handle",
836 (PyCFunction)pyxc_handle,
837 0, "\n"
838 "Query the xc control interface file descriptor.\n\n"
839 "Returns: [int] file descriptor\n" },
841 { "domain_create",
842 (PyCFunction)pyxc_domain_create,
843 METH_VARARGS | METH_KEYWORDS, "\n"
844 "Create a new domain.\n"
845 " dom [int, 0]: Domain identifier to use (allocated if zero).\n"
846 "Returns: [int] new domain identifier; -1 on error.\n" },
848 { "domain_dumpcore",
849 (PyCFunction)pyxc_domain_dumpcore,
850 METH_VARARGS | METH_KEYWORDS, "\n"
851 "Dump core of a domain.\n"
852 " dom [int]: Identifier of domain to dump core of.\n"
853 " corefile [string]: Name of corefile to be created.\n\n"
854 "Returns: [int] 0 on success; -1 on error.\n" },
856 { "domain_pause",
857 (PyCFunction)pyxc_domain_pause,
858 METH_VARARGS | METH_KEYWORDS, "\n"
859 "Temporarily pause execution of a domain.\n"
860 " dom [int]: Identifier of domain to be paused.\n\n"
861 "Returns: [int] 0 on success; -1 on error.\n" },
863 { "domain_unpause",
864 (PyCFunction)pyxc_domain_unpause,
865 METH_VARARGS | METH_KEYWORDS, "\n"
866 "(Re)start execution of a domain.\n"
867 " dom [int]: Identifier of domain to be unpaused.\n\n"
868 "Returns: [int] 0 on success; -1 on error.\n" },
870 { "domain_destroy",
871 (PyCFunction)pyxc_domain_destroy,
872 METH_VARARGS | METH_KEYWORDS, "\n"
873 "Destroy a domain.\n"
874 " dom [int]: Identifier of domain to be destroyed.\n\n"
875 "Returns: [int] 0 on success; -1 on error.\n" },
877 { "domain_pincpu",
878 (PyCFunction)pyxc_domain_pincpu,
879 METH_VARARGS | METH_KEYWORDS, "\n"
880 "Pin a VCPU to a specified set CPUs.\n"
881 " dom [int]: Identifier of domain to which VCPU belongs.\n"
882 " vcpu [int, 0]: VCPU being pinned.\n"
883 " cpumap [int, -1]: Bitmap of usable CPUs.\n\n"
884 "Returns: [int] 0 on success; -1 on error.\n" },
886 { "domain_setcpuweight",
887 (PyCFunction)pyxc_domain_setcpuweight,
888 METH_VARARGS | METH_KEYWORDS, "\n"
889 "Set cpuweight scheduler parameter for domain.\n"
890 " dom [int]: Identifier of domain to be changed.\n"
891 " cpuweight [float, 1]: VCPU being pinned.\n"
892 "Returns: [int] 0 on success; -1 on error.\n" },
894 { "domain_getinfo",
895 (PyCFunction)pyxc_domain_getinfo,
896 METH_VARARGS | METH_KEYWORDS, "\n"
897 "Get information regarding a set of domains, in increasing id order.\n"
898 " first_dom [int, 0]: First domain to retrieve info about.\n"
899 " max_doms [int, 1024]: Maximum number of domains to retrieve info"
900 " about.\n\n"
901 "Returns: [list of dicts] if list length is less than 'max_doms'\n"
902 " parameter then there was an error, or the end of the\n"
903 " domain-id space was reached.\n"
904 " dom [int]: Identifier of domain to which this info pertains\n"
905 " cpu [int]: CPU to which this domain is bound\n"
906 " vcpus [int]: Number of Virtual CPUS in this domain\n"
907 " dying [int]: Bool - is the domain dying?\n"
908 " crashed [int]: Bool - has the domain crashed?\n"
909 " shutdown [int]: Bool - has the domain shut itself down?\n"
910 " paused [int]: Bool - is the domain paused by control software?\n"
911 " blocked [int]: Bool - is the domain blocked waiting for an event?\n"
912 " running [int]: Bool - is the domain currently running?\n"
913 " mem_kb [int]: Memory reservation, in kilobytes\n"
914 " maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
915 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
916 " shutdown_reason [int]: Numeric code from guest OS, explaining "
917 "reason why it shut itself down.\n"
918 " vcpu_to_cpu [[int]]: List that maps VCPUS to CPUS\n" },
920 { "linux_build",
921 (PyCFunction)pyxc_linux_build,
922 METH_VARARGS | METH_KEYWORDS, "\n"
923 "Build a new Linux guest OS.\n"
924 " dom [int]: Identifier of domain to build into.\n"
925 " image [str]: Name of kernel image file. May be gzipped.\n"
926 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
927 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
928 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
929 "Returns: [int] 0 on success; -1 on error.\n" },
931 { "vmx_build",
932 (PyCFunction)pyxc_vmx_build,
933 METH_VARARGS | METH_KEYWORDS, "\n"
934 "Build a new Linux guest OS.\n"
935 " dom [int]: Identifier of domain to build into.\n"
936 " image [str]: Name of kernel image file. May be gzipped.\n"
937 " memmap [str]: Memory map.\n\n"
938 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
939 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
940 "Returns: [int] 0 on success; -1 on error.\n" },
942 { "bvtsched_global_set",
943 (PyCFunction)pyxc_bvtsched_global_set,
944 METH_VARARGS | METH_KEYWORDS, "\n"
945 "Set global tuning parameters for Borrowed Virtual Time scheduler.\n"
946 " ctx_allow [int]: Minimal guaranteed quantum.\n\n"
947 "Returns: [int] 0 on success; -1 on error.\n" },
949 { "bvtsched_global_get",
950 (PyCFunction)pyxc_bvtsched_global_get,
951 METH_KEYWORDS, "\n"
952 "Get global tuning parameters for BVT scheduler.\n"
953 "Returns: [dict]:\n"
954 " ctx_allow [int]: context switch allowance\n" },
956 { "bvtsched_domain_set",
957 (PyCFunction)pyxc_bvtsched_domain_set,
958 METH_VARARGS | METH_KEYWORDS, "\n"
959 "Set per-domain tuning parameters for Borrowed Virtual Time scheduler.\n"
960 " dom [int]: Identifier of domain to be tuned.\n"
961 " mcuadv [int]: Proportional to the inverse of the domain's weight.\n"
962 " warpback [int]: Warp ? \n"
963 " warpvalue [int]: How far to warp domain's EVT on unblock.\n"
964 " warpl [int]: How long the domain can run warped.\n"
965 " warpu [int]: How long before the domain can warp again.\n\n"
966 "Returns: [int] 0 on success; -1 on error.\n" },
968 { "bvtsched_domain_get",
969 (PyCFunction)pyxc_bvtsched_domain_get,
970 METH_KEYWORDS, "\n"
971 "Get per-domain tuning parameters under the BVT scheduler.\n"
972 " dom [int]: Identifier of domain to be queried.\n"
973 "Returns [dict]:\n"
974 " domain [int]: Domain ID.\n"
975 " mcuadv [long]: MCU Advance.\n"
976 " warp [long]: Warp.\n"
977 " warpu [long]: Unwarp requirement.\n"
978 " warpl [long]: Warp limit,\n"
979 },
981 { "sedf_domain_set",
982 (PyCFunction)pyxc_sedf_domain_set,
983 METH_KEYWORDS, "\n"
984 "Set the scheduling parameters for a domain when running with Atropos.\n"
985 " dom [int]: domain to set\n"
986 " period [long]: domain's scheduling period\n"
987 " slice [long]: domain's slice per period\n"
988 " latency [long]: domain's wakeup latency hint\n"
989 " extratime [int]: domain aware of extratime?\n"
990 "Returns: [int] 0 on success; -1 on error.\n" },
992 { "sedf_domain_get",
993 (PyCFunction)pyxc_sedf_domain_get,
994 METH_KEYWORDS, "\n"
995 "Get the current scheduling parameters for a domain when running with\n"
996 "the Atropos scheduler."
997 " dom [int]: domain to query\n"
998 "Returns: [dict]\n"
999 " domain [int]: domain ID\n"
1000 " period [long]: scheduler period\n"
1001 " slice [long]: CPU reservation per period\n"
1002 " latency [long]: domain's wakeup latency hint\n"
1003 " extratime [int]: domain aware of extratime?\n"},
1005 { "evtchn_alloc_unbound",
1006 (PyCFunction)pyxc_evtchn_alloc_unbound,
1007 METH_VARARGS | METH_KEYWORDS, "\n"
1008 "Allocate an unbound local port that will await a remote connection.\n"
1009 " dom [int]: Remote domain to accept connections from.\n\n"
1010 "Returns: [int] Unbound event-channel port.\n" },
1012 { "evtchn_bind_interdomain",
1013 (PyCFunction)pyxc_evtchn_bind_interdomain,
1014 METH_VARARGS | METH_KEYWORDS, "\n"
1015 "Open an event channel between two domains.\n"
1016 " dom1 [int, SELF]: First domain to be connected.\n"
1017 " dom2 [int, SELF]: Second domain to be connected.\n\n"
1018 "Returns: [dict] dictionary is empty on failure.\n"
1019 " port1 [int]: Port-id for endpoint at dom1.\n"
1020 " port2 [int]: Port-id for endpoint at dom2.\n" },
1022 { "evtchn_bind_virq",
1023 (PyCFunction)pyxc_evtchn_bind_virq,
1024 METH_VARARGS | METH_KEYWORDS, "\n"
1025 "Bind an event channel to the specified VIRQ.\n"
1026 " virq [int]: VIRQ to bind.\n\n"
1027 "Returns: [int] Bound event-channel port.\n" },
1029 { "evtchn_close",
1030 (PyCFunction)pyxc_evtchn_close,
1031 METH_VARARGS | METH_KEYWORDS, "\n"
1032 "Close an event channel. If interdomain, sets remote end to 'unbound'.\n"
1033 " dom [int, SELF]: Dom-id of one endpoint of the channel.\n"
1034 " port [int]: Port-id of one endpoint of the channel.\n\n"
1035 "Returns: [int] 0 on success; -1 on error.\n" },
1037 { "evtchn_send",
1038 (PyCFunction)pyxc_evtchn_send,
1039 METH_VARARGS | METH_KEYWORDS, "\n"
1040 "Send an event along a locally-connected event channel.\n"
1041 " port [int]: Port-id of a local channel endpoint.\n\n"
1042 "Returns: [int] 0 on success; -1 on error.\n" },
1044 { "evtchn_status",
1045 (PyCFunction)pyxc_evtchn_status,
1046 METH_VARARGS | METH_KEYWORDS, "\n"
1047 "Query the status of an event channel.\n"
1048 " dom [int, SELF]: Dom-id of one endpoint of the channel.\n"
1049 " port [int]: Port-id of one endpoint of the channel.\n\n"
1050 "Returns: [dict] dictionary is empty on failure.\n"
1051 " status [str]: 'closed', 'unbound', 'interdomain', 'pirq',"
1052 " or 'virq'.\n"
1053 "The following are returned if 'status' is 'interdomain':\n"
1054 " dom [int]: Dom-id of remote endpoint.\n"
1055 " port [int]: Port-id of remote endpoint.\n"
1056 "The following are returned if 'status' is 'pirq' or 'virq':\n"
1057 " irq [int]: IRQ number.\n" },
1059 { "physdev_pci_access_modify",
1060 (PyCFunction)pyxc_physdev_pci_access_modify,
1061 METH_VARARGS | METH_KEYWORDS, "\n"
1062 "Allow a domain access to a PCI device\n"
1063 " dom [int]: Identifier of domain to be allowed access.\n"
1064 " bus [int]: PCI bus\n"
1065 " dev [int]: PCI slot\n"
1066 " func [int]: PCI function\n"
1067 " enable [int]: Non-zero means enable access; else disable access\n\n"
1068 "Returns: [int] 0 on success; -1 on error.\n" },
1070 { "readconsolering",
1071 (PyCFunction)pyxc_readconsolering,
1072 METH_VARARGS | METH_KEYWORDS, "\n"
1073 "Read Xen's console ring.\n"
1074 " clear [int, 0]: Bool - clear the ring after reading from it?\n\n"
1075 "Returns: [str] string is empty on failure.\n" },
1077 { "physinfo",
1078 (PyCFunction)pyxc_physinfo,
1079 METH_VARARGS, "\n"
1080 "Get information about the physical host machine\n"
1081 "Returns [dict]: information about the hardware"
1082 " [None]: on failure.\n" },
1084 { "shadow_control",
1085 (PyCFunction)pyxc_shadow_control,
1086 METH_VARARGS | METH_KEYWORDS, "\n"
1087 "Set parameter for shadow pagetable interface\n"
1088 " dom [int]: Identifier of domain.\n"
1089 " op [int, 0]: operation\n\n"
1090 "Returns: [int] 0 on success; -1 on error.\n" },
1092 { "domain_setmaxmem",
1093 (PyCFunction)pyxc_domain_setmaxmem,
1094 METH_VARARGS | METH_KEYWORDS, "\n"
1095 "Set a domain's memory limit\n"
1096 " dom [int]: Identifier of domain.\n"
1097 " maxmem_kb [long]: .\n"
1098 "Returns: [int] 0 on success; -1 on error.\n" },
1100 { "domain_memory_increase_reservation",
1101 (PyCFunction)pyxc_domain_memory_increase_reservation,
1102 METH_VARARGS | METH_KEYWORDS, "\n"
1103 "Increase a domain's memory reservation\n"
1104 " dom [int]: Identifier of domain.\n"
1105 " mem_kb [long]: .\n"
1106 "Returns: [int] 0 on success; -1 on error.\n" },
1108 { "init_store",
1109 (PyCFunction)pyxc_init_store,
1110 METH_VARARGS | METH_KEYWORDS, "\n"
1111 "Initialize the store event channel and return the store page mfn.\n"
1112 " remote_port [int]: store event channel port number.\n"
1113 "Returns: [int] mfn on success; <0 on error.\n" },
1115 { NULL, NULL, 0, NULL }
1116 };
1119 /*
1120 * Definitions for the 'Xc' module wrapper.
1121 */
1123 staticforward PyTypeObject PyXcType;
1125 static PyObject *PyXc_new(PyObject *self, PyObject *args)
1127 XcObject *xc;
1129 if ( !PyArg_ParseTuple(args, ":new") )
1130 return NULL;
1132 xc = PyObject_New(XcObject, &PyXcType);
1134 if ( (xc->xc_handle = xc_interface_open()) == -1 )
1136 PyObject_Del((PyObject *)xc);
1137 return PyErr_SetFromErrno(xc_error);
1140 return (PyObject *)xc;
1143 static PyObject *PyXc_getattr(PyObject *obj, char *name)
1145 return Py_FindMethod(pyxc_methods, obj, name);
1148 static void PyXc_dealloc(PyObject *self)
1150 XcObject *xc = (XcObject *)self;
1151 (void)xc_interface_close(xc->xc_handle);
1152 PyObject_Del(self);
1155 static PyTypeObject PyXcType = {
1156 PyObject_HEAD_INIT(&PyType_Type)
1157 0,
1158 "Xc",
1159 sizeof(XcObject),
1160 0,
1161 PyXc_dealloc, /* tp_dealloc */
1162 NULL, /* tp_print */
1163 PyXc_getattr, /* tp_getattr */
1164 NULL, /* tp_setattr */
1165 NULL, /* tp_compare */
1166 NULL, /* tp_repr */
1167 NULL, /* tp_as_number */
1168 NULL, /* tp_as_sequence */
1169 NULL, /* tp_as_mapping */
1170 NULL /* tp_hash */
1171 };
1173 static PyMethodDef PyXc_methods[] = {
1174 { "new", PyXc_new, METH_VARARGS, "Create a new " XENPKG " object." },
1175 { NULL, NULL, 0, NULL }
1176 };
1178 PyMODINIT_FUNC initxc(void)
1180 PyObject *m, *d;
1182 m = Py_InitModule(XENPKG, PyXc_methods);
1184 d = PyModule_GetDict(m);
1185 xc_error = PyErr_NewException(XENPKG ".error", NULL, NULL);
1186 PyDict_SetItemString(d, "error", xc_error);
1187 PyDict_SetItemString(d, "VIRQ_DOM_EXC", PyInt_FromLong(VIRQ_DOM_EXC));
1189 zero = PyInt_FromLong(0);
1191 /* KAF: This ensures that we get debug output in a timely manner. */
1192 setbuf(stdout, NULL);
1193 setbuf(stderr, NULL);