ia64/xen-unstable

view tools/python/xen/lowlevel/xc/xc.c @ 7420:76a413a8eef0

There are only six fields in vcpuinfo.
Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Oct 18 10:53:30 2005 +0100 (2005-10-18)
parents 75ec60b67f64
children bd1298cf0b4d
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"
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 uint32_t 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 uint32_t dom = 0;
81 int ret, i;
82 uint32_t ssidref = 0;
83 PyObject *pyhandle = NULL;
84 xen_domain_handle_t handle = {
85 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
86 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef };
88 static char *kwd_list[] = { "dom", "ssidref", "handle", NULL };
90 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiO", kwd_list,
91 &dom, &ssidref, &pyhandle))
92 return NULL;
94 if ( pyhandle != NULL )
95 {
96 if ( !PyList_Check(pyhandle) ||
97 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
98 {
99 out_exception:
100 errno = EINVAL;
101 PyErr_SetFromErrno(xc_error);
102 return NULL;
103 }
105 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
106 {
107 PyObject *p = PyList_GetItem(pyhandle, i);
108 if ( !PyInt_Check(p) )
109 goto out_exception;
110 handle[i] = (uint8_t)PyInt_AsLong(p);
111 }
112 }
114 if ( (ret = xc_domain_create(xc->xc_handle, ssidref, handle, &dom)) < 0 )
115 return PyErr_SetFromErrno(xc_error);
117 return PyInt_FromLong(dom);
118 }
120 static PyObject *pyxc_domain_max_vcpus(PyObject *self,
121 PyObject *args,
122 PyObject *kwds)
123 {
124 XcObject *xc = (XcObject *)self;
126 uint32_t dom, max;
128 static char *kwd_list[] = { "dom", "max", NULL };
130 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, &dom, &max) )
131 return NULL;
133 if ( xc_domain_max_vcpus(xc->xc_handle, dom, max) != 0 )
134 return PyErr_SetFromErrno(xc_error);
136 Py_INCREF(zero);
137 return zero;
138 }
140 static PyObject *pyxc_domain_pause(PyObject *self,
141 PyObject *args,
142 PyObject *kwds)
143 {
144 XcObject *xc = (XcObject *)self;
146 uint32_t dom;
148 static char *kwd_list[] = { "dom", NULL };
150 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
151 return NULL;
153 if ( xc_domain_pause(xc->xc_handle, dom) != 0 )
154 return PyErr_SetFromErrno(xc_error);
156 Py_INCREF(zero);
157 return zero;
158 }
160 static PyObject *pyxc_domain_unpause(PyObject *self,
161 PyObject *args,
162 PyObject *kwds)
163 {
164 XcObject *xc = (XcObject *)self;
166 uint32_t dom;
168 static char *kwd_list[] = { "dom", NULL };
170 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
171 return NULL;
173 if ( xc_domain_unpause(xc->xc_handle, dom) != 0 )
174 return PyErr_SetFromErrno(xc_error);
176 Py_INCREF(zero);
177 return zero;
178 }
180 static PyObject *pyxc_domain_destroy(PyObject *self,
181 PyObject *args,
182 PyObject *kwds)
183 {
184 XcObject *xc = (XcObject *)self;
186 uint32_t dom;
188 static char *kwd_list[] = { "dom", NULL };
190 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
191 return NULL;
193 if ( xc_domain_destroy(xc->xc_handle, dom) != 0 )
194 return PyErr_SetFromErrno(xc_error);
196 Py_INCREF(zero);
197 return zero;
198 }
200 static PyObject *pyxc_domain_pincpu(PyObject *self,
201 PyObject *args,
202 PyObject *kwds)
203 {
204 XcObject *xc = (XcObject *)self;
206 uint32_t dom;
207 int vcpu = 0;
208 cpumap_t cpumap = ~0ULL;
210 static char *kwd_list[] = { "dom", "vcpu", "cpumap", NULL };
212 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|ii", kwd_list,
213 &dom, &vcpu, &cpumap) )
214 return NULL;
216 if ( xc_domain_pincpu(xc->xc_handle, dom, vcpu, cpumap) != 0 )
217 return PyErr_SetFromErrno(xc_error);
219 Py_INCREF(zero);
220 return zero;
221 }
223 static PyObject *pyxc_domain_setcpuweight(PyObject *self,
224 PyObject *args,
225 PyObject *kwds)
226 {
227 XcObject *xc = (XcObject *)self;
229 uint32_t dom;
230 float cpuweight = 1;
232 static char *kwd_list[] = { "dom", "cpuweight", NULL };
234 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|f", kwd_list,
235 &dom, &cpuweight) )
236 return NULL;
238 if ( xc_domain_setcpuweight(xc->xc_handle, dom, cpuweight) != 0 )
239 return PyErr_SetFromErrno(xc_error);
241 Py_INCREF(zero);
242 return zero;
243 }
245 static PyObject *pyxc_domain_sethandle(PyObject *self,
246 PyObject *args,
247 PyObject *kwds)
248 {
249 XcObject *xc = (XcObject *)self;
251 int i;
252 uint32_t dom;
253 PyObject *pyhandle;
254 xen_domain_handle_t handle;
256 static char *kwd_list[] = { "dom", "handle", NULL };
258 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iO", kwd_list,
259 &dom, &pyhandle) )
260 return NULL;
262 if ( !PyList_Check(pyhandle) ||
263 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
264 {
265 out_exception:
266 errno = EINVAL;
267 PyErr_SetFromErrno(xc_error);
268 return NULL;
269 }
271 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
272 {
273 PyObject *p = PyList_GetItem(pyhandle, i);
274 if ( !PyInt_Check(p) )
275 goto out_exception;
276 handle[i] = (uint8_t)PyInt_AsLong(p);
277 }
279 if ( xc_domain_sethandle(xc->xc_handle, dom, handle) < 0 )
280 return PyErr_SetFromErrno(xc_error);
282 Py_INCREF(zero);
283 return zero;
284 }
286 static PyObject *pyxc_domain_getinfo(PyObject *self,
287 PyObject *args,
288 PyObject *kwds)
289 {
290 XcObject *xc = (XcObject *)self;
291 PyObject *list, *info_dict;
293 uint32_t first_dom = 0;
294 int max_doms = 1024, nr_doms, i, j;
295 xc_dominfo_t *info;
297 static char *kwd_list[] = { "first_dom", "max_doms", NULL };
299 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
300 &first_dom, &max_doms) )
301 return NULL;
303 if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL )
304 return PyErr_NoMemory();
306 nr_doms = xc_domain_getinfo(xc->xc_handle, first_dom, max_doms, info);
308 if (nr_doms < 0)
309 {
310 free(info);
311 return PyErr_SetFromErrno(xc_error);
312 }
314 list = PyList_New(nr_doms);
315 for ( i = 0 ; i < nr_doms; i++ )
316 {
317 PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t));
318 for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
319 PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
320 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
321 ",s:l,s:L,s:l,s:i,s:i}",
322 "dom", info[i].domid,
323 "online_vcpus", info[i].nr_online_vcpus,
324 "max_vcpu_id", info[i].max_vcpu_id,
325 "dying", info[i].dying,
326 "crashed", info[i].crashed,
327 "shutdown", info[i].shutdown,
328 "paused", info[i].paused,
329 "blocked", info[i].blocked,
330 "running", info[i].running,
331 "mem_kb", info[i].nr_pages*(XC_PAGE_SIZE/1024),
332 "cpu_time", info[i].cpu_time,
333 "maxmem_kb", info[i].max_memkb,
334 "ssidref", info[i].ssidref,
335 "shutdown_reason", info[i].shutdown_reason);
336 PyDict_SetItemString(info_dict, "handle", pyhandle);
337 PyList_SetItem(list, i, info_dict);
338 }
340 free(info);
342 return list;
343 }
345 static PyObject *pyxc_vcpu_getinfo(PyObject *self,
346 PyObject *args,
347 PyObject *kwds)
348 {
349 XcObject *xc = (XcObject *)self;
350 PyObject *info_dict;
352 uint32_t dom, vcpu = 0;
353 xc_vcpuinfo_t info;
354 int rc;
356 static char *kwd_list[] = { "dom", "vcpu", NULL };
358 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
359 &dom, &vcpu) )
360 return NULL;
362 rc = xc_domain_get_vcpu_info(xc->xc_handle, dom, vcpu, &info);
363 if ( rc < 0 )
364 return PyErr_SetFromErrno(xc_error);
366 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i,s:i}",
367 "online", info.online,
368 "blocked", info.blocked,
369 "running", info.running,
370 "cpu_time", info.cpu_time,
371 "cpu", info.cpu,
372 "cpumap", info.cpumap);
374 return info_dict;
375 }
377 static PyObject *pyxc_linux_build(PyObject *self,
378 PyObject *args,
379 PyObject *kwds)
380 {
381 XcObject *xc = (XcObject *)self;
383 uint32_t dom;
384 char *image, *ramdisk = NULL, *cmdline = "";
385 int flags = 0, vcpus = 1;
386 int store_evtchn, console_evtchn;
387 unsigned long store_mfn = 0;
388 unsigned long console_mfn = 0;
390 static char *kwd_list[] = { "dom", "store_evtchn",
391 "console_evtchn", "image",
392 /* optional */
393 "ramdisk", "cmdline", "flags",
394 "vcpus", NULL };
396 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssii", kwd_list,
397 &dom, &store_evtchn,
398 &console_evtchn, &image,
399 /* optional */
400 &ramdisk, &cmdline, &flags,
401 &vcpus) )
402 return NULL;
404 if ( xc_linux_build(xc->xc_handle, dom, image,
405 ramdisk, cmdline, flags, vcpus,
406 store_evtchn, &store_mfn,
407 console_evtchn, &console_mfn) != 0 )
408 return PyErr_SetFromErrno(xc_error);
410 return Py_BuildValue("{s:i,s:i}",
411 "store_mfn", store_mfn,
412 "console_mfn", console_mfn);
413 }
415 static PyObject *pyxc_vmx_build(PyObject *self,
416 PyObject *args,
417 PyObject *kwds)
418 {
419 XcObject *xc = (XcObject *)self;
421 uint32_t dom;
422 char *image;
423 int control_evtchn, store_evtchn;
424 int flags = 0, vcpus = 1;
425 int memsize;
426 unsigned long store_mfn = 0;
428 static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn",
429 "memsize", "image", "flags", "vcpus", NULL };
431 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisii", kwd_list,
432 &dom, &control_evtchn, &store_evtchn,
433 &memsize, &image, &flags, &vcpus) )
434 return NULL;
436 if ( xc_vmx_build(xc->xc_handle, dom, memsize, image, control_evtchn,
437 flags, vcpus, store_evtchn, &store_mfn) != 0 )
438 return PyErr_SetFromErrno(xc_error);
440 return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
441 }
443 static PyObject *pyxc_bvtsched_global_set(PyObject *self,
444 PyObject *args,
445 PyObject *kwds)
446 {
447 XcObject *xc = (XcObject *)self;
449 unsigned long ctx_allow;
451 static char *kwd_list[] = { "ctx_allow", NULL };
453 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "l", kwd_list, &ctx_allow) )
454 return NULL;
456 if ( xc_bvtsched_global_set(xc->xc_handle, ctx_allow) != 0 )
457 return PyErr_SetFromErrno(xc_error);
459 Py_INCREF(zero);
460 return zero;
461 }
463 static PyObject *pyxc_bvtsched_global_get(PyObject *self,
464 PyObject *args,
465 PyObject *kwds)
466 {
467 XcObject *xc = (XcObject *)self;
469 unsigned long ctx_allow;
471 if ( !PyArg_ParseTuple(args, "") )
472 return NULL;
474 if ( xc_bvtsched_global_get(xc->xc_handle, &ctx_allow) != 0 )
475 return PyErr_SetFromErrno(xc_error);
477 return Py_BuildValue("s:l", "ctx_allow", ctx_allow);
478 }
480 static PyObject *pyxc_bvtsched_domain_set(PyObject *self,
481 PyObject *args,
482 PyObject *kwds)
483 {
484 XcObject *xc = (XcObject *)self;
486 uint32_t dom;
487 uint32_t mcuadv;
488 int warpback;
489 int32_t warpvalue;
490 long long warpl;
491 long long warpu;
493 static char *kwd_list[] = { "dom", "mcuadv", "warpback", "warpvalue",
494 "warpl", "warpu", NULL };
496 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiiLL", kwd_list,
497 &dom, &mcuadv, &warpback, &warpvalue,
498 &warpl, &warpu) )
499 return NULL;
501 if ( xc_bvtsched_domain_set(xc->xc_handle, dom, mcuadv,
502 warpback, warpvalue, warpl, warpu) != 0 )
503 return PyErr_SetFromErrno(xc_error);
505 Py_INCREF(zero);
506 return zero;
507 }
509 static PyObject *pyxc_bvtsched_domain_get(PyObject *self,
510 PyObject *args,
511 PyObject *kwds)
512 {
513 XcObject *xc = (XcObject *)self;
514 uint32_t dom;
515 uint32_t mcuadv;
516 int warpback;
517 int32_t warpvalue;
518 long long warpl;
519 long long warpu;
521 static char *kwd_list[] = { "dom", NULL };
523 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
524 return NULL;
526 if ( xc_bvtsched_domain_get(xc->xc_handle, dom, &mcuadv, &warpback,
527 &warpvalue, &warpl, &warpu) != 0 )
528 return PyErr_SetFromErrno(xc_error);
530 return Py_BuildValue("{s:i,s:l,s:l,s:l,s:l}",
531 "domain", dom,
532 "mcuadv", mcuadv,
533 "warpback", warpback,
534 "warpvalue", warpvalue,
535 "warpl", warpl,
536 "warpu", warpu);
537 }
539 static PyObject *pyxc_evtchn_alloc_unbound(PyObject *self,
540 PyObject *args,
541 PyObject *kwds)
542 {
543 XcObject *xc = (XcObject *)self;
545 uint32_t dom, remote_dom;
546 int port;
548 static char *kwd_list[] = { "dom", "remote_dom", NULL };
550 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
551 &dom, &remote_dom) )
552 return NULL;
554 if ( (port = xc_evtchn_alloc_unbound(xc->xc_handle, dom, remote_dom)) < 0 )
555 return PyErr_SetFromErrno(xc_error);
557 return PyInt_FromLong(port);
558 }
560 static PyObject *pyxc_evtchn_status(PyObject *self,
561 PyObject *args,
562 PyObject *kwds)
563 {
564 XcObject *xc = (XcObject *)self;
565 PyObject *dict;
567 uint32_t dom = DOMID_SELF;
568 int port, ret;
569 xc_evtchn_status_t status;
571 static char *kwd_list[] = { "port", "dom", NULL };
573 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
574 &port, &dom) )
575 return NULL;
577 ret = xc_evtchn_status(xc->xc_handle, dom, port, &status);
578 if ( ret != 0 )
579 return PyErr_SetFromErrno(xc_error);
581 switch ( status.status )
582 {
583 case EVTCHNSTAT_closed:
584 dict = Py_BuildValue("{s:s}",
585 "status", "closed");
586 break;
587 case EVTCHNSTAT_unbound:
588 dict = Py_BuildValue("{s:s}",
589 "status", "unbound");
590 break;
591 case EVTCHNSTAT_interdomain:
592 dict = Py_BuildValue("{s:s,s:i,s:i}",
593 "status", "interdomain",
594 "dom", status.u.interdomain.dom,
595 "port", status.u.interdomain.port);
596 break;
597 case EVTCHNSTAT_pirq:
598 dict = Py_BuildValue("{s:s,s:i}",
599 "status", "pirq",
600 "irq", status.u.pirq);
601 break;
602 case EVTCHNSTAT_virq:
603 dict = Py_BuildValue("{s:s,s:i}",
604 "status", "virq",
605 "irq", status.u.virq);
606 break;
607 default:
608 dict = Py_BuildValue("{}");
609 break;
610 }
612 return dict;
613 }
615 static PyObject *pyxc_physdev_pci_access_modify(PyObject *self,
616 PyObject *args,
617 PyObject *kwds)
618 {
619 XcObject *xc = (XcObject *)self;
620 uint32_t dom;
621 int bus, dev, func, enable, ret;
623 static char *kwd_list[] = { "dom", "bus", "dev", "func", "enable", NULL };
625 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list,
626 &dom, &bus, &dev, &func, &enable) )
627 return NULL;
629 ret = xc_physdev_pci_access_modify(
630 xc->xc_handle, dom, bus, dev, func, enable);
631 if ( ret != 0 )
632 return PyErr_SetFromErrno(xc_error);
634 Py_INCREF(zero);
635 return zero;
636 }
638 static PyObject *pyxc_readconsolering(PyObject *self,
639 PyObject *args,
640 PyObject *kwds)
641 {
642 XcObject *xc = (XcObject *)self;
644 unsigned int clear = 0;
645 char _str[32768], *str = _str;
646 unsigned int count = 32768;
647 int ret;
649 static char *kwd_list[] = { "clear", NULL };
651 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &clear) )
652 return NULL;
654 ret = xc_readconsolering(xc->xc_handle, &str, &count, clear);
655 if ( ret < 0 )
656 return PyErr_SetFromErrno(xc_error);
658 return PyString_FromStringAndSize(str, count);
659 }
661 static PyObject *pyxc_physinfo(PyObject *self,
662 PyObject *args,
663 PyObject *kwds)
664 {
665 XcObject *xc = (XcObject *)self;
666 xc_physinfo_t info;
667 char cpu_cap[128], *p=cpu_cap, *q=cpu_cap;
668 int i;
670 if ( !PyArg_ParseTuple(args, "") )
671 return NULL;
673 if ( xc_physinfo(xc->xc_handle, &info) != 0 )
674 return PyErr_SetFromErrno(xc_error);
676 *q=0;
677 for(i=0;i<sizeof(info.hw_cap)/4;i++)
678 {
679 p+=sprintf(p,"%08x:",info.hw_cap[i]);
680 if(info.hw_cap[i])
681 q=p;
682 }
683 if(q>cpu_cap)
684 *(q-1)=0;
686 return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:i,s:s}",
687 "threads_per_core", info.threads_per_core,
688 "cores_per_socket", info.cores_per_socket,
689 "sockets_per_node", info.sockets_per_node,
690 "nr_nodes", info.nr_nodes,
691 "total_pages", info.total_pages,
692 "free_pages", info.free_pages,
693 "cpu_khz", info.cpu_khz,
694 "hw_caps", cpu_cap);
695 }
697 static PyObject *pyxc_xeninfo(PyObject *self,
698 PyObject *args,
699 PyObject *kwds)
700 {
701 XcObject *xc = (XcObject *)self;
702 xen_extraversion_t xen_extra;
703 xen_compile_info_t xen_cc;
704 xen_changeset_info_t xen_chgset;
705 xen_capabilities_info_t xen_caps;
706 xen_parameters_info_t xen_parms;
707 long xen_version;
708 char str[128];
710 xen_version = xc_version(xc->xc_handle, XENVER_version, NULL);
712 if ( xc_version(xc->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
713 return PyErr_SetFromErrno(xc_error);
715 if ( xc_version(xc->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
716 return PyErr_SetFromErrno(xc_error);
718 if ( xc_version(xc->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
719 return PyErr_SetFromErrno(xc_error);
721 if ( xc_version(xc->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
722 return PyErr_SetFromErrno(xc_error);
724 if ( xc_version(xc->xc_handle, XENVER_parameters, &xen_parms) != 0 )
725 return PyErr_SetFromErrno(xc_error);
727 sprintf(str,"virt_start=0x%lx",xen_parms.virt_start);
729 return Py_BuildValue("{s:i,s:i,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s}",
730 "xen_major", xen_version >> 16,
731 "xen_minor", (xen_version & 0xffff),
732 "xen_extra", xen_extra,
733 "xen_caps", xen_caps,
734 "xen_params", str,
735 "xen_changeset", xen_chgset,
736 "cc_compiler", xen_cc.compiler,
737 "cc_compile_by", xen_cc.compile_by,
738 "cc_compile_domain", xen_cc.compile_domain,
739 "cc_compile_date", xen_cc.compile_date);
740 }
743 static PyObject *pyxc_sedf_domain_set(PyObject *self,
744 PyObject *args,
745 PyObject *kwds)
746 {
747 XcObject *xc = (XcObject *)self;
748 uint32_t domid;
749 uint64_t period, slice, latency;
750 uint16_t extratime, weight;
751 static char *kwd_list[] = { "dom", "period", "slice",
752 "latency", "extratime", "weight",NULL };
754 if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLhh", kwd_list,
755 &domid, &period, &slice,
756 &latency, &extratime, &weight) )
757 return NULL;
758 if ( xc_sedf_domain_set(xc->xc_handle, domid, period,
759 slice, latency, extratime,weight) != 0 )
760 return PyErr_SetFromErrno(xc_error);
762 Py_INCREF(zero);
763 return zero;
764 }
766 static PyObject *pyxc_sedf_domain_get(PyObject *self,
767 PyObject *args,
768 PyObject *kwds)
769 {
770 XcObject *xc = (XcObject *)self;
771 uint32_t domid;
772 uint64_t period, slice,latency;
773 uint16_t weight, extratime;
775 static char *kwd_list[] = { "dom", NULL };
777 if( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &domid) )
778 return NULL;
780 if ( xc_sedf_domain_get( xc->xc_handle, domid, &period,
781 &slice,&latency,&extratime,&weight) )
782 return PyErr_SetFromErrno(xc_error);
784 return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i}",
785 "domain", domid,
786 "period", period,
787 "slice", slice,
788 "latency", latency,
789 "extratime", extratime);
790 }
792 static PyObject *pyxc_shadow_control(PyObject *self,
793 PyObject *args,
794 PyObject *kwds)
795 {
796 XcObject *xc = (XcObject *)self;
798 uint32_t dom;
799 int op=0;
801 static char *kwd_list[] = { "dom", "op", NULL };
803 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
804 &dom, &op) )
805 return NULL;
807 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL) < 0 )
808 return PyErr_SetFromErrno(xc_error);
810 Py_INCREF(zero);
811 return zero;
812 }
814 static PyObject *pyxc_domain_setmaxmem(PyObject *self,
815 PyObject *args,
816 PyObject *kwds)
817 {
818 XcObject *xc = (XcObject *)self;
820 uint32_t dom;
821 unsigned int maxmem_kb;
823 static char *kwd_list[] = { "dom", "maxmem_kb", NULL };
825 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
826 &dom, &maxmem_kb) )
827 return NULL;
829 if ( xc_domain_setmaxmem(xc->xc_handle, dom, maxmem_kb) != 0 )
830 return PyErr_SetFromErrno(xc_error);
832 Py_INCREF(zero);
833 return zero;
834 }
836 static PyObject *pyxc_domain_memory_increase_reservation(PyObject *self,
837 PyObject *args,
838 PyObject *kwds)
839 {
840 XcObject *xc = (XcObject *)self;
842 uint32_t dom;
843 unsigned long mem_kb;
844 unsigned int extent_order = 0 , address_bits = 0;
845 unsigned long nr_extents;
847 static char *kwd_list[] = { "dom", "mem_kb", "extent_order", "address_bits", NULL };
849 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "il|ii", kwd_list,
850 &dom, &mem_kb, &extent_order, &address_bits) )
851 return NULL;
853 /* round down to nearest power of 2. Assume callers using extent_order>0
854 know what they are doing */
855 nr_extents = (mem_kb / (XC_PAGE_SIZE/1024)) >> extent_order;
856 if ( xc_domain_memory_increase_reservation(xc->xc_handle, dom,
857 nr_extents, extent_order,
858 address_bits, NULL) )
859 return PyErr_SetFromErrno(xc_error);
861 Py_INCREF(zero);
862 return zero;
863 }
865 static PyMethodDef pyxc_methods[] = {
866 { "handle",
867 (PyCFunction)pyxc_handle,
868 0, "\n"
869 "Query the xc control interface file descriptor.\n\n"
870 "Returns: [int] file descriptor\n" },
872 { "domain_create",
873 (PyCFunction)pyxc_domain_create,
874 METH_VARARGS | METH_KEYWORDS, "\n"
875 "Create a new domain.\n"
876 " dom [int, 0]: Domain identifier to use (allocated if zero).\n"
877 "Returns: [int] new domain identifier; -1 on error.\n" },
879 { "domain_max_vcpus",
880 (PyCFunction)pyxc_domain_max_vcpus,
881 METH_VARARGS | METH_KEYWORDS, "\n"
882 "Set the maximum number of VCPUs a domain may create.\n"
883 " dom [int, 0]: Domain identifier to use.\n"
884 " max [int, 0]: New maximum number of VCPUs in domain.\n"
885 "Returns: [int] 0 on success; -1 on error.\n" },
887 { "domain_dumpcore",
888 (PyCFunction)pyxc_domain_dumpcore,
889 METH_VARARGS | METH_KEYWORDS, "\n"
890 "Dump core of a domain.\n"
891 " dom [int]: Identifier of domain to dump core of.\n"
892 " corefile [string]: Name of corefile to be created.\n\n"
893 "Returns: [int] 0 on success; -1 on error.\n" },
895 { "domain_pause",
896 (PyCFunction)pyxc_domain_pause,
897 METH_VARARGS | METH_KEYWORDS, "\n"
898 "Temporarily pause execution of a domain.\n"
899 " dom [int]: Identifier of domain to be paused.\n\n"
900 "Returns: [int] 0 on success; -1 on error.\n" },
902 { "domain_unpause",
903 (PyCFunction)pyxc_domain_unpause,
904 METH_VARARGS | METH_KEYWORDS, "\n"
905 "(Re)start execution of a domain.\n"
906 " dom [int]: Identifier of domain to be unpaused.\n\n"
907 "Returns: [int] 0 on success; -1 on error.\n" },
909 { "domain_destroy",
910 (PyCFunction)pyxc_domain_destroy,
911 METH_VARARGS | METH_KEYWORDS, "\n"
912 "Destroy a domain.\n"
913 " dom [int]: Identifier of domain to be destroyed.\n\n"
914 "Returns: [int] 0 on success; -1 on error.\n" },
916 { "domain_pincpu",
917 (PyCFunction)pyxc_domain_pincpu,
918 METH_VARARGS | METH_KEYWORDS, "\n"
919 "Pin a VCPU to a specified set CPUs.\n"
920 " dom [int]: Identifier of domain to which VCPU belongs.\n"
921 " vcpu [int, 0]: VCPU being pinned.\n"
922 " cpumap [int, -1]: Bitmap of usable CPUs.\n\n"
923 "Returns: [int] 0 on success; -1 on error.\n" },
925 { "domain_setcpuweight",
926 (PyCFunction)pyxc_domain_setcpuweight,
927 METH_VARARGS | METH_KEYWORDS, "\n"
928 "Set cpuweight scheduler parameter for domain.\n"
929 " dom [int]: Identifier of domain to be changed.\n"
930 " cpuweight [float, 1]: VCPU being pinned.\n"
931 "Returns: [int] 0 on success; -1 on error.\n" },
933 { "domain_sethandle",
934 (PyCFunction)pyxc_domain_sethandle,
935 METH_VARARGS | METH_KEYWORDS, "\n"
936 "Set domain's opaque handle.\n"
937 " dom [int]: Identifier of domain.\n"
938 " handle [list of 16 ints]: New opaque handle.\n"
939 "Returns: [int] 0 on success; -1 on error.\n" },
941 { "domain_getinfo",
942 (PyCFunction)pyxc_domain_getinfo,
943 METH_VARARGS | METH_KEYWORDS, "\n"
944 "Get information regarding a set of domains, in increasing id order.\n"
945 " first_dom [int, 0]: First domain to retrieve info about.\n"
946 " max_doms [int, 1024]: Maximum number of domains to retrieve info"
947 " about.\n\n"
948 "Returns: [list of dicts] if list length is less than 'max_doms'\n"
949 " parameter then there was an error, or the end of the\n"
950 " domain-id space was reached.\n"
951 " dom [int]: Identifier of domain to which this info pertains\n"
952 " cpu [int]: CPU to which this domain is bound\n"
953 " vcpus [int]: Number of Virtual CPUS in this domain\n"
954 " dying [int]: Bool - is the domain dying?\n"
955 " crashed [int]: Bool - has the domain crashed?\n"
956 " shutdown [int]: Bool - has the domain shut itself down?\n"
957 " paused [int]: Bool - is the domain paused by control software?\n"
958 " blocked [int]: Bool - is the domain blocked waiting for an event?\n"
959 " running [int]: Bool - is the domain currently running?\n"
960 " mem_kb [int]: Memory reservation, in kilobytes\n"
961 " maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
962 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
963 " shutdown_reason [int]: Numeric code from guest OS, explaining "
964 "reason why it shut itself down.\n" },
966 { "vcpu_getinfo",
967 (PyCFunction)pyxc_vcpu_getinfo,
968 METH_VARARGS | METH_KEYWORDS, "\n"
969 "Get information regarding a VCPU.\n"
970 " dom [int]: Domain to retrieve info about.\n"
971 " vcpu [int, 0]: VCPU to retrieve info about.\n\n"
972 "Returns: [dict]\n"
973 " online [int]: Bool - Is this VCPU currently online?\n"
974 " blocked [int]: Bool - Is this VCPU blocked waiting for an event?\n"
975 " running [int]: Bool - Is this VCPU currently running on a CPU?\n"
976 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
977 " cpumap [int]: Bitmap of CPUs this VCPU can run on\n"
978 " cpu [int]: CPU that this VCPU is currently bound to\n" },
980 { "linux_build",
981 (PyCFunction)pyxc_linux_build,
982 METH_VARARGS | METH_KEYWORDS, "\n"
983 "Build a new Linux guest OS.\n"
984 " dom [int]: Identifier of domain to build into.\n"
985 " image [str]: Name of kernel image file. May be gzipped.\n"
986 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
987 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
988 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
989 "Returns: [int] 0 on success; -1 on error.\n" },
991 { "vmx_build",
992 (PyCFunction)pyxc_vmx_build,
993 METH_VARARGS | METH_KEYWORDS, "\n"
994 "Build a new Linux guest OS.\n"
995 " dom [int]: Identifier of domain to build into.\n"
996 " image [str]: Name of kernel image file. May be gzipped.\n"
997 " memmap [str]: Memory map.\n\n"
998 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
999 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
1000 "Returns: [int] 0 on success; -1 on error.\n" },
1002 { "bvtsched_global_set",
1003 (PyCFunction)pyxc_bvtsched_global_set,
1004 METH_VARARGS | METH_KEYWORDS, "\n"
1005 "Set global tuning parameters for Borrowed Virtual Time scheduler.\n"
1006 " ctx_allow [int]: Minimal guaranteed quantum.\n\n"
1007 "Returns: [int] 0 on success; -1 on error.\n" },
1009 { "bvtsched_global_get",
1010 (PyCFunction)pyxc_bvtsched_global_get,
1011 METH_KEYWORDS, "\n"
1012 "Get global tuning parameters for BVT scheduler.\n"
1013 "Returns: [dict]:\n"
1014 " ctx_allow [int]: context switch allowance\n" },
1016 { "bvtsched_domain_set",
1017 (PyCFunction)pyxc_bvtsched_domain_set,
1018 METH_VARARGS | METH_KEYWORDS, "\n"
1019 "Set per-domain tuning parameters for Borrowed Virtual Time scheduler.\n"
1020 " dom [int]: Identifier of domain to be tuned.\n"
1021 " mcuadv [int]: Proportional to the inverse of the domain's weight.\n"
1022 " warpback [int]: Warp ? \n"
1023 " warpvalue [int]: How far to warp domain's EVT on unblock.\n"
1024 " warpl [int]: How long the domain can run warped.\n"
1025 " warpu [int]: How long before the domain can warp again.\n\n"
1026 "Returns: [int] 0 on success; -1 on error.\n" },
1028 { "bvtsched_domain_get",
1029 (PyCFunction)pyxc_bvtsched_domain_get,
1030 METH_KEYWORDS, "\n"
1031 "Get per-domain tuning parameters under the BVT scheduler.\n"
1032 " dom [int]: Identifier of domain to be queried.\n"
1033 "Returns [dict]:\n"
1034 " domain [int]: Domain ID.\n"
1035 " mcuadv [long]: MCU Advance.\n"
1036 " warp [long]: Warp.\n"
1037 " warpu [long]: Unwarp requirement.\n"
1038 " warpl [long]: Warp limit,\n"
1039 },
1041 { "sedf_domain_set",
1042 (PyCFunction)pyxc_sedf_domain_set,
1043 METH_KEYWORDS, "\n"
1044 "Set the scheduling parameters for a domain when running with Atropos.\n"
1045 " dom [int]: domain to set\n"
1046 " period [long]: domain's scheduling period\n"
1047 " slice [long]: domain's slice per period\n"
1048 " latency [long]: domain's wakeup latency hint\n"
1049 " extratime [int]: domain aware of extratime?\n"
1050 "Returns: [int] 0 on success; -1 on error.\n" },
1052 { "sedf_domain_get",
1053 (PyCFunction)pyxc_sedf_domain_get,
1054 METH_KEYWORDS, "\n"
1055 "Get the current scheduling parameters for a domain when running with\n"
1056 "the Atropos scheduler."
1057 " dom [int]: domain to query\n"
1058 "Returns: [dict]\n"
1059 " domain [int]: domain ID\n"
1060 " period [long]: scheduler period\n"
1061 " slice [long]: CPU reservation per period\n"
1062 " latency [long]: domain's wakeup latency hint\n"
1063 " extratime [int]: domain aware of extratime?\n"},
1065 { "evtchn_alloc_unbound",
1066 (PyCFunction)pyxc_evtchn_alloc_unbound,
1067 METH_VARARGS | METH_KEYWORDS, "\n"
1068 "Allocate an unbound port that will await a remote connection.\n"
1069 " dom [int]: Domain whose port space to allocate from.\n"
1070 " remote_dom [int]: Remote domain to accept connections from.\n\n"
1071 "Returns: [int] Unbound event-channel port.\n" },
1073 { "evtchn_status",
1074 (PyCFunction)pyxc_evtchn_status,
1075 METH_VARARGS | METH_KEYWORDS, "\n"
1076 "Query the status of an event channel.\n"
1077 " dom [int, SELF]: Dom-id of one endpoint of the channel.\n"
1078 " port [int]: Port-id of one endpoint of the channel.\n\n"
1079 "Returns: [dict] dictionary is empty on failure.\n"
1080 " status [str]: 'closed', 'unbound', 'interdomain', 'pirq',"
1081 " or 'virq'.\n"
1082 "The following are returned if 'status' is 'interdomain':\n"
1083 " dom [int]: Dom-id of remote endpoint.\n"
1084 " port [int]: Port-id of remote endpoint.\n"
1085 "The following are returned if 'status' is 'pirq' or 'virq':\n"
1086 " irq [int]: IRQ number.\n" },
1088 { "physdev_pci_access_modify",
1089 (PyCFunction)pyxc_physdev_pci_access_modify,
1090 METH_VARARGS | METH_KEYWORDS, "\n"
1091 "Allow a domain access to a PCI device\n"
1092 " dom [int]: Identifier of domain to be allowed access.\n"
1093 " bus [int]: PCI bus\n"
1094 " dev [int]: PCI slot\n"
1095 " func [int]: PCI function\n"
1096 " enable [int]: Non-zero means enable access; else disable access\n\n"
1097 "Returns: [int] 0 on success; -1 on error.\n" },
1099 { "readconsolering",
1100 (PyCFunction)pyxc_readconsolering,
1101 METH_VARARGS | METH_KEYWORDS, "\n"
1102 "Read Xen's console ring.\n"
1103 " clear [int, 0]: Bool - clear the ring after reading from it?\n\n"
1104 "Returns: [str] string is empty on failure.\n" },
1106 { "physinfo",
1107 (PyCFunction)pyxc_physinfo,
1108 METH_VARARGS, "\n"
1109 "Get information about the physical host machine\n"
1110 "Returns [dict]: information about the hardware"
1111 " [None]: on failure.\n" },
1113 { "xeninfo",
1114 (PyCFunction)pyxc_xeninfo,
1115 METH_VARARGS, "\n"
1116 "Get information about the Xen host\n"
1117 "Returns [dict]: information about Xen"
1118 " [None]: on failure.\n" },
1120 { "shadow_control",
1121 (PyCFunction)pyxc_shadow_control,
1122 METH_VARARGS | METH_KEYWORDS, "\n"
1123 "Set parameter for shadow pagetable interface\n"
1124 " dom [int]: Identifier of domain.\n"
1125 " op [int, 0]: operation\n\n"
1126 "Returns: [int] 0 on success; -1 on error.\n" },
1128 { "domain_setmaxmem",
1129 (PyCFunction)pyxc_domain_setmaxmem,
1130 METH_VARARGS | METH_KEYWORDS, "\n"
1131 "Set a domain's memory limit\n"
1132 " dom [int]: Identifier of domain.\n"
1133 " maxmem_kb [int]: .\n"
1134 "Returns: [int] 0 on success; -1 on error.\n" },
1136 { "domain_memory_increase_reservation",
1137 (PyCFunction)pyxc_domain_memory_increase_reservation,
1138 METH_VARARGS | METH_KEYWORDS, "\n"
1139 "Increase a domain's memory reservation\n"
1140 " dom [int]: Identifier of domain.\n"
1141 " mem_kb [long]: .\n"
1142 "Returns: [int] 0 on success; -1 on error.\n" },
1144 { NULL, NULL, 0, NULL }
1145 };
1148 /*
1149 * Definitions for the 'Xc' module wrapper.
1150 */
1152 staticforward PyTypeObject PyXcType;
1154 static PyObject *PyXc_new(PyObject *self, PyObject *args)
1156 XcObject *xc;
1158 if ( !PyArg_ParseTuple(args, ":new") )
1159 return NULL;
1161 xc = PyObject_New(XcObject, &PyXcType);
1163 if ( (xc->xc_handle = xc_interface_open()) == -1 )
1165 PyObject_Del((PyObject *)xc);
1166 return PyErr_SetFromErrno(xc_error);
1169 return (PyObject *)xc;
1172 static PyObject *PyXc_getattr(PyObject *obj, char *name)
1174 return Py_FindMethod(pyxc_methods, obj, name);
1177 static void PyXc_dealloc(PyObject *self)
1179 XcObject *xc = (XcObject *)self;
1180 (void)xc_interface_close(xc->xc_handle);
1181 PyObject_Del(self);
1184 static PyTypeObject PyXcType = {
1185 PyObject_HEAD_INIT(&PyType_Type)
1186 0,
1187 "Xc",
1188 sizeof(XcObject),
1189 0,
1190 PyXc_dealloc, /* tp_dealloc */
1191 NULL, /* tp_print */
1192 PyXc_getattr, /* tp_getattr */
1193 NULL, /* tp_setattr */
1194 NULL, /* tp_compare */
1195 NULL, /* tp_repr */
1196 NULL, /* tp_as_number */
1197 NULL, /* tp_as_sequence */
1198 NULL, /* tp_as_mapping */
1199 NULL /* tp_hash */
1200 };
1202 static PyMethodDef PyXc_methods[] = {
1203 { "new", PyXc_new, METH_VARARGS, "Create a new " XENPKG " object." },
1204 { NULL, NULL, 0, NULL }
1205 };
1207 PyMODINIT_FUNC initxc(void)
1209 PyObject *m, *d;
1211 m = Py_InitModule(XENPKG, PyXc_methods);
1213 d = PyModule_GetDict(m);
1214 xc_error = PyErr_NewException(XENPKG ".error", NULL, NULL);
1215 PyDict_SetItemString(d, "error", xc_error);
1216 PyDict_SetItemString(d, "VIRQ_DOM_EXC", PyInt_FromLong(VIRQ_DOM_EXC));
1218 zero = PyInt_FromLong(0);
1220 /* KAF: This ensures that we get debug output in a timely manner. */
1221 setbuf(stdout, NULL);
1222 setbuf(stderr, NULL);