direct-io.hg

view tools/python/xen/lowlevel/xc/xc.c @ 12988:e080700efa56

[TOOLS] Fix the build. Clearly demarcate PPC-specific stuff.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Wed Dec 13 10:23:53 2006 +0000 (2006-12-13)
parents 749c399d73df
children 2fc3392d0889
line source
1 /******************************************************************************
2 * Xc.c
3 *
4 * Copyright (c) 2003-2004, K A Fraser (University of Cambridge)
5 */
7 #include <Python.h>
8 #include <xenctrl.h>
9 #include <xenguest.h>
10 #include <zlib.h>
11 #include <fcntl.h>
12 #include <netinet/in.h>
13 #include <netinet/tcp.h>
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <sys/mman.h>
17 #include <netdb.h>
18 #include <arpa/inet.h>
20 #include "xenctrl.h"
21 #include <xen/hvm/hvm_info_table.h>
22 #include <xen/hvm/params.h>
24 /* Needed for Python versions earlier than 2.3. */
25 #ifndef PyMODINIT_FUNC
26 #define PyMODINIT_FUNC DL_EXPORT(void)
27 #endif
29 #define PKG "xen.lowlevel.xc"
30 #define CLS "xc"
32 static PyObject *xc_error_obj, *zero;
34 typedef struct {
35 PyObject_HEAD;
36 int xc_handle;
37 } XcObject;
40 static PyObject *dom_op(XcObject *self, PyObject *args,
41 int (*fn)(int, uint32_t));
43 static PyObject *pyxc_error_to_exception(void)
44 {
45 PyObject *pyerr;
46 const xc_error const *err = xc_get_last_error();
47 const char *desc = xc_error_code_to_desc(err->code);
49 if (err->code == XC_ERROR_NONE)
50 return PyErr_SetFromErrno(xc_error_obj);
52 if (err->message[0] != '\0')
53 pyerr = Py_BuildValue("(iss)", err->code, desc, err->message);
54 else
55 pyerr = Py_BuildValue("(is)", err->code, desc);
57 xc_clear_last_error();
59 PyErr_SetObject(xc_error_obj, pyerr);
61 return NULL;
62 }
64 static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
65 {
66 uint32_t dom;
67 char *corefile;
69 if (!PyArg_ParseTuple(args, "is", &dom, &corefile))
70 return NULL;
72 if ( (corefile == NULL) || (corefile[0] == '\0') )
73 return NULL;
75 if (xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0)
76 return pyxc_error_to_exception();
78 Py_INCREF(zero);
79 return zero;
80 }
82 static PyObject *pyxc_handle(XcObject *self)
83 {
84 return PyInt_FromLong(self->xc_handle);
85 }
87 static PyObject *pyxc_domain_create(XcObject *self,
88 PyObject *args,
89 PyObject *kwds)
90 {
91 uint32_t dom = 0, ssidref = 0, flags = 0;
92 int ret, i, hvm = 0;
93 PyObject *pyhandle = NULL;
94 xen_domain_handle_t handle = {
95 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
96 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef };
98 static char *kwd_list[] = { "domid", "ssidref", "handle", "hvm", NULL };
100 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOi", kwd_list,
101 &dom, &ssidref, &pyhandle, &hvm))
102 return NULL;
104 if ( pyhandle != NULL )
105 {
106 if ( !PyList_Check(pyhandle) ||
107 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
108 goto out_exception;
110 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
111 {
112 PyObject *p = PyList_GetItem(pyhandle, i);
113 if ( !PyInt_Check(p) )
114 goto out_exception;
115 handle[i] = (uint8_t)PyInt_AsLong(p);
116 }
117 }
119 if ( hvm )
120 flags |= XEN_DOMCTL_CDF_hvm_guest;
122 if ( (ret = xc_domain_create(self->xc_handle, ssidref,
123 handle, flags, &dom)) < 0 )
124 return pyxc_error_to_exception();
126 return PyInt_FromLong(dom);
128 out_exception:
129 errno = EINVAL;
130 PyErr_SetFromErrno(xc_error_obj);
131 return NULL;
132 }
134 static PyObject *pyxc_domain_max_vcpus(XcObject *self, PyObject *args)
135 {
136 uint32_t dom, max;
138 if (!PyArg_ParseTuple(args, "ii", &dom, &max))
139 return NULL;
141 if (xc_domain_max_vcpus(self->xc_handle, dom, max) != 0)
142 return pyxc_error_to_exception();
144 Py_INCREF(zero);
145 return zero;
146 }
148 static PyObject *pyxc_domain_pause(XcObject *self, PyObject *args)
149 {
150 return dom_op(self, args, xc_domain_pause);
151 }
153 static PyObject *pyxc_domain_unpause(XcObject *self, PyObject *args)
154 {
155 return dom_op(self, args, xc_domain_unpause);
156 }
158 static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args)
159 {
160 return dom_op(self, args, xc_domain_destroy);
161 }
164 static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
165 PyObject *args,
166 PyObject *kwds)
167 {
168 uint32_t dom;
169 int vcpu = 0, i;
170 uint64_t cpumap = ~0ULL;
171 PyObject *cpulist = NULL;
173 static char *kwd_list[] = { "domid", "vcpu", "cpumap", NULL };
175 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|iO", kwd_list,
176 &dom, &vcpu, &cpulist) )
177 return NULL;
179 if ( (cpulist != NULL) && PyList_Check(cpulist) )
180 {
181 cpumap = 0ULL;
182 for ( i = 0; i < PyList_Size(cpulist); i++ )
183 cpumap |= (uint64_t)1 << PyInt_AsLong(PyList_GetItem(cpulist, i));
184 }
186 if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
187 return pyxc_error_to_exception();
189 Py_INCREF(zero);
190 return zero;
191 }
193 static PyObject *pyxc_domain_setcpuweight(XcObject *self,
194 PyObject *args,
195 PyObject *kwds)
196 {
197 uint32_t dom;
198 float cpuweight = 1;
200 static char *kwd_list[] = { "domid", "cpuweight", NULL };
202 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|f", kwd_list,
203 &dom, &cpuweight) )
204 return NULL;
206 if ( xc_domain_setcpuweight(self->xc_handle, dom, cpuweight) != 0 )
207 return pyxc_error_to_exception();
209 Py_INCREF(zero);
210 return zero;
211 }
213 static PyObject *pyxc_domain_sethandle(XcObject *self, PyObject *args)
214 {
215 int i;
216 uint32_t dom;
217 PyObject *pyhandle;
218 xen_domain_handle_t handle;
220 if (!PyArg_ParseTuple(args, "iO", &dom, &pyhandle))
221 return NULL;
223 if ( !PyList_Check(pyhandle) ||
224 (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
225 {
226 goto out_exception;
227 }
229 for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
230 {
231 PyObject *p = PyList_GetItem(pyhandle, i);
232 if ( !PyInt_Check(p) )
233 goto out_exception;
234 handle[i] = (uint8_t)PyInt_AsLong(p);
235 }
237 if (xc_domain_sethandle(self->xc_handle, dom, handle) < 0)
238 return pyxc_error_to_exception();
240 Py_INCREF(zero);
241 return zero;
243 out_exception:
244 PyErr_SetFromErrno(xc_error_obj);
245 return NULL;
246 }
249 static PyObject *pyxc_domain_getinfo(XcObject *self,
250 PyObject *args,
251 PyObject *kwds)
252 {
253 PyObject *list, *info_dict;
255 uint32_t first_dom = 0;
256 int max_doms = 1024, nr_doms, i, j;
257 xc_dominfo_t *info;
259 static char *kwd_list[] = { "first_dom", "max_doms", NULL };
261 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
262 &first_dom, &max_doms) )
263 return NULL;
265 if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL )
266 return PyErr_NoMemory();
268 nr_doms = xc_domain_getinfo(self->xc_handle, first_dom, max_doms, info);
270 if (nr_doms < 0)
271 {
272 free(info);
273 return pyxc_error_to_exception();
274 }
276 list = PyList_New(nr_doms);
277 for ( i = 0 ; i < nr_doms; i++ )
278 {
279 PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t));
280 for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
281 PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
282 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
283 ",s:l,s:L,s:l,s:i,s:i}",
284 "domid", info[i].domid,
285 "online_vcpus", info[i].nr_online_vcpus,
286 "max_vcpu_id", info[i].max_vcpu_id,
287 "hvm", info[i].hvm,
288 "dying", info[i].dying,
289 "crashed", info[i].crashed,
290 "shutdown", info[i].shutdown,
291 "paused", info[i].paused,
292 "blocked", info[i].blocked,
293 "running", info[i].running,
294 "mem_kb", info[i].nr_pages*(XC_PAGE_SIZE/1024),
295 "cpu_time", info[i].cpu_time,
296 "maxmem_kb", info[i].max_memkb,
297 "ssidref", info[i].ssidref,
298 "shutdown_reason", info[i].shutdown_reason);
299 PyDict_SetItemString(info_dict, "handle", pyhandle);
300 Py_DECREF(pyhandle);
301 PyList_SetItem(list, i, info_dict);
302 }
304 free(info);
306 return list;
307 }
309 static PyObject *pyxc_vcpu_getinfo(XcObject *self,
310 PyObject *args,
311 PyObject *kwds)
312 {
313 PyObject *info_dict, *cpulist;
315 uint32_t dom, vcpu = 0;
316 xc_vcpuinfo_t info;
317 int rc, i;
318 uint64_t cpumap;
320 static char *kwd_list[] = { "domid", "vcpu", NULL };
322 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
323 &dom, &vcpu) )
324 return NULL;
326 rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
327 if ( rc < 0 )
328 return pyxc_error_to_exception();
329 rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, &cpumap);
330 if ( rc < 0 )
331 return pyxc_error_to_exception();
333 info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}",
334 "online", info.online,
335 "blocked", info.blocked,
336 "running", info.running,
337 "cpu_time", info.cpu_time,
338 "cpu", info.cpu);
340 cpulist = PyList_New(0);
341 for ( i = 0; cpumap != 0; i++ )
342 {
343 if ( cpumap & 1 )
344 PyList_Append(cpulist, PyInt_FromLong(i));
345 cpumap >>= 1;
346 }
347 PyDict_SetItemString(info_dict, "cpumap", cpulist);
348 Py_DECREF(cpulist);
349 return info_dict;
350 }
352 static PyObject *pyxc_linux_build(XcObject *self,
353 PyObject *args,
354 PyObject *kwds)
355 {
356 uint32_t dom;
357 char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
358 int flags = 0;
359 int store_evtchn, console_evtchn;
360 unsigned int mem_mb;
361 unsigned long store_mfn = 0;
362 unsigned long console_mfn = 0;
364 static char *kwd_list[] = { "domid", "store_evtchn", "memsize",
365 "console_evtchn", "image",
366 /* optional */
367 "ramdisk", "cmdline", "flags",
368 "features", NULL };
370 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis", kwd_list,
371 &dom, &store_evtchn, &mem_mb,
372 &console_evtchn, &image,
373 /* optional */
374 &ramdisk, &cmdline, &flags,
375 &features) )
376 return NULL;
378 if ( xc_linux_build(self->xc_handle, dom, mem_mb, image,
379 ramdisk, cmdline, features, flags,
380 store_evtchn, &store_mfn,
381 console_evtchn, &console_mfn) != 0 ) {
382 return pyxc_error_to_exception();
383 }
384 return Py_BuildValue("{s:i,s:i}",
385 "store_mfn", store_mfn,
386 "console_mfn", console_mfn);
387 }
389 static PyObject *pyxc_hvm_build(XcObject *self,
390 PyObject *args,
391 PyObject *kwds)
392 {
393 uint32_t dom;
394 #if !defined(__ia64__)
395 struct hvm_info_table *va_hvm;
396 uint8_t *va_map, sum;
397 int i;
398 #endif
399 char *image;
400 int store_evtchn, memsize, vcpus = 1, pae = 0, acpi = 0, apic = 1;
401 unsigned long store_mfn;
403 static char *kwd_list[] = { "domid", "store_evtchn",
404 "memsize", "image", "vcpus", "pae", "acpi",
405 "apic", NULL };
406 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|iiii", kwd_list,
407 &dom, &store_evtchn, &memsize,
408 &image, &vcpus, &pae, &acpi, &apic) )
409 return NULL;
411 #if defined(__ia64__)
412 /* Set vcpus to later be retrieved in setup_guest() */
413 xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_VCPUS, vcpus);
414 #endif
415 if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
416 return pyxc_error_to_exception();
418 #if !defined(__ia64__)
419 /* Set up the HVM info table. */
420 va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
421 PROT_READ | PROT_WRITE,
422 HVM_INFO_PFN);
423 if ( va_map == NULL )
424 return PyErr_SetFromErrno(xc_error_obj);
425 va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
426 memset(va_hvm, 0, sizeof(*va_hvm));
427 strncpy(va_hvm->signature, "HVM INFO", 8);
428 va_hvm->length = sizeof(struct hvm_info_table);
429 va_hvm->acpi_enabled = acpi;
430 va_hvm->apic_mode = apic;
431 va_hvm->nr_vcpus = vcpus;
432 for ( i = 0, sum = 0; i < va_hvm->length; i++ )
433 sum += ((uint8_t *)va_hvm)[i];
434 va_hvm->checksum = -sum;
435 munmap(va_map, XC_PAGE_SIZE);
436 #endif
438 xc_get_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_PFN, &store_mfn);
439 #if !defined(__ia64__)
440 xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
441 #endif
442 xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_EVTCHN,
443 store_evtchn);
445 return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
446 }
448 static PyObject *pyxc_evtchn_alloc_unbound(XcObject *self,
449 PyObject *args,
450 PyObject *kwds)
451 {
452 uint32_t dom, remote_dom;
453 int port;
455 static char *kwd_list[] = { "domid", "remote_dom", NULL };
457 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
458 &dom, &remote_dom) )
459 return NULL;
461 if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) < 0 )
462 return pyxc_error_to_exception();
464 return PyInt_FromLong(port);
465 }
467 static PyObject *pyxc_physdev_pci_access_modify(XcObject *self,
468 PyObject *args,
469 PyObject *kwds)
470 {
471 uint32_t dom;
472 int bus, dev, func, enable, ret;
474 static char *kwd_list[] = { "domid", "bus", "dev", "func", "enable", NULL };
476 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list,
477 &dom, &bus, &dev, &func, &enable) )
478 return NULL;
480 ret = xc_physdev_pci_access_modify(
481 self->xc_handle, dom, bus, dev, func, enable);
482 if ( ret != 0 )
483 return pyxc_error_to_exception();
485 Py_INCREF(zero);
486 return zero;
487 }
489 static PyObject *pyxc_readconsolering(XcObject *self,
490 PyObject *args,
491 PyObject *kwds)
492 {
493 unsigned int clear = 0;
494 char _str[32768], *str = _str;
495 unsigned int count = 32768;
496 int ret;
498 static char *kwd_list[] = { "clear", NULL };
500 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &clear) )
501 return NULL;
503 ret = xc_readconsolering(self->xc_handle, &str, &count, clear);
504 if ( ret < 0 )
505 return pyxc_error_to_exception();
507 return PyString_FromStringAndSize(str, count);
508 }
511 static unsigned long pages_to_kib(unsigned long pages)
512 {
513 return pages * (XC_PAGE_SIZE / 1024);
514 }
517 static PyObject *pyxc_pages_to_kib(XcObject *self, PyObject *args)
518 {
519 unsigned long pages;
521 if (!PyArg_ParseTuple(args, "l", &pages))
522 return NULL;
524 return PyLong_FromUnsignedLong(pages_to_kib(pages));
525 }
528 static PyObject *pyxc_physinfo(XcObject *self)
529 {
530 xc_physinfo_t info;
531 char cpu_cap[128], *p=cpu_cap, *q=cpu_cap;
532 int i;
534 if ( xc_physinfo(self->xc_handle, &info) != 0 )
535 return pyxc_error_to_exception();
537 *q=0;
538 for(i=0;i<sizeof(info.hw_cap)/4;i++)
539 {
540 p+=sprintf(p,"%08x:",info.hw_cap[i]);
541 if(info.hw_cap[i])
542 q=p;
543 }
544 if(q>cpu_cap)
545 *(q-1)=0;
547 return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s}",
548 "threads_per_core", info.threads_per_core,
549 "cores_per_socket", info.cores_per_socket,
550 "sockets_per_node", info.sockets_per_node,
551 "nr_nodes", info.nr_nodes,
552 "total_memory", pages_to_kib(info.total_pages),
553 "free_memory", pages_to_kib(info.free_pages),
554 "scrub_memory", pages_to_kib(info.scrub_pages),
555 "cpu_khz", info.cpu_khz,
556 "hw_caps", cpu_cap);
557 }
559 static PyObject *pyxc_xeninfo(XcObject *self)
560 {
561 xen_extraversion_t xen_extra;
562 xen_compile_info_t xen_cc;
563 xen_changeset_info_t xen_chgset;
564 xen_capabilities_info_t xen_caps;
565 xen_platform_parameters_t p_parms;
566 long xen_version;
567 long xen_pagesize;
568 char str[128];
570 xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
572 if ( xc_version(self->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
573 return pyxc_error_to_exception();
575 if ( xc_version(self->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
576 return pyxc_error_to_exception();
578 if ( xc_version(self->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
579 return pyxc_error_to_exception();
581 if ( xc_version(self->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
582 return pyxc_error_to_exception();
584 if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) != 0 )
585 return pyxc_error_to_exception();
587 sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
589 xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
590 if (xen_pagesize < 0 )
591 return pyxc_error_to_exception();
593 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}",
594 "xen_major", xen_version >> 16,
595 "xen_minor", (xen_version & 0xffff),
596 "xen_extra", xen_extra,
597 "xen_caps", xen_caps,
598 "xen_pagesize", xen_pagesize,
599 "platform_params", str,
600 "xen_changeset", xen_chgset,
601 "cc_compiler", xen_cc.compiler,
602 "cc_compile_by", xen_cc.compile_by,
603 "cc_compile_domain", xen_cc.compile_domain,
604 "cc_compile_date", xen_cc.compile_date);
605 }
608 static PyObject *pyxc_sedf_domain_set(XcObject *self,
609 PyObject *args,
610 PyObject *kwds)
611 {
612 uint32_t domid;
613 uint64_t period, slice, latency;
614 uint16_t extratime, weight;
615 static char *kwd_list[] = { "domid", "period", "slice",
616 "latency", "extratime", "weight",NULL };
618 if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLhh", kwd_list,
619 &domid, &period, &slice,
620 &latency, &extratime, &weight) )
621 return NULL;
622 if ( xc_sedf_domain_set(self->xc_handle, domid, period,
623 slice, latency, extratime,weight) != 0 )
624 return pyxc_error_to_exception();
626 Py_INCREF(zero);
627 return zero;
628 }
630 static PyObject *pyxc_sedf_domain_get(XcObject *self, PyObject *args)
631 {
632 uint32_t domid;
633 uint64_t period, slice,latency;
634 uint16_t weight, extratime;
636 if(!PyArg_ParseTuple(args, "i", &domid))
637 return NULL;
639 if (xc_sedf_domain_get(self->xc_handle, domid, &period,
640 &slice,&latency,&extratime,&weight))
641 return pyxc_error_to_exception();
643 return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
644 "domid", domid,
645 "period", period,
646 "slice", slice,
647 "latency", latency,
648 "extratime", extratime,
649 "weight", weight);
650 }
652 static PyObject *pyxc_shadow_control(PyObject *self,
653 PyObject *args,
654 PyObject *kwds)
655 {
656 XcObject *xc = (XcObject *)self;
658 uint32_t dom;
659 int op=0;
661 static char *kwd_list[] = { "dom", "op", NULL };
663 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
664 &dom, &op) )
665 return NULL;
667 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL, 0, NULL)
668 < 0 )
669 return pyxc_error_to_exception();
671 Py_INCREF(zero);
672 return zero;
673 }
675 static PyObject *pyxc_shadow_mem_control(PyObject *self,
676 PyObject *args,
677 PyObject *kwds)
678 {
679 XcObject *xc = (XcObject *)self;
680 int op;
681 uint32_t dom;
682 int mbarg = -1;
683 unsigned long mb;
685 static char *kwd_list[] = { "dom", "mb", NULL };
687 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
688 &dom, &mbarg) )
689 return NULL;
691 if ( mbarg < 0 )
692 op = XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION;
693 else
694 {
695 mb = mbarg;
696 op = XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION;
697 }
698 if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, &mb, 0, NULL) < 0 )
699 return pyxc_error_to_exception();
701 mbarg = mb;
702 return Py_BuildValue("i", mbarg);
703 }
705 static PyObject *pyxc_sched_id_get(XcObject *self) {
707 int sched_id;
708 if (xc_sched_id(self->xc_handle, &sched_id) != 0)
709 return PyErr_SetFromErrno(xc_error_obj);
711 return Py_BuildValue("i", sched_id);
712 }
714 static PyObject *pyxc_sched_credit_domain_set(XcObject *self,
715 PyObject *args,
716 PyObject *kwds)
717 {
718 uint32_t domid;
719 uint16_t weight;
720 uint16_t cap;
721 static char *kwd_list[] = { "domid", "weight", "cap", NULL };
722 static char kwd_type[] = "I|HH";
723 struct xen_domctl_sched_credit sdom;
725 weight = 0;
726 cap = (uint16_t)~0U;
727 if( !PyArg_ParseTupleAndKeywords(args, kwds, kwd_type, kwd_list,
728 &domid, &weight, &cap) )
729 return NULL;
731 sdom.weight = weight;
732 sdom.cap = cap;
734 if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 )
735 return pyxc_error_to_exception();
737 Py_INCREF(zero);
738 return zero;
739 }
741 static PyObject *pyxc_sched_credit_domain_get(XcObject *self, PyObject *args)
742 {
743 uint32_t domid;
744 struct xen_domctl_sched_credit sdom;
746 if( !PyArg_ParseTuple(args, "I", &domid) )
747 return NULL;
749 if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 )
750 return pyxc_error_to_exception();
752 return Py_BuildValue("{s:H,s:H}",
753 "weight", sdom.weight,
754 "cap", sdom.cap);
755 }
757 static PyObject *pyxc_domain_setmaxmem(XcObject *self, PyObject *args)
758 {
759 uint32_t dom;
760 unsigned int maxmem_kb;
762 if (!PyArg_ParseTuple(args, "ii", &dom, &maxmem_kb))
763 return NULL;
765 if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0)
766 return pyxc_error_to_exception();
768 Py_INCREF(zero);
769 return zero;
770 }
772 static PyObject *pyxc_domain_set_memmap_limit(XcObject *self, PyObject *args)
773 {
774 uint32_t dom;
775 unsigned int maplimit_kb;
777 if ( !PyArg_ParseTuple(args, "ii", &dom, &maplimit_kb) )
778 return NULL;
780 if ( xc_domain_set_memmap_limit(self->xc_handle, dom, maplimit_kb) != 0 )
781 return pyxc_error_to_exception();
783 Py_INCREF(zero);
784 return zero;
785 }
787 static PyObject *pyxc_domain_memory_increase_reservation(XcObject *self,
788 PyObject *args,
789 PyObject *kwds)
790 {
791 uint32_t dom;
792 unsigned long mem_kb;
793 unsigned int extent_order = 0 , address_bits = 0;
794 unsigned long nr_extents;
796 static char *kwd_list[] = { "domid", "mem_kb", "extent_order", "address_bits", NULL };
798 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "il|ii", kwd_list,
799 &dom, &mem_kb, &extent_order, &address_bits) )
800 return NULL;
802 /* round down to nearest power of 2. Assume callers using extent_order>0
803 know what they are doing */
804 nr_extents = (mem_kb / (XC_PAGE_SIZE/1024)) >> extent_order;
805 if ( xc_domain_memory_increase_reservation(self->xc_handle, dom,
806 nr_extents, extent_order,
807 address_bits, NULL) )
808 return pyxc_error_to_exception();
810 Py_INCREF(zero);
811 return zero;
812 }
814 static PyObject *pyxc_domain_ioport_permission(XcObject *self,
815 PyObject *args,
816 PyObject *kwds)
817 {
818 uint32_t dom;
819 int first_port, nr_ports, allow_access, ret;
821 static char *kwd_list[] = { "domid", "first_port", "nr_ports", "allow_access", NULL };
823 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiii", kwd_list,
824 &dom, &first_port, &nr_ports, &allow_access) )
825 return NULL;
827 ret = xc_domain_ioport_permission(
828 self->xc_handle, dom, first_port, nr_ports, allow_access);
829 if ( ret != 0 )
830 return pyxc_error_to_exception();
832 Py_INCREF(zero);
833 return zero;
834 }
836 static PyObject *pyxc_domain_irq_permission(PyObject *self,
837 PyObject *args,
838 PyObject *kwds)
839 {
840 XcObject *xc = (XcObject *)self;
841 uint32_t dom;
842 int pirq, allow_access, ret;
844 static char *kwd_list[] = { "domid", "pirq", "allow_access", NULL };
846 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list,
847 &dom, &pirq, &allow_access) )
848 return NULL;
850 ret = xc_domain_irq_permission(
851 xc->xc_handle, dom, pirq, allow_access);
852 if ( ret != 0 )
853 return pyxc_error_to_exception();
855 Py_INCREF(zero);
856 return zero;
857 }
859 static PyObject *pyxc_domain_iomem_permission(PyObject *self,
860 PyObject *args,
861 PyObject *kwds)
862 {
863 XcObject *xc = (XcObject *)self;
864 uint32_t dom;
865 unsigned long first_pfn, nr_pfns, allow_access, ret;
867 static char *kwd_list[] = { "domid", "first_pfn", "nr_pfns", "allow_access", NULL };
869 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illi", kwd_list,
870 &dom, &first_pfn, &nr_pfns, &allow_access) )
871 return NULL;
873 ret = xc_domain_iomem_permission(
874 xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
875 if ( ret != 0 )
876 return pyxc_error_to_exception();
878 Py_INCREF(zero);
879 return zero;
880 }
882 static PyObject *pyxc_domain_set_time_offset(XcObject *self, PyObject *args)
883 {
884 uint32_t dom;
885 int32_t time_offset_seconds;
886 time_t calendar_time;
887 struct tm local_time;
888 struct tm utc_time;
890 if (!PyArg_ParseTuple(args, "i", &dom))
891 return NULL;
893 calendar_time = time(NULL);
894 localtime_r(&calendar_time, &local_time);
895 gmtime_r(&calendar_time, &utc_time);
896 /* set up to get calendar time based on utc_time, with local dst setting */
897 utc_time.tm_isdst = local_time.tm_isdst;
898 time_offset_seconds = (int32_t)difftime(calendar_time, mktime(&utc_time));
900 if (xc_domain_set_time_offset(self->xc_handle, dom, time_offset_seconds) != 0)
901 return NULL;
903 Py_INCREF(zero);
904 return zero;
905 }
907 static PyObject *dom_op(XcObject *self, PyObject *args,
908 int (*fn)(int, uint32_t))
909 {
910 uint32_t dom;
912 if (!PyArg_ParseTuple(args, "i", &dom))
913 return NULL;
915 if (fn(self->xc_handle, dom) != 0)
916 return pyxc_error_to_exception();
918 Py_INCREF(zero);
919 return zero;
920 }
922 #ifdef __powerpc__
923 static PyObject *pyxc_alloc_real_mode_area(XcObject *self,
924 PyObject *args,
925 PyObject *kwds)
926 {
927 uint32_t dom;
928 unsigned int log;
930 static char *kwd_list[] = { "dom", "log", NULL };
932 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
933 &dom, &log) )
934 return NULL;
936 if ( xc_alloc_real_mode_area(self->xc_handle, dom, log) )
937 return PyErr_SetFromErrno(xc_error);
939 Py_INCREF(zero);
940 return zero;
941 }
943 static PyObject *pyxc_prose_build(XcObject *self,
944 PyObject *args,
945 PyObject *kwds)
946 {
947 uint32_t dom;
948 char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
949 int flags = 0;
950 int store_evtchn, console_evtchn;
951 unsigned long store_mfn = 0;
952 unsigned long console_mfn = 0;
953 void *arch_args = NULL;
954 int unused;
956 static char *kwd_list[] = { "dom", "store_evtchn",
957 "console_evtchn", "image",
958 /* optional */
959 "ramdisk", "cmdline", "flags",
960 "features", "arch_args", NULL };
962 if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssiss#", kwd_list,
963 &dom, &store_evtchn,
964 &console_evtchn, &image,
965 /* optional */
966 &ramdisk, &cmdline, &flags,
967 &features, &arch_args, &unused) )
968 return NULL;
970 if ( xc_prose_build(self->xc_handle, dom, image,
971 ramdisk, cmdline, features, flags,
972 store_evtchn, &store_mfn,
973 console_evtchn, &console_mfn,
974 arch_args) != 0 ) {
975 if (!errno)
976 errno = EINVAL;
977 return PyErr_SetFromErrno(xc_error);
978 }
979 return Py_BuildValue("{s:i,s:i}",
980 "store_mfn", store_mfn,
981 "console_mfn", console_mfn);
982 }
983 #endif /* powerpc */
985 static PyMethodDef pyxc_methods[] = {
986 { "handle",
987 (PyCFunction)pyxc_handle,
988 METH_NOARGS, "\n"
989 "Query the xc control interface file descriptor.\n\n"
990 "Returns: [int] file descriptor\n" },
992 { "domain_create",
993 (PyCFunction)pyxc_domain_create,
994 METH_VARARGS | METH_KEYWORDS, "\n"
995 "Create a new domain.\n"
996 " dom [int, 0]: Domain identifier to use (allocated if zero).\n"
997 "Returns: [int] new domain identifier; -1 on error.\n" },
999 { "domain_max_vcpus",
1000 (PyCFunction)pyxc_domain_max_vcpus,
1001 METH_VARARGS, "\n"
1002 "Set the maximum number of VCPUs a domain may create.\n"
1003 " dom [int, 0]: Domain identifier to use.\n"
1004 " max [int, 0]: New maximum number of VCPUs in domain.\n"
1005 "Returns: [int] 0 on success; -1 on error.\n" },
1007 { "domain_dumpcore",
1008 (PyCFunction)pyxc_domain_dumpcore,
1009 METH_VARARGS, "\n"
1010 "Dump core of a domain.\n"
1011 " dom [int]: Identifier of domain to dump core of.\n"
1012 " corefile [string]: Name of corefile to be created.\n\n"
1013 "Returns: [int] 0 on success; -1 on error.\n" },
1015 { "domain_pause",
1016 (PyCFunction)pyxc_domain_pause,
1017 METH_VARARGS, "\n"
1018 "Temporarily pause execution of a domain.\n"
1019 " dom [int]: Identifier of domain to be paused.\n\n"
1020 "Returns: [int] 0 on success; -1 on error.\n" },
1022 { "domain_unpause",
1023 (PyCFunction)pyxc_domain_unpause,
1024 METH_VARARGS, "\n"
1025 "(Re)start execution of a domain.\n"
1026 " dom [int]: Identifier of domain to be unpaused.\n\n"
1027 "Returns: [int] 0 on success; -1 on error.\n" },
1029 { "domain_destroy",
1030 (PyCFunction)pyxc_domain_destroy,
1031 METH_VARARGS, "\n"
1032 "Destroy a domain.\n"
1033 " dom [int]: Identifier of domain to be destroyed.\n\n"
1034 "Returns: [int] 0 on success; -1 on error.\n" },
1036 { "vcpu_setaffinity",
1037 (PyCFunction)pyxc_vcpu_setaffinity,
1038 METH_VARARGS | METH_KEYWORDS, "\n"
1039 "Pin a VCPU to a specified set CPUs.\n"
1040 " dom [int]: Identifier of domain to which VCPU belongs.\n"
1041 " vcpu [int, 0]: VCPU being pinned.\n"
1042 " cpumap [list, []]: list of usable CPUs.\n\n"
1043 "Returns: [int] 0 on success; -1 on error.\n" },
1045 { "domain_setcpuweight",
1046 (PyCFunction)pyxc_domain_setcpuweight,
1047 METH_VARARGS | METH_KEYWORDS, "\n"
1048 "Set cpuweight scheduler parameter for domain.\n"
1049 " dom [int]: Identifier of domain to be changed.\n"
1050 " cpuweight [float, 1]: VCPU being pinned.\n"
1051 "Returns: [int] 0 on success; -1 on error.\n" },
1053 { "domain_sethandle",
1054 (PyCFunction)pyxc_domain_sethandle,
1055 METH_VARARGS, "\n"
1056 "Set domain's opaque handle.\n"
1057 " dom [int]: Identifier of domain.\n"
1058 " handle [list of 16 ints]: New opaque handle.\n"
1059 "Returns: [int] 0 on success; -1 on error.\n" },
1061 { "domain_getinfo",
1062 (PyCFunction)pyxc_domain_getinfo,
1063 METH_VARARGS | METH_KEYWORDS, "\n"
1064 "Get information regarding a set of domains, in increasing id order.\n"
1065 " first_dom [int, 0]: First domain to retrieve info about.\n"
1066 " max_doms [int, 1024]: Maximum number of domains to retrieve info"
1067 " about.\n\n"
1068 "Returns: [list of dicts] if list length is less than 'max_doms'\n"
1069 " parameter then there was an error, or the end of the\n"
1070 " domain-id space was reached.\n"
1071 " dom [int]: Identifier of domain to which this info pertains\n"
1072 " cpu [int]: CPU to which this domain is bound\n"
1073 " vcpus [int]: Number of Virtual CPUS in this domain\n"
1074 " dying [int]: Bool - is the domain dying?\n"
1075 " crashed [int]: Bool - has the domain crashed?\n"
1076 " shutdown [int]: Bool - has the domain shut itself down?\n"
1077 " paused [int]: Bool - is the domain paused by control software?\n"
1078 " blocked [int]: Bool - is the domain blocked waiting for an event?\n"
1079 " running [int]: Bool - is the domain currently running?\n"
1080 " mem_kb [int]: Memory reservation, in kilobytes\n"
1081 " maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
1082 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1083 " shutdown_reason [int]: Numeric code from guest OS, explaining "
1084 "reason why it shut itself down.\n" },
1086 { "vcpu_getinfo",
1087 (PyCFunction)pyxc_vcpu_getinfo,
1088 METH_VARARGS | METH_KEYWORDS, "\n"
1089 "Get information regarding a VCPU.\n"
1090 " dom [int]: Domain to retrieve info about.\n"
1091 " vcpu [int, 0]: VCPU to retrieve info about.\n\n"
1092 "Returns: [dict]\n"
1093 " online [int]: Bool - Is this VCPU currently online?\n"
1094 " blocked [int]: Bool - Is this VCPU blocked waiting for an event?\n"
1095 " running [int]: Bool - Is this VCPU currently running on a CPU?\n"
1096 " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1097 " cpumap [int]: Bitmap of CPUs this VCPU can run on\n"
1098 " cpu [int]: CPU that this VCPU is currently bound to\n" },
1100 { "linux_build",
1101 (PyCFunction)pyxc_linux_build,
1102 METH_VARARGS | METH_KEYWORDS, "\n"
1103 "Build a new Linux guest OS.\n"
1104 " dom [int]: Identifier of domain to build into.\n"
1105 " image [str]: Name of kernel image file. May be gzipped.\n"
1106 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
1107 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
1108 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1109 "Returns: [int] 0 on success; -1 on error.\n" },
1111 { "hvm_build",
1112 (PyCFunction)pyxc_hvm_build,
1113 METH_VARARGS | METH_KEYWORDS, "\n"
1114 "Build a new HVM guest OS.\n"
1115 " dom [int]: Identifier of domain to build into.\n"
1116 " image [str]: Name of HVM loader image file.\n"
1117 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1118 "Returns: [int] 0 on success; -1 on error.\n" },
1120 { "sched_id_get",
1121 (PyCFunction)pyxc_sched_id_get,
1122 METH_NOARGS, "\n"
1123 "Get the current scheduler type in use.\n"
1124 "Returns: [int] sched_id.\n" },
1126 { "sedf_domain_set",
1127 (PyCFunction)pyxc_sedf_domain_set,
1128 METH_KEYWORDS, "\n"
1129 "Set the scheduling parameters for a domain when running with Atropos.\n"
1130 " dom [int]: domain to set\n"
1131 " period [long]: domain's scheduling period\n"
1132 " slice [long]: domain's slice per period\n"
1133 " latency [long]: domain's wakeup latency hint\n"
1134 " extratime [int]: domain aware of extratime?\n"
1135 "Returns: [int] 0 on success; -1 on error.\n" },
1137 { "sedf_domain_get",
1138 (PyCFunction)pyxc_sedf_domain_get,
1139 METH_VARARGS, "\n"
1140 "Get the current scheduling parameters for a domain when running with\n"
1141 "the Atropos scheduler."
1142 " dom [int]: domain to query\n"
1143 "Returns: [dict]\n"
1144 " domain [int]: domain ID\n"
1145 " period [long]: scheduler period\n"
1146 " slice [long]: CPU reservation per period\n"
1147 " latency [long]: domain's wakeup latency hint\n"
1148 " extratime [int]: domain aware of extratime?\n"},
1150 { "sched_credit_domain_set",
1151 (PyCFunction)pyxc_sched_credit_domain_set,
1152 METH_KEYWORDS, "\n"
1153 "Set the scheduling parameters for a domain when running with the\n"
1154 "SMP credit scheduler.\n"
1155 " domid [int]: domain id to set\n"
1156 " weight [short]: domain's scheduling weight\n"
1157 "Returns: [int] 0 on success; -1 on error.\n" },
1159 { "sched_credit_domain_get",
1160 (PyCFunction)pyxc_sched_credit_domain_get,
1161 METH_VARARGS, "\n"
1162 "Get the scheduling parameters for a domain when running with the\n"
1163 "SMP credit scheduler.\n"
1164 " domid [int]: domain id to get\n"
1165 "Returns: [dict]\n"
1166 " weight [short]: domain's scheduling weight\n"},
1168 { "evtchn_alloc_unbound",
1169 (PyCFunction)pyxc_evtchn_alloc_unbound,
1170 METH_VARARGS | METH_KEYWORDS, "\n"
1171 "Allocate an unbound port that will await a remote connection.\n"
1172 " dom [int]: Domain whose port space to allocate from.\n"
1173 " remote_dom [int]: Remote domain to accept connections from.\n\n"
1174 "Returns: [int] Unbound event-channel port.\n" },
1176 { "physdev_pci_access_modify",
1177 (PyCFunction)pyxc_physdev_pci_access_modify,
1178 METH_VARARGS | METH_KEYWORDS, "\n"
1179 "Allow a domain access to a PCI device\n"
1180 " dom [int]: Identifier of domain to be allowed access.\n"
1181 " bus [int]: PCI bus\n"
1182 " dev [int]: PCI slot\n"
1183 " func [int]: PCI function\n"
1184 " enable [int]: Non-zero means enable access; else disable access\n\n"
1185 "Returns: [int] 0 on success; -1 on error.\n" },
1187 { "readconsolering",
1188 (PyCFunction)pyxc_readconsolering,
1189 METH_VARARGS | METH_KEYWORDS, "\n"
1190 "Read Xen's console ring.\n"
1191 " clear [int, 0]: Bool - clear the ring after reading from it?\n\n"
1192 "Returns: [str] string is empty on failure.\n" },
1194 { "physinfo",
1195 (PyCFunction)pyxc_physinfo,
1196 METH_NOARGS, "\n"
1197 "Get information about the physical host machine\n"
1198 "Returns [dict]: information about the hardware"
1199 " [None]: on failure.\n" },
1201 { "xeninfo",
1202 (PyCFunction)pyxc_xeninfo,
1203 METH_NOARGS, "\n"
1204 "Get information about the Xen host\n"
1205 "Returns [dict]: information about Xen"
1206 " [None]: on failure.\n" },
1208 { "shadow_control",
1209 (PyCFunction)pyxc_shadow_control,
1210 METH_VARARGS | METH_KEYWORDS, "\n"
1211 "Set parameter for shadow pagetable interface\n"
1212 " dom [int]: Identifier of domain.\n"
1213 " op [int, 0]: operation\n\n"
1214 "Returns: [int] 0 on success; -1 on error.\n" },
1216 { "shadow_mem_control",
1217 (PyCFunction)pyxc_shadow_mem_control,
1218 METH_VARARGS | METH_KEYWORDS, "\n"
1219 "Set or read shadow pagetable memory use\n"
1220 " dom [int]: Identifier of domain.\n"
1221 " mb [int, -1]: MB of shadow memory this domain should have.\n\n"
1222 "Returns: [int] MB of shadow memory in use by this domain.\n" },
1224 { "domain_setmaxmem",
1225 (PyCFunction)pyxc_domain_setmaxmem,
1226 METH_VARARGS, "\n"
1227 "Set a domain's memory limit\n"
1228 " dom [int]: Identifier of domain.\n"
1229 " maxmem_kb [int]: .\n"
1230 "Returns: [int] 0 on success; -1 on error.\n" },
1232 { "domain_set_memmap_limit",
1233 (PyCFunction)pyxc_domain_set_memmap_limit,
1234 METH_VARARGS, "\n"
1235 "Set a domain's physical memory mappping limit\n"
1236 " dom [int]: Identifier of domain.\n"
1237 " map_limitkb [int]: .\n"
1238 "Returns: [int] 0 on success; -1 on error.\n" },
1240 { "domain_memory_increase_reservation",
1241 (PyCFunction)pyxc_domain_memory_increase_reservation,
1242 METH_VARARGS | METH_KEYWORDS, "\n"
1243 "Increase a domain's memory reservation\n"
1244 " dom [int]: Identifier of domain.\n"
1245 " mem_kb [long]: .\n"
1246 "Returns: [int] 0 on success; -1 on error.\n" },
1248 { "domain_ioport_permission",
1249 (PyCFunction)pyxc_domain_ioport_permission,
1250 METH_VARARGS | METH_KEYWORDS, "\n"
1251 "Allow a domain access to a range of IO ports\n"
1252 " dom [int]: Identifier of domain to be allowed access.\n"
1253 " first_port [int]: First IO port\n"
1254 " nr_ports [int]: Number of IO ports\n"
1255 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1256 "Returns: [int] 0 on success; -1 on error.\n" },
1258 { "domain_irq_permission",
1259 (PyCFunction)pyxc_domain_irq_permission,
1260 METH_VARARGS | METH_KEYWORDS, "\n"
1261 "Allow a domain access to a physical IRQ\n"
1262 " dom [int]: Identifier of domain to be allowed access.\n"
1263 " pirq [int]: The Physical IRQ\n"
1264 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1265 "Returns: [int] 0 on success; -1 on error.\n" },
1267 { "domain_iomem_permission",
1268 (PyCFunction)pyxc_domain_iomem_permission,
1269 METH_VARARGS | METH_KEYWORDS, "\n"
1270 "Allow a domain access to a range of IO memory pages\n"
1271 " dom [int]: Identifier of domain to be allowed access.\n"
1272 " first_pfn [long]: First page of I/O Memory\n"
1273 " nr_pfns [long]: Number of pages of I/O Memory (>0)\n"
1274 " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1275 "Returns: [int] 0 on success; -1 on error.\n" },
1277 { "pages_to_kib",
1278 (PyCFunction)pyxc_pages_to_kib,
1279 METH_VARARGS, "\n"
1280 "Returns: [int]: The size in KiB of memory spanning the given number "
1281 "of pages.\n" },
1283 { "domain_set_time_offset",
1284 (PyCFunction)pyxc_domain_set_time_offset,
1285 METH_VARARGS, "\n"
1286 "Set a domain's time offset to Dom0's localtime\n"
1287 " dom [int]: Domain whose time offset is being set.\n"
1288 "Returns: [int] 0 on success; -1 on error.\n" },
1290 #ifdef __powerpc__
1291 { "arch_alloc_real_mode_area",
1292 (PyCFunction)pyxc_alloc_real_mode_area,
1293 METH_VARARGS | METH_KEYWORDS, "\n"
1294 "Allocate a domain's real mode area.\n"
1295 " dom [int]: Identifier of domain.\n"
1296 " log [int]: Specifies the area's size.\n"
1297 "Returns: [int] 0 on success; -1 on error.\n" },
1299 { "arch_prose_build",
1300 (PyCFunction)pyxc_prose_build,
1301 METH_VARARGS | METH_KEYWORDS, "\n"
1302 "Build a new Linux guest OS.\n"
1303 " dom [int]: Identifier of domain to build into.\n"
1304 " image [str]: Name of kernel image file. May be gzipped.\n"
1305 " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
1306 " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
1307 " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
1308 "Returns: [int] 0 on success; -1 on error.\n" },
1309 #endif /* __powerpc */
1311 { NULL, NULL, 0, NULL }
1312 };
1315 static PyObject *PyXc_getattr(PyObject *obj, char *name)
1317 return Py_FindMethod(pyxc_methods, obj, name);
1320 static PyObject *PyXc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1322 XcObject *self = (XcObject *)type->tp_alloc(type, 0);
1324 if (self == NULL)
1325 return NULL;
1327 self->xc_handle = -1;
1329 return (PyObject *)self;
1332 static int
1333 PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
1335 if ((self->xc_handle = xc_interface_open()) == -1) {
1336 pyxc_error_to_exception();
1337 return -1;
1340 return 0;
1343 static void PyXc_dealloc(XcObject *self)
1345 if (self->xc_handle != -1) {
1346 xc_interface_close(self->xc_handle);
1347 self->xc_handle = -1;
1350 self->ob_type->tp_free((PyObject *)self);
1353 static PyTypeObject PyXcType = {
1354 PyObject_HEAD_INIT(NULL)
1355 0,
1356 PKG "." CLS,
1357 sizeof(XcObject),
1358 0,
1359 (destructor)PyXc_dealloc, /* tp_dealloc */
1360 NULL, /* tp_print */
1361 PyXc_getattr, /* tp_getattr */
1362 NULL, /* tp_setattr */
1363 NULL, /* tp_compare */
1364 NULL, /* tp_repr */
1365 NULL, /* tp_as_number */
1366 NULL, /* tp_as_sequence */
1367 NULL, /* tp_as_mapping */
1368 NULL, /* tp_hash */
1369 NULL, /* tp_call */
1370 NULL, /* tp_str */
1371 NULL, /* tp_getattro */
1372 NULL, /* tp_setattro */
1373 NULL, /* tp_as_buffer */
1374 Py_TPFLAGS_DEFAULT, /* tp_flags */
1375 "Xen client connections", /* tp_doc */
1376 NULL, /* tp_traverse */
1377 NULL, /* tp_clear */
1378 NULL, /* tp_richcompare */
1379 0, /* tp_weaklistoffset */
1380 NULL, /* tp_iter */
1381 NULL, /* tp_iternext */
1382 pyxc_methods, /* tp_methods */
1383 NULL, /* tp_members */
1384 NULL, /* tp_getset */
1385 NULL, /* tp_base */
1386 NULL, /* tp_dict */
1387 NULL, /* tp_descr_get */
1388 NULL, /* tp_descr_set */
1389 0, /* tp_dictoffset */
1390 (initproc)PyXc_init, /* tp_init */
1391 NULL, /* tp_alloc */
1392 PyXc_new, /* tp_new */
1393 };
1395 static PyMethodDef xc_methods[] = { { NULL } };
1397 PyMODINIT_FUNC initxc(void)
1399 PyObject *m;
1401 if (PyType_Ready(&PyXcType) < 0)
1402 return;
1404 m = Py_InitModule(PKG, xc_methods);
1406 if (m == NULL)
1407 return;
1409 xc_error_obj = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
1410 zero = PyInt_FromLong(0);
1412 /* KAF: This ensures that we get debug output in a timely manner. */
1413 setbuf(stdout, NULL);
1414 setbuf(stderr, NULL);
1416 Py_INCREF(&PyXcType);
1417 PyModule_AddObject(m, CLS, (PyObject *)&PyXcType);
1419 Py_INCREF(xc_error_obj);
1420 PyModule_AddObject(m, "Error", xc_error_obj);
1422 /* Expose some libxc constants to Python */
1423 PyModule_AddIntConstant(m, "XEN_SCHEDULER_SEDF", XEN_SCHEDULER_SEDF);
1424 PyModule_AddIntConstant(m, "XEN_SCHEDULER_CREDIT", XEN_SCHEDULER_CREDIT);
1429 /*
1430 * Local variables:
1431 * c-indent-level: 4
1432 * c-basic-offset: 4
1433 * End:
1434 */