source: trunk/packages/xen-3.1/xen-3.1/tools/python/xen/lowlevel/xc/xc.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 50.2 KB
Line 
1/******************************************************************************
2 * Xc.c
3 *
4 * Copyright (c) 2003-2004, K A Fraser (University of Cambridge)
5 */
6
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>
19
20#include "xenctrl.h"
21#include <xen/elfnote.h>
22#include "xc_dom.h"
23#include <xen/hvm/hvm_info_table.h>
24#include <xen/hvm/params.h>
25
26#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
27
28/* Needed for Python versions earlier than 2.3. */
29#ifndef PyMODINIT_FUNC
30#define PyMODINIT_FUNC DL_EXPORT(void)
31#endif
32
33#define PKG "xen.lowlevel.xc"
34#define CLS "xc"
35
36static PyObject *xc_error_obj, *zero;
37
38typedef struct {
39    PyObject_HEAD;
40    int xc_handle;
41} XcObject;
42
43
44static PyObject *dom_op(XcObject *self, PyObject *args,
45                        int (*fn)(int, uint32_t));
46
47static PyObject *pyxc_error_to_exception(void)
48{
49    PyObject *pyerr;
50    const xc_error *err = xc_get_last_error();
51    const char *desc = xc_error_code_to_desc(err->code);
52
53    if ( err->code == XC_ERROR_NONE )
54        return PyErr_SetFromErrno(xc_error_obj);
55
56    if ( err->message[0] != '\0' )
57        pyerr = Py_BuildValue("(iss)", err->code, desc, err->message);
58    else
59        pyerr = Py_BuildValue("(is)", err->code, desc);
60
61    xc_clear_last_error();
62
63    if ( pyerr != NULL )
64    {
65        PyErr_SetObject(xc_error_obj, pyerr);
66        Py_DECREF(pyerr);
67    }
68
69    return NULL;
70}
71
72static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
73{
74    uint32_t dom;
75    char *corefile;
76
77    if ( !PyArg_ParseTuple(args, "is", &dom, &corefile) )
78        return NULL;
79
80    if ( (corefile == NULL) || (corefile[0] == '\0') )
81        return NULL;
82
83    if ( xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0 )
84        return pyxc_error_to_exception();
85   
86    Py_INCREF(zero);
87    return zero;
88}
89
90static PyObject *pyxc_handle(XcObject *self)
91{
92    return PyInt_FromLong(self->xc_handle);
93}
94
95static PyObject *pyxc_domain_create(XcObject *self,
96                                    PyObject *args,
97                                    PyObject *kwds)
98{
99    uint32_t dom = 0, ssidref = 0, flags = 0;
100    int      ret, i, hvm = 0;
101    PyObject *pyhandle = NULL;
102    xen_domain_handle_t handle = { 
103        0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
104        0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef };
105
106    static char *kwd_list[] = { "domid", "ssidref", "handle", "hvm", NULL };
107
108    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOi", kwd_list,
109                                      &dom, &ssidref, &pyhandle, &hvm))
110        return NULL;
111
112    if ( pyhandle != NULL )
113    {
114        if ( !PyList_Check(pyhandle) || 
115             (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
116            goto out_exception;
117
118        for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
119        {
120            PyObject *p = PyList_GetItem(pyhandle, i);
121            if ( !PyInt_Check(p) )
122                goto out_exception;
123            handle[i] = (uint8_t)PyInt_AsLong(p);
124        }
125    }
126
127    if ( hvm )
128        flags |= XEN_DOMCTL_CDF_hvm_guest;
129
130    if ( (ret = xc_domain_create(self->xc_handle, ssidref,
131                                 handle, flags, &dom)) < 0 )
132        return pyxc_error_to_exception();
133
134    return PyInt_FromLong(dom);
135
136out_exception:
137    errno = EINVAL;
138    PyErr_SetFromErrno(xc_error_obj);
139    return NULL;
140}
141
142static PyObject *pyxc_domain_max_vcpus(XcObject *self, PyObject *args)
143{
144    uint32_t dom, max;
145
146    if (!PyArg_ParseTuple(args, "ii", &dom, &max))
147      return NULL;
148
149    if (xc_domain_max_vcpus(self->xc_handle, dom, max) != 0)
150        return pyxc_error_to_exception();
151   
152    Py_INCREF(zero);
153    return zero;
154}
155
156static PyObject *pyxc_domain_pause(XcObject *self, PyObject *args)
157{
158    return dom_op(self, args, xc_domain_pause);
159}
160
161static PyObject *pyxc_domain_unpause(XcObject *self, PyObject *args)
162{
163    return dom_op(self, args, xc_domain_unpause);
164}
165
166static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args)
167{
168    return dom_op(self, args, xc_domain_destroy);
169}
170
171static PyObject *pyxc_domain_shutdown(XcObject *self, PyObject *args)
172{
173    uint32_t dom, reason;
174
175    if ( !PyArg_ParseTuple(args, "ii", &dom, &reason) )
176      return NULL;
177
178    if ( xc_domain_shutdown(self->xc_handle, dom, reason) != 0 )
179        return pyxc_error_to_exception();
180   
181    Py_INCREF(zero);
182    return zero;
183}
184
185static PyObject *pyxc_domain_resume(XcObject *self, PyObject *args)
186{
187    uint32_t dom;
188    int fast;
189
190    if ( !PyArg_ParseTuple(args, "ii", &dom, &fast) )
191        return NULL;
192
193    if ( xc_domain_resume(self->xc_handle, dom, fast) != 0 )
194        return pyxc_error_to_exception();
195
196    Py_INCREF(zero);
197    return zero;
198}
199
200static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
201                                       PyObject *args,
202                                       PyObject *kwds)
203{
204    uint32_t dom;
205    int vcpu = 0, i;
206    uint64_t  cpumap = ~0ULL;
207    PyObject *cpulist = NULL;
208
209    static char *kwd_list[] = { "domid", "vcpu", "cpumap", NULL };
210
211    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|iO", kwd_list, 
212                                      &dom, &vcpu, &cpulist) )
213        return NULL;
214
215    if ( (cpulist != NULL) && PyList_Check(cpulist) )
216    {
217        cpumap = 0ULL;
218        for ( i = 0; i < PyList_Size(cpulist); i++ ) 
219            cpumap |= (uint64_t)1 << PyInt_AsLong(PyList_GetItem(cpulist, i));
220    }
221 
222    if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
223        return pyxc_error_to_exception();
224   
225    Py_INCREF(zero);
226    return zero;
227}
228
229static PyObject *pyxc_domain_setcpuweight(XcObject *self,
230                                          PyObject *args,
231                                          PyObject *kwds)
232{
233    uint32_t dom;
234    float cpuweight = 1;
235
236    static char *kwd_list[] = { "domid", "cpuweight", NULL };
237
238    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|f", kwd_list, 
239                                      &dom, &cpuweight) )
240        return NULL;
241
242    if ( xc_domain_setcpuweight(self->xc_handle, dom, cpuweight) != 0 )
243        return pyxc_error_to_exception();
244   
245    Py_INCREF(zero);
246    return zero;
247}
248
249static PyObject *pyxc_domain_sethandle(XcObject *self, PyObject *args)
250{
251    int i;
252    uint32_t dom;
253    PyObject *pyhandle;
254    xen_domain_handle_t handle;
255
256    if (!PyArg_ParseTuple(args, "iO", &dom, &pyhandle))
257        return NULL;
258
259    if ( !PyList_Check(pyhandle) || 
260         (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
261    {
262        goto out_exception;
263    }
264
265    for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
266    {
267        PyObject *p = PyList_GetItem(pyhandle, i);
268        if ( !PyInt_Check(p) )
269            goto out_exception;
270        handle[i] = (uint8_t)PyInt_AsLong(p);
271    }
272
273    if (xc_domain_sethandle(self->xc_handle, dom, handle) < 0)
274        return pyxc_error_to_exception();
275   
276    Py_INCREF(zero);
277    return zero;
278
279out_exception:
280    PyErr_SetFromErrno(xc_error_obj);
281    return NULL;
282}
283
284
285static PyObject *pyxc_domain_getinfo(XcObject *self,
286                                     PyObject *args,
287                                     PyObject *kwds)
288{
289    PyObject *list, *info_dict, *pyhandle;
290
291    uint32_t first_dom = 0;
292    int max_doms = 1024, nr_doms, i, j;
293    xc_dominfo_t *info;
294
295    static char *kwd_list[] = { "first_dom", "max_doms", NULL };
296   
297    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
298                                      &first_dom, &max_doms) )
299        return NULL;
300
301    if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL )
302        return PyErr_NoMemory();
303
304    nr_doms = xc_domain_getinfo(self->xc_handle, first_dom, max_doms, info);
305
306    if (nr_doms < 0)
307    {
308        free(info);
309        return pyxc_error_to_exception();
310    }
311
312    list = PyList_New(nr_doms);
313    for ( i = 0 ; i < nr_doms; i++ )
314    {
315        info_dict = Py_BuildValue(
316            "{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
317            ",s:L,s:L,s:L,s:i,s:i}",
318            "domid",           (int)info[i].domid,
319            "online_vcpus",    info[i].nr_online_vcpus,
320            "max_vcpu_id",     info[i].max_vcpu_id,
321            "hvm",             info[i].hvm,
322            "dying",           info[i].dying,
323            "crashed",         info[i].crashed,
324            "shutdown",        info[i].shutdown,
325            "paused",          info[i].paused,
326            "blocked",         info[i].blocked,
327            "running",         info[i].running,
328            "mem_kb",          (long long)info[i].nr_pages*(XC_PAGE_SIZE/1024),
329            "cpu_time",        (long long)info[i].cpu_time,
330            "maxmem_kb",       (long long)info[i].max_memkb,
331            "ssidref",         (int)info[i].ssidref,
332            "shutdown_reason", info[i].shutdown_reason);
333        pyhandle = PyList_New(sizeof(xen_domain_handle_t));
334        if ( (pyhandle == NULL) || (info_dict == NULL) )
335        {
336            Py_DECREF(list);
337            if ( pyhandle  != NULL ) { Py_DECREF(pyhandle);  }
338            if ( info_dict != NULL ) { Py_DECREF(info_dict); }
339            return NULL;
340        }
341        for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
342            PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
343        PyDict_SetItemString(info_dict, "handle", pyhandle);
344        Py_DECREF(pyhandle);
345        PyList_SetItem(list, i, info_dict);
346    }
347
348    free(info);
349
350    return list;
351}
352
353static PyObject *pyxc_vcpu_getinfo(XcObject *self,
354                                   PyObject *args,
355                                   PyObject *kwds)
356{
357    PyObject *info_dict, *cpulist;
358
359    uint32_t dom, vcpu = 0;
360    xc_vcpuinfo_t info;
361    int rc, i;
362    uint64_t cpumap;
363
364    static char *kwd_list[] = { "domid", "vcpu", NULL };
365   
366    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
367                                      &dom, &vcpu) )
368        return NULL;
369
370    rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
371    if ( rc < 0 )
372        return pyxc_error_to_exception();
373    rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, &cpumap);
374    if ( rc < 0 )
375        return pyxc_error_to_exception();
376
377    info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}",
378                              "online",   info.online,
379                              "blocked",  info.blocked,
380                              "running",  info.running,
381                              "cpu_time", info.cpu_time,
382                              "cpu",      info.cpu);
383
384    cpulist = PyList_New(0);
385    for ( i = 0; cpumap != 0; i++ )
386    {
387        if ( cpumap & 1 )
388            PyList_Append(cpulist, PyInt_FromLong(i));
389        cpumap >>= 1;
390    }
391    PyDict_SetItemString(info_dict, "cpumap", cpulist);
392    Py_DECREF(cpulist);
393    return info_dict;
394}
395
396static PyObject *pyxc_linux_build(XcObject *self,
397                                  PyObject *args,
398                                  PyObject *kwds)
399{
400    uint32_t domid;
401    struct xc_dom_image *dom;
402    char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
403    int flags = 0;
404    int store_evtchn, console_evtchn;
405    unsigned int mem_mb;
406    unsigned long store_mfn = 0;
407    unsigned long console_mfn = 0;
408    PyObject* elfnote_dict;
409    PyObject* elfnote = NULL;
410    int i;
411
412    static char *kwd_list[] = { "domid", "store_evtchn", "memsize",
413                                "console_evtchn", "image",
414                                /* optional */
415                                "ramdisk", "cmdline", "flags",
416                                "features", NULL };
417
418    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis", kwd_list,
419                                      &domid, &store_evtchn, &mem_mb,
420                                      &console_evtchn, &image,
421                                      /* optional */
422                                      &ramdisk, &cmdline, &flags,
423                                      &features) )
424        return NULL;
425
426    xc_dom_loginit();
427    if (!(dom = xc_dom_allocate(cmdline, features)))
428        return pyxc_error_to_exception();
429
430    if ( xc_dom_linux_build(self->xc_handle, dom, domid, mem_mb, image,
431                            ramdisk, flags, store_evtchn, &store_mfn,
432                            console_evtchn, &console_mfn) != 0 ) {
433        goto out;
434    }
435
436    if ( !(elfnote_dict = PyDict_New()) )
437        goto out;
438   
439    for ( i = 0; i < ARRAY_SIZE(dom->parms.elf_notes); i++ )
440    {
441        switch ( dom->parms.elf_notes[i].type )
442        {
443        case XEN_ENT_NONE:
444            continue;
445        case XEN_ENT_LONG:
446            elfnote = Py_BuildValue("k", dom->parms.elf_notes[i].data.num);
447            break;
448        case XEN_ENT_STR:
449            elfnote = Py_BuildValue("s", dom->parms.elf_notes[i].data.str);
450            break;
451        }
452        PyDict_SetItemString(elfnote_dict,
453                             dom->parms.elf_notes[i].name,
454                             elfnote);
455        Py_DECREF(elfnote);
456    }
457
458    xc_dom_release(dom);
459
460    return Py_BuildValue("{s:i,s:i,s:N}", 
461                         "store_mfn", store_mfn,
462                         "console_mfn", console_mfn,
463                         "notes", elfnote_dict);
464
465  out:
466    xc_dom_release(dom);
467    return pyxc_error_to_exception();
468}
469
470static PyObject *pyxc_get_hvm_param(XcObject *self,
471                                    PyObject *args,
472                                    PyObject *kwds)
473{
474    uint32_t dom;
475    int param;
476    unsigned long value;
477
478    static char *kwd_list[] = { "domid", "param", NULL }; 
479    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
480                                      &dom, &param) )
481        return NULL;
482
483    if ( xc_get_hvm_param(self->xc_handle, dom, param, &value) != 0 )
484        return pyxc_error_to_exception();
485
486    return Py_BuildValue("i", value);
487
488}
489
490static PyObject *pyxc_hvm_build(XcObject *self,
491                                PyObject *args,
492                                PyObject *kwds)
493{
494    uint32_t dom;
495#if !defined(__ia64__)
496    struct hvm_info_table *va_hvm;
497    uint8_t *va_map, sum;
498    int i;
499#endif
500    char *image;
501    int store_evtchn, memsize, vcpus = 1, pae = 0, acpi = 0, apic = 1;
502    unsigned long store_mfn;
503
504    static char *kwd_list[] = { "domid", "store_evtchn",
505                                "memsize", "image", "vcpus", "pae", "acpi",
506                                "apic", NULL };
507    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|iiii", kwd_list,
508                                      &dom, &store_evtchn, &memsize,
509                                      &image, &vcpus, &pae, &acpi, &apic) )
510        return NULL;
511
512    if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
513        return pyxc_error_to_exception();
514
515#if !defined(__ia64__)
516    /* Set up the HVM info table. */
517    va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
518                                  PROT_READ | PROT_WRITE,
519                                  HVM_INFO_PFN);
520    if ( va_map == NULL )
521        return PyErr_SetFromErrno(xc_error_obj);
522    va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
523    memset(va_hvm, 0, sizeof(*va_hvm));
524    strncpy(va_hvm->signature, "HVM INFO", 8);
525    va_hvm->length       = sizeof(struct hvm_info_table);
526    va_hvm->acpi_enabled = acpi;
527    va_hvm->apic_mode    = apic;
528    va_hvm->nr_vcpus     = vcpus;
529    for ( i = 0, sum = 0; i < va_hvm->length; i++ )
530        sum += ((uint8_t *)va_hvm)[i];
531    va_hvm->checksum = -sum;
532    munmap(va_map, XC_PAGE_SIZE);
533#endif
534
535    xc_get_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_PFN, &store_mfn);
536#if !defined(__ia64__)
537    xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
538#endif
539    xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_EVTCHN,
540                     store_evtchn);
541
542    return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
543}
544
545static PyObject *pyxc_evtchn_alloc_unbound(XcObject *self,
546                                           PyObject *args,
547                                           PyObject *kwds)
548{
549    uint32_t dom, remote_dom;
550    int port;
551
552    static char *kwd_list[] = { "domid", "remote_dom", NULL };
553
554    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
555                                      &dom, &remote_dom) )
556        return NULL;
557
558    if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) < 0 )
559        return pyxc_error_to_exception();
560
561    return PyInt_FromLong(port);
562}
563
564static PyObject *pyxc_evtchn_reset(XcObject *self,
565                                   PyObject *args,
566                                   PyObject *kwds)
567{
568    uint32_t dom;
569
570    static char *kwd_list[] = { "dom", NULL };
571
572    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
573        return NULL;
574
575    if ( xc_evtchn_reset(self->xc_handle, dom) < 0 )
576        return pyxc_error_to_exception();
577
578    Py_INCREF(zero);
579    return zero;
580}
581
582static PyObject *pyxc_physdev_pci_access_modify(XcObject *self,
583                                                PyObject *args,
584                                                PyObject *kwds)
585{
586    uint32_t dom;
587    int bus, dev, func, enable, ret;
588
589    static char *kwd_list[] = { "domid", "bus", "dev", "func", "enable", NULL };
590
591    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list, 
592                                      &dom, &bus, &dev, &func, &enable) )
593        return NULL;
594
595    ret = xc_physdev_pci_access_modify(
596        self->xc_handle, dom, bus, dev, func, enable);
597    if ( ret != 0 )
598        return pyxc_error_to_exception();
599
600    Py_INCREF(zero);
601    return zero;
602}
603
604static PyObject *pyxc_readconsolering(XcObject *self,
605                                      PyObject *args,
606                                      PyObject *kwds)
607{
608    unsigned int clear = 0;
609    char         _str[32768], *str = _str;
610    unsigned int count = 32768;
611    int          ret;
612
613    static char *kwd_list[] = { "clear", NULL };
614
615    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &clear) )
616        return NULL;
617
618    ret = xc_readconsolering(self->xc_handle, &str, &count, clear);
619    if ( ret < 0 )
620        return pyxc_error_to_exception();
621
622    return PyString_FromStringAndSize(str, count);
623}
624
625
626static unsigned long pages_to_kib(unsigned long pages)
627{
628    return pages * (XC_PAGE_SIZE / 1024);
629}
630
631
632static PyObject *pyxc_pages_to_kib(XcObject *self, PyObject *args)
633{
634    unsigned long pages;
635
636    if (!PyArg_ParseTuple(args, "l", &pages))
637        return NULL;
638
639    return PyLong_FromUnsignedLong(pages_to_kib(pages));
640}
641
642
643static PyObject *pyxc_physinfo(XcObject *self)
644{
645    xc_physinfo_t info;
646    char cpu_cap[128], *p=cpu_cap, *q=cpu_cap;
647    int i;
648   
649    if ( xc_physinfo(self->xc_handle, &info) != 0 )
650        return pyxc_error_to_exception();
651
652    *q=0;
653    for(i=0;i<sizeof(info.hw_cap)/4;i++)
654    {
655        p+=sprintf(p,"%08x:",info.hw_cap[i]);
656        if(info.hw_cap[i])
657            q=p;
658    }
659    if(q>cpu_cap)
660        *(q-1)=0;
661
662    return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s}",
663                         "threads_per_core", info.threads_per_core,
664                         "cores_per_socket", info.cores_per_socket,
665                         "sockets_per_node", info.sockets_per_node,
666                         "nr_nodes",         info.nr_nodes,
667                         "total_memory",     pages_to_kib(info.total_pages),
668                         "free_memory",      pages_to_kib(info.free_pages),
669                         "scrub_memory",     pages_to_kib(info.scrub_pages),
670                         "cpu_khz",          info.cpu_khz,
671                         "hw_caps",          cpu_cap);
672}
673
674static PyObject *pyxc_xeninfo(XcObject *self)
675{
676    xen_extraversion_t xen_extra;
677    xen_compile_info_t xen_cc;
678    xen_changeset_info_t xen_chgset;
679    xen_capabilities_info_t xen_caps;
680    xen_platform_parameters_t p_parms;
681    long xen_version;
682    long xen_pagesize;
683    char str[128];
684
685    xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
686
687    if ( xc_version(self->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
688        return pyxc_error_to_exception();
689
690    if ( xc_version(self->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
691        return pyxc_error_to_exception();
692
693    if ( xc_version(self->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
694        return pyxc_error_to_exception();
695
696    if ( xc_version(self->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
697        return pyxc_error_to_exception();
698
699    if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) != 0 )
700        return pyxc_error_to_exception();
701
702    sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
703
704    xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
705    if (xen_pagesize < 0 )
706        return pyxc_error_to_exception();
707
708    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}",
709                         "xen_major", xen_version >> 16,
710                         "xen_minor", (xen_version & 0xffff),
711                         "xen_extra", xen_extra,
712                         "xen_caps",  xen_caps,
713                         "xen_pagesize", xen_pagesize,
714                         "platform_params", str,
715                         "xen_changeset", xen_chgset,
716                         "cc_compiler", xen_cc.compiler,
717                         "cc_compile_by", xen_cc.compile_by,
718                         "cc_compile_domain", xen_cc.compile_domain,
719                         "cc_compile_date", xen_cc.compile_date);
720}
721
722
723static PyObject *pyxc_sedf_domain_set(XcObject *self,
724                                      PyObject *args,
725                                      PyObject *kwds)
726{
727    uint32_t domid;
728    uint64_t period, slice, latency;
729    uint16_t extratime, weight;
730    static char *kwd_list[] = { "domid", "period", "slice",
731                                "latency", "extratime", "weight",NULL };
732   
733    if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLhh", kwd_list, 
734                                     &domid, &period, &slice,
735                                     &latency, &extratime, &weight) )
736        return NULL;
737   if ( xc_sedf_domain_set(self->xc_handle, domid, period,
738                           slice, latency, extratime,weight) != 0 )
739        return pyxc_error_to_exception();
740
741    Py_INCREF(zero);
742    return zero;
743}
744
745static PyObject *pyxc_sedf_domain_get(XcObject *self, PyObject *args)
746{
747    uint32_t domid;
748    uint64_t period, slice,latency;
749    uint16_t weight, extratime;
750   
751    if(!PyArg_ParseTuple(args, "i", &domid))
752        return NULL;
753   
754    if (xc_sedf_domain_get(self->xc_handle, domid, &period,
755                           &slice,&latency,&extratime,&weight))
756        return pyxc_error_to_exception();
757
758    return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
759                         "domid",    domid,
760                         "period",    period,
761                         "slice",     slice,
762                         "latency",   latency,
763                         "extratime", extratime,
764                         "weight",    weight);
765}
766
767static PyObject *pyxc_shadow_control(PyObject *self,
768                                     PyObject *args,
769                                     PyObject *kwds)
770{
771    XcObject *xc = (XcObject *)self;
772
773    uint32_t dom;
774    int op=0;
775
776    static char *kwd_list[] = { "dom", "op", NULL };
777
778    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, 
779                                      &dom, &op) )
780        return NULL;
781   
782    if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL, 0, NULL) 
783         < 0 )
784        return pyxc_error_to_exception();
785   
786    Py_INCREF(zero);
787    return zero;
788}
789
790static PyObject *pyxc_shadow_mem_control(PyObject *self,
791                                         PyObject *args,
792                                         PyObject *kwds)
793{
794    XcObject *xc = (XcObject *)self;
795    int op;
796    uint32_t dom;
797    int mbarg = -1;
798    unsigned long mb;
799
800    static char *kwd_list[] = { "dom", "mb", NULL };
801
802    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, 
803                                      &dom, &mbarg) )
804        return NULL;
805   
806    if ( mbarg < 0 ) 
807        op = XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION;
808    else 
809    {
810        mb = mbarg;
811        op = XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION;
812    }
813    if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, &mb, 0, NULL) < 0 )
814        return pyxc_error_to_exception();
815   
816    mbarg = mb;
817    return Py_BuildValue("i", mbarg);
818}
819
820static PyObject *pyxc_sched_id_get(XcObject *self) {
821   
822    int sched_id;
823    if (xc_sched_id(self->xc_handle, &sched_id) != 0)
824        return PyErr_SetFromErrno(xc_error_obj);
825
826    return Py_BuildValue("i", sched_id);
827}
828
829static PyObject *pyxc_sched_credit_domain_set(XcObject *self,
830                                              PyObject *args,
831                                              PyObject *kwds)
832{
833    uint32_t domid;
834    uint16_t weight;
835    uint16_t cap;
836    static char *kwd_list[] = { "domid", "weight", "cap", NULL };
837    static char kwd_type[] = "I|HH";
838    struct xen_domctl_sched_credit sdom;
839   
840    weight = 0;
841    cap = (uint16_t)~0U;
842    if( !PyArg_ParseTupleAndKeywords(args, kwds, kwd_type, kwd_list, 
843                                     &domid, &weight, &cap) )
844        return NULL;
845
846    sdom.weight = weight;
847    sdom.cap = cap;
848
849    if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 )
850        return pyxc_error_to_exception();
851
852    Py_INCREF(zero);
853    return zero;
854}
855
856static PyObject *pyxc_sched_credit_domain_get(XcObject *self, PyObject *args)
857{
858    uint32_t domid;
859    struct xen_domctl_sched_credit sdom;
860   
861    if( !PyArg_ParseTuple(args, "I", &domid) )
862        return NULL;
863   
864    if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 )
865        return pyxc_error_to_exception();
866
867    return Py_BuildValue("{s:H,s:H}",
868                         "weight",  sdom.weight,
869                         "cap",     sdom.cap);
870}
871
872static PyObject *pyxc_domain_setmaxmem(XcObject *self, PyObject *args)
873{
874    uint32_t dom;
875    unsigned int maxmem_kb;
876
877    if (!PyArg_ParseTuple(args, "ii", &dom, &maxmem_kb))
878        return NULL;
879
880    if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0)
881        return pyxc_error_to_exception();
882   
883    Py_INCREF(zero);
884    return zero;
885}
886
887static PyObject *pyxc_domain_set_memmap_limit(XcObject *self, PyObject *args)
888{
889    uint32_t dom;
890    unsigned int maplimit_kb;
891
892    if ( !PyArg_ParseTuple(args, "ii", &dom, &maplimit_kb) )
893        return NULL;
894
895    if ( xc_domain_set_memmap_limit(self->xc_handle, dom, maplimit_kb) != 0 )
896        return pyxc_error_to_exception();
897   
898    Py_INCREF(zero);
899    return zero;
900}
901
902static PyObject *pyxc_domain_memory_increase_reservation(XcObject *self,
903                                                         PyObject *args,
904                                                         PyObject *kwds)
905{
906    uint32_t dom;
907    unsigned long mem_kb;
908    unsigned int extent_order = 0 , address_bits = 0;
909    unsigned long nr_extents;
910
911    static char *kwd_list[] = { "domid", "mem_kb", "extent_order", "address_bits", NULL };
912
913    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "il|ii", kwd_list, 
914                                      &dom, &mem_kb, &extent_order, &address_bits) )
915        return NULL;
916
917    /* round down to nearest power of 2. Assume callers using extent_order>0
918       know what they are doing */
919    nr_extents = (mem_kb / (XC_PAGE_SIZE/1024)) >> extent_order;
920    if ( xc_domain_memory_increase_reservation(self->xc_handle, dom, 
921                                               nr_extents, extent_order, 
922                                               address_bits, NULL) )
923        return pyxc_error_to_exception();
924   
925    Py_INCREF(zero);
926    return zero;
927}
928
929static PyObject *pyxc_domain_ioport_permission(XcObject *self,
930                                               PyObject *args,
931                                               PyObject *kwds)
932{
933    uint32_t dom;
934    int first_port, nr_ports, allow_access, ret;
935
936    static char *kwd_list[] = { "domid", "first_port", "nr_ports", "allow_access", NULL };
937
938    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiii", kwd_list, 
939                                      &dom, &first_port, &nr_ports, &allow_access) )
940        return NULL;
941
942    ret = xc_domain_ioport_permission(
943        self->xc_handle, dom, first_port, nr_ports, allow_access);
944    if ( ret != 0 )
945        return pyxc_error_to_exception();
946
947    Py_INCREF(zero);
948    return zero;
949}
950
951static PyObject *pyxc_domain_irq_permission(PyObject *self,
952                                            PyObject *args,
953                                            PyObject *kwds)
954{
955    XcObject *xc = (XcObject *)self;
956    uint32_t dom;
957    int pirq, allow_access, ret;
958
959    static char *kwd_list[] = { "domid", "pirq", "allow_access", NULL };
960
961    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list, 
962                                      &dom, &pirq, &allow_access) )
963        return NULL;
964
965    ret = xc_domain_irq_permission(
966        xc->xc_handle, dom, pirq, allow_access);
967    if ( ret != 0 )
968        return pyxc_error_to_exception();
969
970    Py_INCREF(zero);
971    return zero;
972}
973
974static PyObject *pyxc_domain_iomem_permission(PyObject *self,
975                                               PyObject *args,
976                                               PyObject *kwds)
977{
978    XcObject *xc = (XcObject *)self;
979    uint32_t dom;
980    unsigned long first_pfn, nr_pfns, allow_access, ret;
981
982    static char *kwd_list[] = { "domid", "first_pfn", "nr_pfns", "allow_access", NULL };
983
984    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illi", kwd_list, 
985                                      &dom, &first_pfn, &nr_pfns, &allow_access) )
986        return NULL;
987
988    ret = xc_domain_iomem_permission(
989        xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
990    if ( ret != 0 )
991        return pyxc_error_to_exception();
992
993    Py_INCREF(zero);
994    return zero;
995}
996
997static PyObject *pyxc_domain_set_time_offset(XcObject *self, PyObject *args)
998{
999    uint32_t dom;
1000    int32_t time_offset_seconds;
1001    time_t calendar_time;
1002    struct tm local_time;
1003    struct tm utc_time;
1004
1005    if (!PyArg_ParseTuple(args, "i", &dom))
1006        return NULL;
1007
1008    calendar_time = time(NULL);
1009    localtime_r(&calendar_time, &local_time);
1010    gmtime_r(&calendar_time, &utc_time);
1011    /* set up to get calendar time based on utc_time, with local dst setting */
1012    utc_time.tm_isdst = local_time.tm_isdst;
1013    time_offset_seconds = (int32_t)difftime(calendar_time, mktime(&utc_time));
1014
1015    if (xc_domain_set_time_offset(self->xc_handle, dom, time_offset_seconds) != 0)
1016        return NULL;
1017
1018    Py_INCREF(zero);
1019    return zero;
1020}
1021
1022static PyObject *pyxc_domain_send_trigger(XcObject *self,
1023                                          PyObject *args,
1024                                          PyObject *kwds)
1025{
1026    uint32_t dom;
1027    int trigger, vcpu = 0;
1028
1029    static char *kwd_list[] = { "domid", "trigger", "vcpu", NULL };
1030
1031    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii|i", kwd_list, 
1032                                      &dom, &trigger, &vcpu) )
1033        return NULL;
1034
1035    if (xc_domain_send_trigger(self->xc_handle, dom, trigger, vcpu) != 0)
1036        return pyxc_error_to_exception();
1037
1038    Py_INCREF(zero);
1039    return zero;
1040}
1041
1042static PyObject *pyxc_send_debug_keys(XcObject *self,
1043                                      PyObject *args,
1044                                      PyObject *kwds)
1045{
1046    char *keys;
1047
1048    static char *kwd_list[] = { "keys", NULL };
1049
1050    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list, &keys) )
1051        return NULL;
1052
1053    if ( xc_send_debug_keys(self->xc_handle, keys) != 0 )
1054        return pyxc_error_to_exception();
1055
1056    Py_INCREF(zero);
1057    return zero;
1058}
1059
1060static PyObject *dom_op(XcObject *self, PyObject *args,
1061                        int (*fn)(int, uint32_t))
1062{
1063    uint32_t dom;
1064
1065    if (!PyArg_ParseTuple(args, "i", &dom))
1066        return NULL;
1067
1068    if (fn(self->xc_handle, dom) != 0)
1069        return pyxc_error_to_exception();
1070
1071    Py_INCREF(zero);
1072    return zero;
1073}
1074
1075#ifdef __powerpc__
1076static PyObject *pyxc_alloc_real_mode_area(XcObject *self,
1077                                           PyObject *args,
1078                                           PyObject *kwds)
1079{
1080    uint32_t dom;
1081    unsigned int log;
1082
1083    static char *kwd_list[] = { "dom", "log", NULL };
1084
1085    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, 
1086                                      &dom, &log) )
1087        return NULL;
1088
1089    if ( xc_alloc_real_mode_area(self->xc_handle, dom, log) )
1090        return pyxc_error_to_exception();
1091
1092    Py_INCREF(zero);
1093    return zero;
1094}
1095#endif /* powerpc */
1096
1097static PyMethodDef pyxc_methods[] = {
1098    { "handle",
1099      (PyCFunction)pyxc_handle,
1100      METH_NOARGS, "\n"
1101      "Query the xc control interface file descriptor.\n\n"
1102      "Returns: [int] file descriptor\n" },
1103
1104    { "domain_create", 
1105      (PyCFunction)pyxc_domain_create, 
1106      METH_VARARGS | METH_KEYWORDS, "\n"
1107      "Create a new domain.\n"
1108      " dom    [int, 0]:        Domain identifier to use (allocated if zero).\n"
1109      "Returns: [int] new domain identifier; -1 on error.\n" },
1110
1111    { "domain_max_vcpus", 
1112      (PyCFunction)pyxc_domain_max_vcpus,
1113      METH_VARARGS, "\n"
1114      "Set the maximum number of VCPUs a domain may create.\n"
1115      " dom       [int, 0]:      Domain identifier to use.\n"
1116      " max     [int, 0]:      New maximum number of VCPUs in domain.\n"
1117      "Returns: [int] 0 on success; -1 on error.\n" },
1118
1119    { "domain_dumpcore", 
1120      (PyCFunction)pyxc_domain_dumpcore, 
1121      METH_VARARGS, "\n"
1122      "Dump core of a domain.\n"
1123      " dom [int]: Identifier of domain to dump core of.\n"
1124      " corefile [string]: Name of corefile to be created.\n\n"
1125      "Returns: [int] 0 on success; -1 on error.\n" },
1126
1127    { "domain_pause", 
1128      (PyCFunction)pyxc_domain_pause, 
1129      METH_VARARGS, "\n"
1130      "Temporarily pause execution of a domain.\n"
1131      " dom [int]: Identifier of domain to be paused.\n\n"
1132      "Returns: [int] 0 on success; -1 on error.\n" },
1133
1134    { "domain_unpause", 
1135      (PyCFunction)pyxc_domain_unpause, 
1136      METH_VARARGS, "\n"
1137      "(Re)start execution of a domain.\n"
1138      " dom [int]: Identifier of domain to be unpaused.\n\n"
1139      "Returns: [int] 0 on success; -1 on error.\n" },
1140
1141    { "domain_destroy", 
1142      (PyCFunction)pyxc_domain_destroy, 
1143      METH_VARARGS, "\n"
1144      "Destroy a domain.\n"
1145      " dom [int]:    Identifier of domain to be destroyed.\n\n"
1146      "Returns: [int] 0 on success; -1 on error.\n" },
1147
1148    { "domain_resume", 
1149      (PyCFunction)pyxc_domain_resume,
1150      METH_VARARGS, "\n"
1151      "Resume execution of a suspended domain.\n"
1152      " dom [int]: Identifier of domain to be resumed.\n"
1153      " fast [int]: Use cooperative resume.\n\n"
1154      "Returns: [int] 0 on success; -1 on error.\n" },
1155
1156    { "domain_shutdown", 
1157      (PyCFunction)pyxc_domain_shutdown,
1158      METH_VARARGS, "\n"
1159      "Shutdown a domain.\n"
1160      " dom       [int, 0]:      Domain identifier to use.\n"
1161      " reason     [int, 0]:      Reason for shutdown.\n"
1162      "Returns: [int] 0 on success; -1 on error.\n" },
1163
1164    { "vcpu_setaffinity", 
1165      (PyCFunction)pyxc_vcpu_setaffinity, 
1166      METH_VARARGS | METH_KEYWORDS, "\n"
1167      "Pin a VCPU to a specified set CPUs.\n"
1168      " dom [int]:     Identifier of domain to which VCPU belongs.\n"
1169      " vcpu [int, 0]: VCPU being pinned.\n"
1170      " cpumap [list, []]: list of usable CPUs.\n\n"
1171      "Returns: [int] 0 on success; -1 on error.\n" },
1172
1173    { "domain_setcpuweight", 
1174      (PyCFunction)pyxc_domain_setcpuweight, 
1175      METH_VARARGS | METH_KEYWORDS, "\n"
1176      "Set cpuweight scheduler parameter for domain.\n"
1177      " dom [int]:            Identifier of domain to be changed.\n"
1178      " cpuweight [float, 1]: VCPU being pinned.\n"
1179      "Returns: [int] 0 on success; -1 on error.\n" },
1180
1181    { "domain_sethandle", 
1182      (PyCFunction)pyxc_domain_sethandle,
1183      METH_VARARGS, "\n"
1184      "Set domain's opaque handle.\n"
1185      " dom [int]:            Identifier of domain.\n"
1186      " handle [list of 16 ints]: New opaque handle.\n"
1187      "Returns: [int] 0 on success; -1 on error.\n" },
1188
1189    { "domain_getinfo", 
1190      (PyCFunction)pyxc_domain_getinfo, 
1191      METH_VARARGS | METH_KEYWORDS, "\n"
1192      "Get information regarding a set of domains, in increasing id order.\n"
1193      " first_dom [int, 0]:    First domain to retrieve info about.\n"
1194      " max_doms  [int, 1024]: Maximum number of domains to retrieve info"
1195      " about.\n\n"
1196      "Returns: [list of dicts] if list length is less than 'max_doms'\n"
1197      "         parameter then there was an error, or the end of the\n"
1198      "         domain-id space was reached.\n"
1199      " dom      [int]: Identifier of domain to which this info pertains\n"
1200      " cpu      [int]:  CPU to which this domain is bound\n"
1201      " vcpus    [int]:  Number of Virtual CPUS in this domain\n"
1202      " dying    [int]:  Bool - is the domain dying?\n"
1203      " crashed  [int]:  Bool - has the domain crashed?\n"
1204      " shutdown [int]:  Bool - has the domain shut itself down?\n"
1205      " paused   [int]:  Bool - is the domain paused by control software?\n"
1206      " blocked  [int]:  Bool - is the domain blocked waiting for an event?\n"
1207      " running  [int]:  Bool - is the domain currently running?\n"
1208      " mem_kb   [int]:  Memory reservation, in kilobytes\n"
1209      " maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
1210      " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1211      " shutdown_reason [int]: Numeric code from guest OS, explaining "
1212      "reason why it shut itself down.\n" },
1213
1214    { "vcpu_getinfo", 
1215      (PyCFunction)pyxc_vcpu_getinfo, 
1216      METH_VARARGS | METH_KEYWORDS, "\n"
1217      "Get information regarding a VCPU.\n"
1218      " dom  [int]:    Domain to retrieve info about.\n"
1219      " vcpu [int, 0]: VCPU to retrieve info about.\n\n"
1220      "Returns: [dict]\n"
1221      " online   [int]:  Bool - Is this VCPU currently online?\n"
1222      " blocked  [int]:  Bool - Is this VCPU blocked waiting for an event?\n"
1223      " running  [int]:  Bool - Is this VCPU currently running on a CPU?\n"
1224      " cpu_time [long]: CPU time consumed, in nanoseconds\n"
1225      " cpumap   [int]:  Bitmap of CPUs this VCPU can run on\n"
1226      " cpu      [int]:  CPU that this VCPU is currently bound to\n" },
1227
1228    { "linux_build", 
1229      (PyCFunction)pyxc_linux_build, 
1230      METH_VARARGS | METH_KEYWORDS, "\n"
1231      "Build a new Linux guest OS.\n"
1232      " dom     [int]:      Identifier of domain to build into.\n"
1233      " image   [str]:      Name of kernel image file. May be gzipped.\n"
1234      " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
1235      " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
1236      " vcpus   [int, 1]:   Number of Virtual CPUS in domain.\n\n"
1237      "Returns: [int] 0 on success; -1 on error.\n" },
1238
1239    { "hvm_build", 
1240      (PyCFunction)pyxc_hvm_build, 
1241      METH_VARARGS | METH_KEYWORDS, "\n"
1242      "Build a new HVM guest OS.\n"
1243      " dom     [int]:      Identifier of domain to build into.\n"
1244      " image   [str]:      Name of HVM loader image file.\n"
1245      " vcpus   [int, 1]:   Number of Virtual CPUS in domain.\n\n"
1246      "Returns: [int] 0 on success; -1 on error.\n" },
1247
1248    { "hvm_get_param", 
1249      (PyCFunction)pyxc_get_hvm_param, 
1250      METH_VARARGS | METH_KEYWORDS, "\n"
1251      "get a parameter of HVM guest OS.\n"
1252      " dom     [int]:      Identifier of domain to build into.\n"
1253      " param   [int]:      No. of HVM param.\n"
1254      "Returns: [int] value of the param.\n" },
1255
1256    { "sched_id_get",
1257      (PyCFunction)pyxc_sched_id_get,
1258      METH_NOARGS, "\n"
1259      "Get the current scheduler type in use.\n"
1260      "Returns: [int] sched_id.\n" },   
1261
1262    { "sedf_domain_set",
1263      (PyCFunction)pyxc_sedf_domain_set,
1264      METH_KEYWORDS, "\n"
1265      "Set the scheduling parameters for a domain when running with Atropos.\n"
1266      " dom       [int]:  domain to set\n"
1267      " period    [long]: domain's scheduling period\n"
1268      " slice     [long]: domain's slice per period\n"
1269      " latency   [long]: domain's wakeup latency hint\n"
1270      " extratime [int]:  domain aware of extratime?\n"
1271      "Returns: [int] 0 on success; -1 on error.\n" },
1272
1273    { "sedf_domain_get",
1274      (PyCFunction)pyxc_sedf_domain_get,
1275      METH_VARARGS, "\n"
1276      "Get the current scheduling parameters for a domain when running with\n"
1277      "the Atropos scheduler."
1278      " dom       [int]: domain to query\n"
1279      "Returns:   [dict]\n"
1280      " domain    [int]: domain ID\n"
1281      " period    [long]: scheduler period\n"
1282      " slice     [long]: CPU reservation per period\n"
1283      " latency   [long]: domain's wakeup latency hint\n"
1284      " extratime [int]:  domain aware of extratime?\n"},
1285   
1286    { "sched_credit_domain_set",
1287      (PyCFunction)pyxc_sched_credit_domain_set,
1288      METH_KEYWORDS, "\n"
1289      "Set the scheduling parameters for a domain when running with the\n"
1290      "SMP credit scheduler.\n"
1291      " domid     [int]:   domain id to set\n"
1292      " weight    [short]: domain's scheduling weight\n"
1293      "Returns: [int] 0 on success; -1 on error.\n" },
1294
1295    { "sched_credit_domain_get",
1296      (PyCFunction)pyxc_sched_credit_domain_get,
1297      METH_VARARGS, "\n"
1298      "Get the scheduling parameters for a domain when running with the\n"
1299      "SMP credit scheduler.\n"
1300      " domid     [int]:   domain id to get\n"
1301      "Returns:   [dict]\n"
1302      " weight    [short]: domain's scheduling weight\n"},
1303
1304    { "evtchn_alloc_unbound", 
1305      (PyCFunction)pyxc_evtchn_alloc_unbound,
1306      METH_VARARGS | METH_KEYWORDS, "\n"
1307      "Allocate an unbound port that will await a remote connection.\n"
1308      " dom        [int]: Domain whose port space to allocate from.\n"
1309      " remote_dom [int]: Remote domain to accept connections from.\n\n"
1310      "Returns: [int] Unbound event-channel port.\n" },
1311
1312    { "evtchn_reset", 
1313      (PyCFunction)pyxc_evtchn_reset,
1314      METH_VARARGS | METH_KEYWORDS, "\n"
1315      "Reset all connections.\n"
1316      " dom [int]: Domain to reset.\n" },
1317
1318    { "physdev_pci_access_modify",
1319      (PyCFunction)pyxc_physdev_pci_access_modify,
1320      METH_VARARGS | METH_KEYWORDS, "\n"
1321      "Allow a domain access to a PCI device\n"
1322      " dom    [int]: Identifier of domain to be allowed access.\n"
1323      " bus    [int]: PCI bus\n"
1324      " dev    [int]: PCI slot\n"
1325      " func   [int]: PCI function\n"
1326      " enable [int]: Non-zero means enable access; else disable access\n\n"
1327      "Returns: [int] 0 on success; -1 on error.\n" },
1328 
1329    { "readconsolering", 
1330      (PyCFunction)pyxc_readconsolering, 
1331      METH_VARARGS | METH_KEYWORDS, "\n"
1332      "Read Xen's console ring.\n"
1333      " clear [int, 0]: Bool - clear the ring after reading from it?\n\n"
1334      "Returns: [str] string is empty on failure.\n" },
1335
1336    { "physinfo",
1337      (PyCFunction)pyxc_physinfo,
1338      METH_NOARGS, "\n"
1339      "Get information about the physical host machine\n"
1340      "Returns [dict]: information about the hardware"
1341      "        [None]: on failure.\n" },
1342
1343    { "xeninfo",
1344      (PyCFunction)pyxc_xeninfo,
1345      METH_NOARGS, "\n"
1346      "Get information about the Xen host\n"
1347      "Returns [dict]: information about Xen"
1348      "        [None]: on failure.\n" },
1349
1350    { "shadow_control", 
1351      (PyCFunction)pyxc_shadow_control, 
1352      METH_VARARGS | METH_KEYWORDS, "\n"
1353      "Set parameter for shadow pagetable interface\n"
1354      " dom [int]:   Identifier of domain.\n"
1355      " op [int, 0]: operation\n\n"
1356      "Returns: [int] 0 on success; -1 on error.\n" },
1357
1358    { "shadow_mem_control", 
1359      (PyCFunction)pyxc_shadow_mem_control, 
1360      METH_VARARGS | METH_KEYWORDS, "\n"
1361      "Set or read shadow pagetable memory use\n"
1362      " dom [int]:   Identifier of domain.\n"
1363      " mb [int, -1]: MB of shadow memory this domain should have.\n\n"
1364      "Returns: [int] MB of shadow memory in use by this domain.\n" },
1365
1366    { "domain_setmaxmem", 
1367      (PyCFunction)pyxc_domain_setmaxmem, 
1368      METH_VARARGS, "\n"
1369      "Set a domain's memory limit\n"
1370      " dom [int]: Identifier of domain.\n"
1371      " maxmem_kb [int]: .\n"
1372      "Returns: [int] 0 on success; -1 on error.\n" },
1373
1374    { "domain_set_memmap_limit", 
1375      (PyCFunction)pyxc_domain_set_memmap_limit, 
1376      METH_VARARGS, "\n"
1377      "Set a domain's physical memory mappping limit\n"
1378      " dom [int]: Identifier of domain.\n"
1379      " map_limitkb [int]: .\n"
1380      "Returns: [int] 0 on success; -1 on error.\n" },
1381
1382    { "domain_memory_increase_reservation", 
1383      (PyCFunction)pyxc_domain_memory_increase_reservation, 
1384      METH_VARARGS | METH_KEYWORDS, "\n"
1385      "Increase a domain's memory reservation\n"
1386      " dom [int]: Identifier of domain.\n"
1387      " mem_kb [long]: .\n"
1388      "Returns: [int] 0 on success; -1 on error.\n" },
1389
1390    { "domain_ioport_permission",
1391      (PyCFunction)pyxc_domain_ioport_permission,
1392      METH_VARARGS | METH_KEYWORDS, "\n"
1393      "Allow a domain access to a range of IO ports\n"
1394      " dom          [int]: Identifier of domain to be allowed access.\n"
1395      " first_port   [int]: First IO port\n"
1396      " nr_ports     [int]: Number of IO ports\n"
1397      " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1398      "Returns: [int] 0 on success; -1 on error.\n" },
1399
1400    { "domain_irq_permission",
1401      (PyCFunction)pyxc_domain_irq_permission,
1402      METH_VARARGS | METH_KEYWORDS, "\n"
1403      "Allow a domain access to a physical IRQ\n"
1404      " dom          [int]: Identifier of domain to be allowed access.\n"
1405      " pirq         [int]: The Physical IRQ\n"
1406      " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1407      "Returns: [int] 0 on success; -1 on error.\n" },
1408
1409    { "domain_iomem_permission",
1410      (PyCFunction)pyxc_domain_iomem_permission,
1411      METH_VARARGS | METH_KEYWORDS, "\n"
1412      "Allow a domain access to a range of IO memory pages\n"
1413      " dom          [int]: Identifier of domain to be allowed access.\n"
1414      " first_pfn   [long]: First page of I/O Memory\n"
1415      " nr_pfns     [long]: Number of pages of I/O Memory (>0)\n"
1416      " allow_access [int]: Non-zero means enable access; else disable access\n\n"
1417      "Returns: [int] 0 on success; -1 on error.\n" },
1418
1419    { "pages_to_kib",
1420      (PyCFunction)pyxc_pages_to_kib,
1421      METH_VARARGS, "\n"
1422      "Returns: [int]: The size in KiB of memory spanning the given number "
1423      "of pages.\n" },
1424
1425    { "domain_set_time_offset",
1426      (PyCFunction)pyxc_domain_set_time_offset,
1427      METH_VARARGS, "\n"
1428      "Set a domain's time offset to Dom0's localtime\n"
1429      " dom        [int]: Domain whose time offset is being set.\n"
1430      "Returns: [int] 0 on success; -1 on error.\n" },
1431
1432    { "domain_send_trigger",
1433      (PyCFunction)pyxc_domain_send_trigger,
1434      METH_VARARGS | METH_KEYWORDS, "\n"
1435      "Send trigger to a domain.\n"
1436      " dom     [int]: Identifier of domain to be sent trigger.\n"
1437      " trigger [int]: Trigger type number.\n"
1438      " vcpu    [int]: VCPU to be sent trigger.\n"
1439      "Returns: [int] 0 on success; -1 on error.\n" },
1440
1441    { "send_debug_keys",
1442      (PyCFunction)pyxc_send_debug_keys,
1443      METH_VARARGS | METH_KEYWORDS, "\n"
1444      "Inject debug keys into Xen.\n"
1445      " keys    [str]: String of keys to inject.\n" },
1446
1447#ifdef __powerpc__
1448    { "arch_alloc_real_mode_area", 
1449      (PyCFunction)pyxc_alloc_real_mode_area, 
1450      METH_VARARGS | METH_KEYWORDS, "\n"
1451      "Allocate a domain's real mode area.\n"
1452      " dom [int]: Identifier of domain.\n"
1453      " log [int]: Specifies the area's size.\n"
1454      "Returns: [int] 0 on success; -1 on error.\n" },
1455#endif /* __powerpc */
1456
1457    { NULL, NULL, 0, NULL }
1458};
1459
1460
1461static PyObject *PyXc_getattr(PyObject *obj, char *name)
1462{
1463    return Py_FindMethod(pyxc_methods, obj, name);
1464}
1465
1466static PyObject *PyXc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1467{
1468    XcObject *self = (XcObject *)type->tp_alloc(type, 0);
1469
1470    if (self == NULL)
1471        return NULL;
1472
1473    self->xc_handle = -1;
1474
1475    return (PyObject *)self;
1476}
1477
1478static int
1479PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
1480{
1481    if ((self->xc_handle = xc_interface_open()) == -1) {
1482        pyxc_error_to_exception();
1483        return -1;
1484    }
1485
1486    return 0;
1487}
1488
1489static void PyXc_dealloc(XcObject *self)
1490{
1491    if (self->xc_handle != -1) {
1492        xc_interface_close(self->xc_handle);
1493        self->xc_handle = -1;
1494    }
1495
1496    self->ob_type->tp_free((PyObject *)self);
1497}
1498
1499static PyTypeObject PyXcType = {
1500    PyObject_HEAD_INIT(NULL)
1501    0,
1502    PKG "." CLS,
1503    sizeof(XcObject),
1504    0,
1505    (destructor)PyXc_dealloc,     /* tp_dealloc        */
1506    NULL,                         /* tp_print          */
1507    PyXc_getattr,                 /* tp_getattr        */
1508    NULL,                         /* tp_setattr        */
1509    NULL,                         /* tp_compare        */
1510    NULL,                         /* tp_repr           */
1511    NULL,                         /* tp_as_number      */
1512    NULL,                         /* tp_as_sequence    */
1513    NULL,                         /* tp_as_mapping     */
1514    NULL,                         /* tp_hash           */
1515    NULL,                         /* tp_call           */
1516    NULL,                         /* tp_str            */
1517    NULL,                         /* tp_getattro       */
1518    NULL,                         /* tp_setattro       */
1519    NULL,                         /* tp_as_buffer      */
1520    Py_TPFLAGS_DEFAULT,           /* tp_flags          */
1521    "Xen client connections",     /* tp_doc            */
1522    NULL,                         /* tp_traverse       */
1523    NULL,                         /* tp_clear          */
1524    NULL,                         /* tp_richcompare    */
1525    0,                            /* tp_weaklistoffset */
1526    NULL,                         /* tp_iter           */
1527    NULL,                         /* tp_iternext       */
1528    pyxc_methods,                 /* tp_methods        */
1529    NULL,                         /* tp_members        */
1530    NULL,                         /* tp_getset         */
1531    NULL,                         /* tp_base           */
1532    NULL,                         /* tp_dict           */
1533    NULL,                         /* tp_descr_get      */
1534    NULL,                         /* tp_descr_set      */
1535    0,                            /* tp_dictoffset     */
1536    (initproc)PyXc_init,          /* tp_init           */
1537    NULL,                         /* tp_alloc          */
1538    PyXc_new,                     /* tp_new            */
1539};
1540
1541static PyMethodDef xc_methods[] = { { NULL } };
1542
1543PyMODINIT_FUNC initxc(void)
1544{
1545    PyObject *m;
1546
1547    if (PyType_Ready(&PyXcType) < 0)
1548        return;
1549
1550    m = Py_InitModule(PKG, xc_methods);
1551
1552    if (m == NULL)
1553      return;
1554
1555    xc_error_obj = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
1556    zero = PyInt_FromLong(0);
1557
1558    /* KAF: This ensures that we get debug output in a timely manner. */
1559    setbuf(stdout, NULL);
1560    setbuf(stderr, NULL);
1561
1562    Py_INCREF(&PyXcType);
1563    PyModule_AddObject(m, CLS, (PyObject *)&PyXcType);
1564
1565    Py_INCREF(xc_error_obj);
1566    PyModule_AddObject(m, "Error", xc_error_obj);
1567
1568    /* Expose some libxc constants to Python */
1569    PyModule_AddIntConstant(m, "XEN_SCHEDULER_SEDF", XEN_SCHEDULER_SEDF);
1570    PyModule_AddIntConstant(m, "XEN_SCHEDULER_CREDIT", XEN_SCHEDULER_CREDIT);
1571
1572}
1573
1574
1575/*
1576 * Local variables:
1577 *  c-indent-level: 4
1578 *  c-basic-offset: 4
1579 * End:
1580 */
Note: See TracBrowser for help on using the repository browser.