ia64/xen-unstable

view tools/python/xen/lowlevel/xc/xc.c @ 11080:8cca42e2610a

Revert inadvertent code change from "replace tabs with spaces" changeset.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Thu Aug 10 14:29:04 2006 +0100 (2006-08-10)
parents 108c05a9f706
children 2afc3f16ae6e
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 "xenctrl.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 PKG "xen.lowlevel.xc"
27 #define CLS "xc"
29 static PyObject *xc_error, *zero;
31 typedef struct {
32 PyObject_HEAD;
33 int xc_handle;
34 } XcObject;
37 static PyObject *dom_op(XcObject *self, PyObject *args,
38 int (*fn)(int, uint32_t));
41 static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
42 {
43 uint32_t dom;
44 char *corefile;
46 if (!PyArg_ParseTuple(args, "is", &dom, &corefile))
47 return NULL;
49 if ( (corefile == NULL) || (corefile[0] == '\0') )
50 return NULL;
52 if (xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0)
53 return PyErr_SetFromErrno(xc_error);
55 Py_INCREF(zero);
56 return zero;
57 }
59 static PyObject *pyxc_handle(XcObject *self)
60 {
61 return PyInt_FromLong(self->xc_handle);
62 }
64 static PyObject *pyxc_domain_create(XcObject *self,
65 PyObject *args,
66 PyObject *kwds)
67 {
68 uint32_t dom = 0;
69 int ret, i;
70 uint32_t ssidref = 0;
71 PyObject *pyhandle = NULL;
72 xen_domain_handle_t handle = {
73 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
74 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef };
76 static char *kwd_list[] = { "dom", "ssidref", "handle", NULL };
78 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiO", kwd_list,
79 &dom, &ssidref, &pyhandle))
80 return NULL;
82 if ( pyhandle != NULL )
83 {
84 if ( !PyList_Check(pyhandle) ||
85 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
86 goto out_exception;
88 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
89 {
90 PyObject *p = PyList_GetItem(pyhandle, i);
91 if ( !PyInt_Check(p) )
92 goto out_exception;
93 handle[i] = (uint8_t)PyInt_AsLong(p);
94 }
95 }
97 if ( (ret = xc_domain_create(self->xc_handle, ssidref, handle, &dom)) < 0 )
98 return PyErr_SetFromErrno(xc_error);
100 return PyInt_FromLong(dom);
102 out_exception:
103 errno = EINVAL;
104 PyErr_SetFromErrno(xc_error);
105 return NULL;
106 }
108 static PyObject *pyxc_domain_max_vcpus(XcObject *self, PyObject *args)
109 {
110 uint32_t dom, max;
112 if (!PyArg_ParseTuple(args, "ii", &dom, &max))
113 return NULL;
115 if (xc_domain_max_vcpus(self->xc_handle, dom, max) != 0)
116 return PyErr_SetFromErrno(xc_error);
118 Py_INCREF(zero);
119 return zero;
120 }
122 static PyObject *pyxc_domain_pause(XcObject *self, PyObject *args)
123 {
124 return dom_op(self, args, xc_domain_pause);
125 }
127 static PyObject *pyxc_domain_unpause(XcObject *self, PyObject *args)
128 {
129 return dom_op(self, args, xc_domain_unpause);
130 }
132 static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args)
133 {
134 return dom_op(self, args, xc_domain_destroy);
135 }
138 static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
139 PyObject *args,
140 PyObject *kwds)
141 {
142 uint32_t dom;
143 int vcpu = 0, i;
144 cpumap_t cpumap = ~0ULL;
145 PyObject *cpulist = NULL;
147 static char *kwd_list[] = { "dom", "vcpu", "cpumap", NULL };
149 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|iO", kwd_list,
150 &dom, &vcpu, &cpulist) )
151 return NULL;
153 if ( (cpulist != NULL) && PyList_Check(cpulist) )
154 {
155 cpumap = 0ULL;
156 for ( i = 0; i < PyList_Size(cpulist); i++ )
157 cpumap |= (cpumap_t)1 << PyInt_AsLong(PyList_GetItem(cpulist, i));
158 }
160 if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
161 return PyErr_SetFromErrno(xc_error);
163 Py_INCREF(zero);
164 return zero;
165 }
167 static PyObject *pyxc_domain_setcpuweight(XcObject *self,
168 PyObject *args,
169 PyObject *kwds)
170 {
171 uint32_t dom;
172 float cpuweight = 1;
174 static char *kwd_list[] = { "dom", "cpuweight", NULL };
176 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|f", kwd_list,
177 &dom, &cpuweight) )
178 return NULL;
180 if ( xc_domain_setcpuweight(self->xc_handle, dom, cpuweight) != 0 )
181 return PyErr_SetFromErrno(xc_error);
183 Py_INCREF(zero);
184 return zero;
185 }
187 static PyObject *pyxc_domain_sethandle(XcObject *self, PyObject *args)
188 {
189 int i;
190 uint32_t dom;
191 PyObject *pyhandle;
192 xen_domain_handle_t handle;
194 if (!PyArg_ParseTuple(args, "iO", &dom, &pyhandle))
195 return NULL;
197 if ( !PyList_Check(pyhandle) ||
198 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
199 {
200 goto out_exception;
201 }
203 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
204 {
205 PyObject *p = PyList_GetItem(pyhandle, i);
206 if ( !PyInt_Check(p) )
207 goto out_exception;
208 handle[i] = (uint8_t)PyInt_AsLong(p);
209 }
211 if (xc_domain_sethandle(self->xc_handle, dom, handle) < 0)
212 return PyErr_SetFromErrno(xc_error);
214 Py_INCREF(zero);
215 return zero;
217 out_exception:
218 errno = EINVAL;
219 PyErr_SetFromErrno(xc_error);
220 return NULL;
221 }
224 static PyObject *pyxc_domain_getinfo(XcObject *self,
225 PyObject *args,
226 PyObject *kwds)
227 {
228 PyObject *list, *info_dict;
230 uint32_t first_dom = 0;
231 int max_doms = 1024, nr_doms, i, j;
232 xc_dominfo_t *info;
234 static char *kwd_list[] = { "first_dom", "max_doms", NULL };
236 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
237 &first_dom, &max_doms) )
238 return NULL;
240 if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL )
241 return PyErr_NoMemory();
243 nr_doms = xc_domain_getinfo(self->xc_handle, first_dom, max_doms, info);
245 if (nr_doms < 0)
246 {
247 free(info);
248 return PyErr_SetFromErrno(xc_error);
249 }
251 list = PyList_New(nr_doms);
252 for ( i = 0 ; i < nr_doms; i++ )
253 {
254 PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t));
255 for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
256 PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
257 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
258 ",s:l,s:L,s:l,s:i,s:i}",
259 "dom", info[i].domid,
260 "online_vcpus", info[i].nr_online_vcpus,
261 "max_vcpu_id", info[i].max_vcpu_id,
262 "dying", info[i].dying,
263 "crashed", info[i].crashed,
264 "shutdown", info[i].shutdown,
265 "paused", info[i].paused,
266 "blocked", info[i].blocked,
267 "running", info[i].running,
268 "mem_kb", info[i].nr_pages*(XC_PAGE_SIZE/1024),
269 "cpu_time", info[i].cpu_time,
270 "maxmem_kb", info[i].max_memkb,
271 "ssidref", info[i].ssidref,
272 "shutdown_reason", info[i].shutdown_reason);
273 PyDict_SetItemString(info_dict, "handle", pyhandle);
274 Py_DECREF(pyhandle);
275 PyList_SetItem(list, i, info_dict);
276 }
278 free(info);
280 return list;
281 }
283 static PyObject *pyxc_vcpu_getinfo(XcObject *self,
284 PyObject *args,
285 PyObject *kwds)
286 {
287 PyObject *info_dict, *cpulist;
289 uint32_t dom, vcpu = 0;
290 xc_vcpuinfo_t info;
291 int rc, i;
292 cpumap_t cpumap;
294 static char *kwd_list[] = { "dom", "vcpu", NULL };
296 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
297 &dom, &vcpu) )
298 return NULL;
300 rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
301 if ( rc < 0 )
302 return PyErr_SetFromErrno(xc_error);
304 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}",
305 "online", info.online,
306 "blocked", info.blocked,
307 "running", info.running,
308 "cpu_time", info.cpu_time,
309 "cpu", info.cpu);
311 cpumap = info.cpumap;
312 cpulist = PyList_New(0);
313 for ( i = 0; cpumap != 0; i++ )
314 {
315 if ( cpumap & 1 )
316 PyList_Append(cpulist, PyInt_FromLong(i));
317 cpumap >>= 1;
318 }
319 PyDict_SetItemString(info_dict, "cpumap", cpulist);
320 Py_DECREF(cpulist);
321 return info_dict;
322 }
324 static PyObject *pyxc_linux_build(XcObject *self,
325 PyObject *args,
326 PyObject *kwds)
327 {
328 uint32_t dom;
329 char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
330 int flags = 0;
331 int store_evtchn, console_evtchn;
332 unsigned long store_mfn = 0;
333 unsigned long console_mfn = 0;
335 static char *kwd_list[] = { "dom", "store_evtchn",
336 "console_evtchn", "image",
337 /* optional */
338 "ramdisk", "cmdline", "flags",
339 "features", NULL };
341 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssis", kwd_list,
342 &dom, &store_evtchn,
343 &console_evtchn, &image,
344 /* optional */
345 &ramdisk, &cmdline, &flags,
346 &features) )
347 return NULL;
349 if ( xc_linux_build(self->xc_handle, dom, image,
350 ramdisk, cmdline, features, flags,
351 store_evtchn, &store_mfn,
352 console_evtchn, &console_mfn) != 0 ) {
353 if (!errno)
354 errno = EINVAL;
355 return PyErr_SetFromErrno(xc_error);
356 }
357 return Py_BuildValue("{s:i,s:i}",
358 "store_mfn", store_mfn,
359 "console_mfn", console_mfn);
360 }
362 static PyObject *pyxc_hvm_build(XcObject *self,
363 PyObject *args,
364 PyObject *kwds)
365 {
366 uint32_t dom;
367 char *image;
368 int store_evtchn;
369 int memsize;
370 int vcpus = 1;
371 int pae = 0;
372 int acpi = 0;
373 int apic = 0;
374 unsigned long store_mfn = 0;
376 static char *kwd_list[] = { "dom", "store_evtchn", "memsize", "image",
377 "vcpus", "pae", "acpi", "apic",
378 NULL };
379 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiisiiii", kwd_list,
380 &dom, &store_evtchn, &memsize,
381 &image, &vcpus, &pae, &acpi, &apic) )
382 return NULL;
384 if ( xc_hvm_build(self->xc_handle, dom, memsize, image,
385 vcpus, pae, acpi, apic, store_evtchn, &store_mfn) != 0 )
386 return PyErr_SetFromErrno(xc_error);
388 return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
389 }
391 static PyObject *pyxc_bvtsched_global_set(XcObject *self, PyObject *args)
392 {
393 unsigned long ctx_allow;
395 if (!PyArg_ParseTuple(args, "l", &ctx_allow))
396 return NULL;
398 if (xc_bvtsched_global_set(self->xc_handle, ctx_allow) != 0)
399 return PyErr_SetFromErrno(xc_error);
401 Py_INCREF(zero);
402 return zero;
403 }
405 static PyObject *pyxc_bvtsched_global_get(XcObject *self)
406 {
407 unsigned long ctx_allow;
409 if (xc_bvtsched_global_get(self->xc_handle, &ctx_allow) != 0)
410 return PyErr_SetFromErrno(xc_error);
412 return Py_BuildValue("s:l", "ctx_allow", ctx_allow);
413 }
415 static PyObject *pyxc_bvtsched_domain_set(XcObject *self,
416 PyObject *args,
417 PyObject *kwds)
418 {
419 uint32_t dom;
420 uint32_t mcuadv;
421 int warpback;
422 int32_t 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(self->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(XcObject *self,
443 PyObject *args)
444 {
445 uint32_t dom;
446 uint32_t mcuadv;
447 int warpback;
448 int32_t warpvalue;
449 long long warpl;
450 long long warpu;
452 if (!PyArg_ParseTuple(args, "i", &dom))
453 return NULL;
455 if (xc_bvtsched_domain_get(self->xc_handle, dom, &mcuadv, &warpback,
456 &warpvalue, &warpl, &warpu) != 0)
457 return PyErr_SetFromErrno(xc_error);
459 return Py_BuildValue("{s:i,s:l,s:l,s:l,s:l}",
460 "domain", dom,
461 "mcuadv", mcuadv,
462 "warpback", warpback,
463 "warpvalue", warpvalue,
464 "warpl", warpl,
465 "warpu", warpu);
466 }
468 static PyObject *pyxc_evtchn_alloc_unbound(XcObject *self,
469 PyObject *args,
470 PyObject *kwds)
471 {
472 uint32_t dom, remote_dom;
473 int port;
475 static char *kwd_list[] = { "dom", "remote_dom", NULL };
477 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
478 &dom, &remote_dom) )
479 return NULL;
481 if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) < 0 )
482 return PyErr_SetFromErrno(xc_error);
484 return PyInt_FromLong(port);
485 }
487 static PyObject *pyxc_evtchn_status(XcObject *self,
488 PyObject *args,
489 PyObject *kwds)
490 {
491 PyObject *dict;
493 uint32_t dom = DOMID_SELF;
494 int port, ret;
495 xc_evtchn_status_t status;
497 static char *kwd_list[] = { "port", "dom", NULL };
499 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
500 &port, &dom) )
501 return NULL;
503 ret = xc_evtchn_status(self->xc_handle, dom, port, &status);
504 if ( ret != 0 )
505 return PyErr_SetFromErrno(xc_error);
507 switch ( status.status )
508 {
509 case EVTCHNSTAT_closed:
510 dict = Py_BuildValue("{s:s}",
511 "status", "closed");
512 break;
513 case EVTCHNSTAT_unbound:
514 dict = Py_BuildValue("{s:s}",
515 "status", "unbound");
516 break;
517 case EVTCHNSTAT_interdomain:
518 dict = Py_BuildValue("{s:s,s:i,s:i}",
519 "status", "interdomain",
520 "dom", status.u.interdomain.dom,
521 "port", status.u.interdomain.port);
522 break;
523 case EVTCHNSTAT_pirq:
524 dict = Py_BuildValue("{s:s,s:i}",
525 "status", "pirq",
526 "irq", status.u.pirq);
527 break;
528 case EVTCHNSTAT_virq:
529 dict = Py_BuildValue("{s:s,s:i}",
530 "status", "virq",
531 "irq", status.u.virq);
532 break;
533 default:
534 dict = Py_BuildValue("{}");
535 break;
536 }
538 return dict;
539 }
541 static PyObject *pyxc_physdev_pci_access_modify(XcObject *self,
542 PyObject *args,
543 PyObject *kwds)
544 {
545 uint32_t dom;
546 int bus, dev, func, enable, ret;
548 static char *kwd_list[] = { "dom", "bus", "dev", "func", "enable", NULL };
550 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list,
551 &dom, &bus, &dev, &func, &enable) )
552 return NULL;
554 ret = xc_physdev_pci_access_modify(
555 self->xc_handle, dom, bus, dev, func, enable);
556 if ( ret != 0 )
557 return PyErr_SetFromErrno(xc_error);
559 Py_INCREF(zero);
560 return zero;
561 }
563 static PyObject *pyxc_readconsolering(XcObject *self,
564 PyObject *args,
565 PyObject *kwds)
566 {
567 unsigned int clear = 0;
568 char _str[32768], *str = _str;
569 unsigned int count = 32768;
570 int ret;
572 static char *kwd_list[] = { "clear", NULL };
574 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &clear) )
575 return NULL;
577 ret = xc_readconsolering(self->xc_handle, &str, &count, clear);
578 if ( ret < 0 )
579 return PyErr_SetFromErrno(xc_error);
581 return PyString_FromStringAndSize(str, count);
582 }
585 static unsigned long pages_to_kib(unsigned long pages)
586 {
587 return pages * (XC_PAGE_SIZE / 1024);
588 }
591 static PyObject *pyxc_pages_to_kib(XcObject *self, PyObject *args)
592 {
593 unsigned long pages;
595 if (!PyArg_ParseTuple(args, "l", &pages))
596 return NULL;
598 return PyLong_FromUnsignedLong(pages_to_kib(pages));
599 }
602 static PyObject *pyxc_physinfo(XcObject *self)
603 {
604 xc_physinfo_t info;
605 char cpu_cap[128], *p=cpu_cap, *q=cpu_cap;
606 int i;
608 if ( xc_physinfo(self->xc_handle, &info) != 0 )
609 return PyErr_SetFromErrno(xc_error);
611 *q=0;
612 for(i=0;i<sizeof(info.hw_cap)/4;i++)
613 {
614 p+=sprintf(p,"%08x:",info.hw_cap[i]);
615 if(info.hw_cap[i])
616 q=p;
617 }
618 if(q>cpu_cap)
619 *(q-1)=0;
621 return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s}",
622 "threads_per_core", info.threads_per_core,
623 "cores_per_socket", info.cores_per_socket,
624 "sockets_per_node", info.sockets_per_node,
625 "nr_nodes", info.nr_nodes,
626 "total_memory", pages_to_kib(info.total_pages),
627 "free_memory", pages_to_kib(info.free_pages),
628 "scrub_memory", pages_to_kib(info.scrub_pages),
629 "cpu_khz", info.cpu_khz,
630 "hw_caps", cpu_cap);
631 }
633 static PyObject *pyxc_xeninfo(XcObject *self)
634 {
635 xen_extraversion_t xen_extra;
636 xen_compile_info_t xen_cc;
637 xen_changeset_info_t xen_chgset;
638 xen_capabilities_info_t xen_caps;
639 xen_platform_parameters_t p_parms;
640 long xen_version;
641 long xen_pagesize;
642 char str[128];
644 xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
646 if ( xc_version(self->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
647 return PyErr_SetFromErrno(xc_error);
649 if ( xc_version(self->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
650 return PyErr_SetFromErrno(xc_error);
652 if ( xc_version(self->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
653 return PyErr_SetFromErrno(xc_error);
655 if ( xc_version(self->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
656 return PyErr_SetFromErrno(xc_error);
658 if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) != 0 )
659 return PyErr_SetFromErrno(xc_error);
661 sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
663 xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
664 if (xen_pagesize < 0 )
665 return PyErr_SetFromErrno(xc_error);
667 return Py_BuildValue("{s:i,s:i,s:s,s:s,s:i,s:s,s:s,s:s,s:s,s:s,s:s}",
668 "xen_major", xen_version >> 16,
669 "xen_minor", (xen_version & 0xffff),
670 "xen_extra", xen_extra,
671 "xen_caps", xen_caps,
672 "xen_pagesize", xen_pagesize,
673 "platform_params", str,
674 "xen_changeset", xen_chgset,
675 "cc_compiler", xen_cc.compiler,
676 "cc_compile_by", xen_cc.compile_by,
677 "cc_compile_domain", xen_cc.compile_domain,
678 "cc_compile_date", xen_cc.compile_date);
679 }
682 static PyObject *pyxc_sedf_domain_set(XcObject *self,
683 PyObject *args,
684 PyObject *kwds)
685 {
686 uint32_t domid;
687 uint64_t period, slice, latency;
688 uint16_t extratime, weight;
689 static char *kwd_list[] = { "dom", "period", "slice",
690 "latency", "extratime", "weight",NULL };
692 if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLhh", kwd_list,
693 &domid, &period, &slice,
694 &latency, &extratime, &weight) )
695 return NULL;
696 if ( xc_sedf_domain_set(self->xc_handle, domid, period,
697 slice, latency, extratime,weight) != 0 )
698 return PyErr_SetFromErrno(xc_error);
700 Py_INCREF(zero);
701 return zero;
702 }
704 static PyObject *pyxc_sedf_domain_get(XcObject *self, PyObject *args)
705 {
706 uint32_t domid;
707 uint64_t period, slice,latency;
708 uint16_t weight, extratime;
710 if(!PyArg_ParseTuple(args, "i", &domid))
711 return NULL;
713 if (xc_sedf_domain_get(self->xc_handle, domid, &period,
714 &slice,&latency,&extratime,&weight))
715 return PyErr_SetFromErrno(xc_error);
717 return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
718 "domain", domid,
719 "period", period,
720 "slice", slice,
721 "latency", latency,
722 "extratime", extratime,
723 "weight", weight);
724 }
726 static PyObject *pyxc_sched_credit_domain_set(XcObject *self,
727 PyObject *args,
728 PyObject *kwds)
729 {
730 uint32_t domid;
731 uint16_t weight;
732 uint16_t cap;
733 static char *kwd_list[] = { "dom", "weight", "cap", NULL };
734 static char kwd_type[] = "I|HH";
735 struct sched_credit_adjdom sdom;
737 weight = 0;
738 cap = (uint16_t)~0U;
739 if( !PyArg_ParseTupleAndKeywords(args, kwds, kwd_type, kwd_list,
740 &domid, &weight, &cap) )
741 return NULL;
743 sdom.weight = weight;
744 sdom.cap = cap;
746 if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 )
747 return PyErr_SetFromErrno(xc_error);
749 Py_INCREF(zero);
750 return zero;
751 }
753 static PyObject *pyxc_sched_credit_domain_get(XcObject *self, PyObject *args)
754 {
755 uint32_t domid;
756 struct sched_credit_adjdom sdom;
758 if( !PyArg_ParseTuple(args, "I", &domid) )
759 return NULL;
761 if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 )
762 return PyErr_SetFromErrno(xc_error);
764 return Py_BuildValue("{s:H,s:H}",
765 "weight", sdom.weight,
766 "cap", sdom.cap);
767 }
769 static PyObject *pyxc_domain_setmaxmem(XcObject *self, PyObject *args)
770 {
771 uint32_t dom;
772 unsigned int maxmem_kb;
774 if (!PyArg_ParseTuple(args, "ii", &dom, &maxmem_kb))
775 return NULL;
777 if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0)
778 return PyErr_SetFromErrno(xc_error);
780 Py_INCREF(zero);
781 return zero;
782 }
784 static PyObject *pyxc_domain_memory_increase_reservation(XcObject *self,
785 PyObject *args,
786 PyObject *kwds)
787 {
788 uint32_t dom;
789 unsigned long mem_kb;
790 unsigned int extent_order = 0 , address_bits = 0;
791 unsigned long nr_extents;
793 static char *kwd_list[] = { "dom", "mem_kb", "extent_order", "address_bits", NULL };
795 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "il|ii", kwd_list,
796 &dom, &mem_kb, &extent_order, &address_bits) )
797 return NULL;
799 /* round down to nearest power of 2. Assume callers using extent_order>0
800 know what they are doing */
801 nr_extents = (mem_kb / (XC_PAGE_SIZE/1024)) >> extent_order;
802 if ( xc_domain_memory_increase_reservation(self->xc_handle, dom,
803 nr_extents, extent_order,
804 address_bits, NULL) )
805 return PyErr_SetFromErrno(xc_error);
807 Py_INCREF(zero);
808 return zero;
809 }
811 static PyObject *pyxc_domain_ioport_permission(XcObject *self,
812 PyObject *args,
813 PyObject *kwds)
814 {
815 uint32_t dom;
816 int first_port, nr_ports, allow_access, ret;
818 static char *kwd_list[] = { "dom", "first_port", "nr_ports", "allow_access", NULL };
820 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiii", kwd_list,
821 &dom, &first_port, &nr_ports, &allow_access) )
822 return NULL;
824 ret = xc_domain_ioport_permission(
825 self->xc_handle, dom, first_port, nr_ports, allow_access);
826 if ( ret != 0 )
827 return PyErr_SetFromErrno(xc_error);
829 Py_INCREF(zero);
830 return zero;
831 }
833 static PyObject *pyxc_domain_irq_permission(PyObject *self,
834 PyObject *args,
835 PyObject *kwds)
836 {
837 XcObject *xc = (XcObject *)self;
838 uint32_t dom;
839 int pirq, allow_access, ret;
841 static char *kwd_list[] = { "dom", "pirq", "allow_access", NULL };
843 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list,
844 &dom, &pirq, &allow_access) )
845 return NULL;
847 ret = xc_domain_irq_permission(
848 xc->xc_handle, dom, pirq, allow_access);
849 if ( ret != 0 )
850 return PyErr_SetFromErrno(xc_error);
852 Py_INCREF(zero);
853 return zero;
854 }
856 static PyObject *pyxc_domain_iomem_permission(PyObject *self,
857 PyObject *args,
858 PyObject *kwds)
859 {
860 XcObject *xc = (XcObject *)self;
861 uint32_t dom;
862 unsigned long first_pfn, nr_pfns, allow_access, ret;
864 static char *kwd_list[] = { "dom", "first_pfn", "nr_pfns", "allow_access", NULL };
866 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illi", kwd_list,
867 &dom, &first_pfn, &nr_pfns, &allow_access) )
868 return NULL;
870 ret = xc_domain_iomem_permission(
871 xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
872 if ( ret != 0 )
873 return PyErr_SetFromErrno(xc_error);
875 Py_INCREF(zero);
876 return zero;
877 }
879 static PyObject *pyxc_domain_set_time_offset(XcObject *self, PyObject *args)
880 {
881 uint32_t dom;
882 int32_t time_offset_seconds;
883 time_t calendar_time;
884 struct tm local_time;
885 struct tm utc_time;
887 if (!PyArg_ParseTuple(args, "i", &dom))
888 return NULL;
890 calendar_time = time(NULL);
891 localtime_r(&calendar_time, &local_time);
892 gmtime_r(&calendar_time, &utc_time);
893 /* set up to get calendar time based on utc_time, with local dst setting */
894 utc_time.tm_isdst = local_time.tm_isdst;
895 time_offset_seconds = (int32_t)difftime(calendar_time, mktime(&utc_time));
897 if (xc_domain_set_time_offset(self->xc_handle, dom, time_offset_seconds) != 0)
898 return NULL;
900 Py_INCREF(zero);
901 return zero;
902 }
904 static PyObject *dom_op(XcObject *self, PyObject *args,
905 int (*fn)(int, uint32_t))
906 {
907 uint32_t dom;
909 if (!PyArg_ParseTuple(args, "i", &dom))
910 return NULL;
912 if (fn(self->xc_handle, dom) != 0)
913 return PyErr_SetFromErrno(xc_error);
915 Py_INCREF(zero);
916 return zero;
917 }
920 static PyMethodDef pyxc_methods[] = {
921 { "handle",
922 (PyCFunction)pyxc_handle,
923 METH_NOARGS, "\n"
924 "Query the xc control interface file descriptor.\n\n"
925 "Returns: [int] file descriptor\n" },
927 { "domain_create",
928 (PyCFunction)pyxc_domain_create,
929 METH_VARARGS | METH_KEYWORDS, "\n"
930 "Create a new domain.\n"
931 " dom [int, 0]: Domain identifier to use (allocated if zero).\n"
932 "Returns: [int] new domain identifier; -1 on error.\n" },
934 { "domain_max_vcpus",
935 (PyCFunction)pyxc_domain_max_vcpus,
936 METH_VARARGS, "\n"
937 "Set the maximum number of VCPUs a domain may create.\n"
938 " dom [int, 0]: Domain identifier to use.\n"
939 " max [int, 0]: New maximum number of VCPUs in domain.\n"
940 "Returns: [int] 0 on success; -1 on error.\n" },
942 { "domain_dumpcore",
943 (PyCFunction)pyxc_domain_dumpcore,
944 METH_VARARGS, "\n"
945 "Dump core of a domain.\n"
946 " dom [int]: Identifier of domain to dump core of.\n"
947 " corefile [string]: Name of corefile to be created.\n\n"
948 "Returns: [int] 0 on success; -1 on error.\n" },
950 { "domain_pause",
951 (PyCFunction)pyxc_domain_pause,
952 METH_VARARGS, "\n"
953 "Temporarily pause execution of a domain.\n"
954 " dom [int]: Identifier of domain to be paused.\n\n"
955 "Returns: [int] 0 on success; -1 on error.\n" },
957 { "domain_unpause",
958 (PyCFunction)pyxc_domain_unpause,
959 METH_VARARGS, "\n"
960 "(Re)start execution of a domain.\n"
961 " dom [int]: Identifier of domain to be unpaused.\n\n"
962 "Returns: [int] 0 on success; -1 on error.\n" },
964 { "domain_destroy",
965 (PyCFunction)pyxc_domain_destroy,
966 METH_VARARGS, "\n"
967 "Destroy a domain.\n"
968 " dom [int]: Identifier of domain to be destroyed.\n\n"
969 "Returns: [int] 0 on success; -1 on error.\n" },
971 { "vcpu_setaffinity",
972 (PyCFunction)pyxc_vcpu_setaffinity,
973 METH_VARARGS | METH_KEYWORDS, "\n"
974 "Pin a VCPU to a specified set CPUs.\n"
975 " dom [int]: Identifier of domain to which VCPU belongs.\n"
976 " vcpu [int, 0]: VCPU being pinned.\n"
977 " cpumap [list, []]: list of usable CPUs.\n\n"
978 "Returns: [int] 0 on success; -1 on error.\n" },
980 { "domain_setcpuweight",
981 (PyCFunction)pyxc_domain_setcpuweight,
982 METH_VARARGS | METH_KEYWORDS, "\n"
983 "Set cpuweight scheduler parameter for domain.\n"
984 " dom [int]: Identifier of domain to be changed.\n"
985 " cpuweight [float, 1]: VCPU being pinned.\n"
986 "Returns: [int] 0 on success; -1 on error.\n" },
988 { "domain_sethandle",
989 (PyCFunction)pyxc_domain_sethandle,
990 METH_VARARGS, "\n"
991 "Set domain's opaque handle.\n"
992 " dom [int]: Identifier of domain.\n"
993 " handle [list of 16 ints]: New opaque handle.\n"
994 "Returns: [int] 0 on success; -1 on error.\n" },
996 { "domain_getinfo",
997 (PyCFunction)pyxc_domain_getinfo,
998 METH_VARARGS | METH_KEYWORDS, "\n"
999 "Get information regarding a set of domains, in increasing id order.\n"
1000 " first_dom [int, 0]: First domain to retrieve info about.\n"
1001 " max_doms [int, 1024]: Maximum number of domains to retrieve info"
1002 " about.\n\n"
1003 "Returns: [list of dicts] if list length is less than 'max_doms'\n"
1004 " parameter then there was an error, or the end of the\n"
1005 " domain-id space was reached.\n"
1006 " dom [int]: Identifier of domain to which this info pertains\n"
1007 " cpu [int]: CPU to which this domain is bound\n"
1008 " vcpus [int]: Number of Virtual CPUS in this domain\n"
1009 " dying [int]: Bool - is the domain dying?\n"
1010 " crashed [int]: Bool - has the domain crashed?\n"
1011 " shutdown [int]: Bool - has the domain shut itself down?\n"
1012 " paused [int]: Bool - is the domain paused by control software?\n"
1013 " blocked [int]: Bool - is the domain blocked waiting for an event?\n"
1014 " running [int]: Bool - is the domain currently running?\n"
1015 " mem_kb [int]: Memory reservation, in kilobytes\n"
1016 " maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
1017 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1018 " shutdown_reason [int]: Numeric code from guest OS, explaining "
1019 "reason why it shut itself down.\n" },
1021 { "vcpu_getinfo",
1022 (PyCFunction)pyxc_vcpu_getinfo,
1023 METH_VARARGS | METH_KEYWORDS, "\n"
1024 "Get information regarding a VCPU.\n"
1025 " dom [int]: Domain to retrieve info about.\n"
1026 " vcpu [int, 0]: VCPU to retrieve info about.\n\n"
1027 "Returns: [dict]\n"
1028 " online [int]: Bool - Is this VCPU currently online?\n"
1029 " blocked [int]: Bool - Is this VCPU blocked waiting for an event?\n"
1030 " running [int]: Bool - Is this VCPU currently running on a CPU?\n"
1031 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1032 " cpumap [int]: Bitmap of CPUs this VCPU can run on\n"
1033 " cpu [int]: CPU that this VCPU is currently bound to\n" },
1035 { "linux_build",
1036 (PyCFunction)pyxc_linux_build,
1037 METH_VARARGS | METH_KEYWORDS, "\n"
1038 "Build a new Linux guest OS.\n"
1039 " dom [int]: Identifier of domain to build into.\n"
1040 " image [str]: Name of kernel image file. May be gzipped.\n"
1041 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
1042 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
1043 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1044 "Returns: [int] 0 on success; -1 on error.\n" },
1046 { "hvm_build",
1047 (PyCFunction)pyxc_hvm_build,
1048 METH_VARARGS | METH_KEYWORDS, "\n"
1049 "Build a new HVM guest OS.\n"
1050 " dom [int]: Identifier of domain to build into.\n"
1051 " image [str]: Name of HVM loader image file.\n"
1052 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1053 "Returns: [int] 0 on success; -1 on error.\n" },
1055 { "bvtsched_global_set",
1056 (PyCFunction)pyxc_bvtsched_global_set,
1057 METH_VARARGS | METH_KEYWORDS, "\n"
1058 "Set global tuning parameters for Borrowed Virtual Time scheduler.\n"
1059 " ctx_allow [int]: Minimal guaranteed quantum.\n\n"
1060 "Returns: [int] 0 on success; -1 on error.\n" },
1062 { "bvtsched_global_get",
1063 (PyCFunction)pyxc_bvtsched_global_get,
1064 METH_NOARGS, "\n"
1065 "Get global tuning parameters for BVT scheduler.\n"
1066 "Returns: [dict]:\n"
1067 " ctx_allow [int]: context switch allowance\n" },
1069 { "bvtsched_domain_set",
1070 (PyCFunction)pyxc_bvtsched_domain_set,
1071 METH_VARARGS | METH_KEYWORDS, "\n"
1072 "Set per-domain tuning parameters for Borrowed Virtual Time scheduler.\n"
1073 " dom [int]: Identifier of domain to be tuned.\n"
1074 " mcuadv [int]: Proportional to the inverse of the domain's weight.\n"
1075 " warpback [int]: Warp ? \n"
1076 " warpvalue [int]: How far to warp domain's EVT on unblock.\n"
1077 " warpl [int]: How long the domain can run warped.\n"
1078 " warpu [int]: How long before the domain can warp again.\n\n"
1079 "Returns: [int] 0 on success; -1 on error.\n" },
1081 { "bvtsched_domain_get",
1082 (PyCFunction)pyxc_bvtsched_domain_get,
1083 METH_VARARGS, "\n"
1084 "Get per-domain tuning parameters under the BVT scheduler.\n"
1085 " dom [int]: Identifier of domain to be queried.\n"
1086 "Returns [dict]:\n"
1087 " domain [int]: Domain ID.\n"
1088 " mcuadv [long]: MCU Advance.\n"
1089 " warp [long]: Warp.\n"
1090 " warpu [long]: Unwarp requirement.\n"
1091 " warpl [long]: Warp limit,\n"
1092 },
1094 { "sedf_domain_set",
1095 (PyCFunction)pyxc_sedf_domain_set,
1096 METH_KEYWORDS, "\n"
1097 "Set the scheduling parameters for a domain when running with Atropos.\n"
1098 " dom [int]: domain to set\n"
1099 " period [long]: domain's scheduling period\n"
1100 " slice [long]: domain's slice per period\n"
1101 " latency [long]: domain's wakeup latency hint\n"
1102 " extratime [int]: domain aware of extratime?\n"
1103 "Returns: [int] 0 on success; -1 on error.\n" },
1105 { "sedf_domain_get",
1106 (PyCFunction)pyxc_sedf_domain_get,
1107 METH_VARARGS, "\n"
1108 "Get the current scheduling parameters for a domain when running with\n"
1109 "the Atropos scheduler."
1110 " dom [int]: domain to query\n"
1111 "Returns: [dict]\n"
1112 " domain [int]: domain ID\n"
1113 " period [long]: scheduler period\n"
1114 " slice [long]: CPU reservation per period\n"
1115 " latency [long]: domain's wakeup latency hint\n"
1116 " extratime [int]: domain aware of extratime?\n"},
1118 { "sched_credit_domain_set",
1119 (PyCFunction)pyxc_sched_credit_domain_set,
1120 METH_KEYWORDS, "\n"
1121 "Set the scheduling parameters for a domain when running with the\n"
1122 "SMP credit scheduler.\n"
1123 " domid [int]: domain id to set\n"
1124 " weight [short]: domain's scheduling weight\n"
1125 "Returns: [int] 0 on success; -1 on error.\n" },
1127 { "sched_credit_domain_get",
1128 (PyCFunction)pyxc_sched_credit_domain_get,
1129 METH_VARARGS, "\n"
1130 "Get the scheduling parameters for a domain when running with the\n"
1131 "SMP credit scheduler.\n"
1132 " domid [int]: domain id to get\n"
1133 "Returns: [dict]\n"
1134 " weight [short]: domain's scheduling weight\n"},
1136 { "evtchn_alloc_unbound",
1137 (PyCFunction)pyxc_evtchn_alloc_unbound,
1138 METH_VARARGS | METH_KEYWORDS, "\n"
1139 "Allocate an unbound port that will await a remote connection.\n"
1140 " dom [int]: Domain whose port space to allocate from.\n"
1141 " remote_dom [int]: Remote domain to accept connections from.\n\n"
1142 "Returns: [int] Unbound event-channel port.\n" },
1144 { "evtchn_status",
1145 (PyCFunction)pyxc_evtchn_status,
1146 METH_VARARGS | METH_KEYWORDS, "\n"
1147 "Query the status of an event channel.\n"
1148 " dom [int, SELF]: Dom-id of one endpoint of the channel.\n"
1149 " port [int]: Port-id of one endpoint of the channel.\n\n"
1150 "Returns: [dict] dictionary is empty on failure.\n"
1151 " status [str]: 'closed', 'unbound', 'interdomain', 'pirq',"
1152 " or 'virq'.\n"
1153 "The following are returned if 'status' is 'interdomain':\n"
1154 " dom [int]: Dom-id of remote endpoint.\n"
1155 " port [int]: Port-id of remote endpoint.\n"
1156 "The following are returned if 'status' is 'pirq' or 'virq':\n"
1157 " irq [int]: IRQ number.\n" },
1159 { "physdev_pci_access_modify",
1160 (PyCFunction)pyxc_physdev_pci_access_modify,
1161 METH_VARARGS | METH_KEYWORDS, "\n"
1162 "Allow a domain access to a PCI device\n"
1163 " dom [int]: Identifier of domain to be allowed access.\n"
1164 " bus [int]: PCI bus\n"
1165 " dev [int]: PCI slot\n"
1166 " func [int]: PCI function\n"
1167 " enable [int]: Non-zero means enable access; else disable access\n\n"
1168 "Returns: [int] 0 on success; -1 on error.\n" },
1170 { "readconsolering",
1171 (PyCFunction)pyxc_readconsolering,
1172 METH_VARARGS | METH_KEYWORDS, "\n"
1173 "Read Xen's console ring.\n"
1174 " clear [int, 0]: Bool - clear the ring after reading from it?\n\n"
1175 "Returns: [str] string is empty on failure.\n" },
1177 { "physinfo",
1178 (PyCFunction)pyxc_physinfo,
1179 METH_NOARGS, "\n"
1180 "Get information about the physical host machine\n"
1181 "Returns [dict]: information about the hardware"
1182 " [None]: on failure.\n" },
1184 { "xeninfo",
1185 (PyCFunction)pyxc_xeninfo,
1186 METH_NOARGS, "\n"
1187 "Get information about the Xen host\n"
1188 "Returns [dict]: information about Xen"
1189 " [None]: on failure.\n" },
1191 { "domain_setmaxmem",
1192 (PyCFunction)pyxc_domain_setmaxmem,
1193 METH_VARARGS, "\n"
1194 "Set a domain's memory limit\n"
1195 " dom [int]: Identifier of domain.\n"
1196 " maxmem_kb [int]: .\n"
1197 "Returns: [int] 0 on success; -1 on error.\n" },
1199 { "domain_memory_increase_reservation",
1200 (PyCFunction)pyxc_domain_memory_increase_reservation,
1201 METH_VARARGS | METH_KEYWORDS, "\n"
1202 "Increase a domain's memory reservation\n"
1203 " dom [int]: Identifier of domain.\n"
1204 " mem_kb [long]: .\n"
1205 "Returns: [int] 0 on success; -1 on error.\n" },
1207 { "domain_ioport_permission",
1208 (PyCFunction)pyxc_domain_ioport_permission,
1209 METH_VARARGS | METH_KEYWORDS, "\n"
1210 "Allow a domain access to a range of IO ports\n"
1211 " dom [int]: Identifier of domain to be allowed access.\n"
1212 " first_port [int]: First IO port\n"
1213 " nr_ports [int]: Number of IO ports\n"
1214 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1215 "Returns: [int] 0 on success; -1 on error.\n" },
1217 { "domain_irq_permission",
1218 (PyCFunction)pyxc_domain_irq_permission,
1219 METH_VARARGS | METH_KEYWORDS, "\n"
1220 "Allow a domain access to a physical IRQ\n"
1221 " dom [int]: Identifier of domain to be allowed access.\n"
1222 " pirq [int]: The Physical IRQ\n"
1223 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1224 "Returns: [int] 0 on success; -1 on error.\n" },
1226 { "domain_iomem_permission",
1227 (PyCFunction)pyxc_domain_iomem_permission,
1228 METH_VARARGS | METH_KEYWORDS, "\n"
1229 "Allow a domain access to a range of IO memory pages\n"
1230 " dom [int]: Identifier of domain to be allowed access.\n"
1231 " first_pfn [long]: First page of I/O Memory\n"
1232 " nr_pfns [long]: Number of pages of I/O Memory (>0)\n"
1233 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1234 "Returns: [int] 0 on success; -1 on error.\n" },
1236 { "pages_to_kib",
1237 (PyCFunction)pyxc_pages_to_kib,
1238 METH_VARARGS, "\n"
1239 "Returns: [int]: The size in KiB of memory spanning the given number "
1240 "of pages.\n" },
1242 { "domain_set_time_offset",
1243 (PyCFunction)pyxc_domain_set_time_offset,
1244 METH_VARARGS, "\n"
1245 "Set a domain's time offset to Dom0's localtime\n"
1246 " dom [int]: Domain whose time offset is being set.\n"
1247 "Returns: [int] 0 on success; -1 on error.\n" },
1249 { NULL, NULL, 0, NULL }
1250 };
1253 static PyObject *PyXc_getattr(PyObject *obj, char *name)
1255 return Py_FindMethod(pyxc_methods, obj, name);
1258 static PyObject *PyXc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1260 XcObject *self = (XcObject *)type->tp_alloc(type, 0);
1262 if (self == NULL)
1263 return NULL;
1265 self->xc_handle = -1;
1267 return (PyObject *)self;
1270 static int
1271 PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
1273 if ((self->xc_handle = xc_interface_open()) == -1) {
1274 PyErr_SetFromErrno(xc_error);
1275 return -1;
1278 return 0;
1281 static void PyXc_dealloc(XcObject *self)
1283 if (self->xc_handle != -1) {
1284 xc_interface_close(self->xc_handle);
1285 self->xc_handle = -1;
1288 self->ob_type->tp_free((PyObject *)self);
1291 static PyTypeObject PyXcType = {
1292 PyObject_HEAD_INIT(NULL)
1293 0,
1294 PKG "." CLS,
1295 sizeof(XcObject),
1296 0,
1297 (destructor)PyXc_dealloc, /* tp_dealloc */
1298 NULL, /* tp_print */
1299 PyXc_getattr, /* tp_getattr */
1300 NULL, /* tp_setattr */
1301 NULL, /* tp_compare */
1302 NULL, /* tp_repr */
1303 NULL, /* tp_as_number */
1304 NULL, /* tp_as_sequence */
1305 NULL, /* tp_as_mapping */
1306 NULL, /* tp_hash */
1307 NULL, /* tp_call */
1308 NULL, /* tp_str */
1309 NULL, /* tp_getattro */
1310 NULL, /* tp_setattro */
1311 NULL, /* tp_as_buffer */
1312 Py_TPFLAGS_DEFAULT, /* tp_flags */
1313 "Xen client connections", /* tp_doc */
1314 NULL, /* tp_traverse */
1315 NULL, /* tp_clear */
1316 NULL, /* tp_richcompare */
1317 0, /* tp_weaklistoffset */
1318 NULL, /* tp_iter */
1319 NULL, /* tp_iternext */
1320 pyxc_methods, /* tp_methods */
1321 NULL, /* tp_members */
1322 NULL, /* tp_getset */
1323 NULL, /* tp_base */
1324 NULL, /* tp_dict */
1325 NULL, /* tp_descr_get */
1326 NULL, /* tp_descr_set */
1327 0, /* tp_dictoffset */
1328 (initproc)PyXc_init, /* tp_init */
1329 NULL, /* tp_alloc */
1330 PyXc_new, /* tp_new */
1331 };
1333 static PyMethodDef xc_methods[] = { { NULL } };
1335 PyMODINIT_FUNC initxc(void)
1337 PyObject *m;
1339 if (PyType_Ready(&PyXcType) < 0)
1340 return;
1342 m = Py_InitModule(PKG, xc_methods);
1344 if (m == NULL)
1345 return;
1347 xc_error = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
1348 zero = PyInt_FromLong(0);
1350 /* KAF: This ensures that we get debug output in a timely manner. */
1351 setbuf(stdout, NULL);
1352 setbuf(stderr, NULL);
1354 Py_INCREF(&PyXcType);
1355 PyModule_AddObject(m, CLS, (PyObject *)&PyXcType);
1357 Py_INCREF(xc_error);
1358 PyModule_AddObject(m, "Error", xc_error);
1362 /*
1363 * Local variables:
1364 * c-indent-level: 4
1365 * c-basic-offset: 4
1366 * End:
1367 */