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 | |
---|
36 | static PyObject *xc_error_obj, *zero; |
---|
37 | |
---|
38 | typedef struct { |
---|
39 | PyObject_HEAD; |
---|
40 | int xc_handle; |
---|
41 | } XcObject; |
---|
42 | |
---|
43 | |
---|
44 | static PyObject *dom_op(XcObject *self, PyObject *args, |
---|
45 | int (*fn)(int, uint32_t)); |
---|
46 | |
---|
47 | static 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 | |
---|
72 | static 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 | |
---|
90 | static PyObject *pyxc_handle(XcObject *self) |
---|
91 | { |
---|
92 | return PyInt_FromLong(self->xc_handle); |
---|
93 | } |
---|
94 | |
---|
95 | static 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 | |
---|
136 | out_exception: |
---|
137 | errno = EINVAL; |
---|
138 | PyErr_SetFromErrno(xc_error_obj); |
---|
139 | return NULL; |
---|
140 | } |
---|
141 | |
---|
142 | static 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 | |
---|
156 | static PyObject *pyxc_domain_pause(XcObject *self, PyObject *args) |
---|
157 | { |
---|
158 | return dom_op(self, args, xc_domain_pause); |
---|
159 | } |
---|
160 | |
---|
161 | static PyObject *pyxc_domain_unpause(XcObject *self, PyObject *args) |
---|
162 | { |
---|
163 | return dom_op(self, args, xc_domain_unpause); |
---|
164 | } |
---|
165 | |
---|
166 | static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args) |
---|
167 | { |
---|
168 | return dom_op(self, args, xc_domain_destroy); |
---|
169 | } |
---|
170 | |
---|
171 | static 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 | |
---|
185 | static 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 | |
---|
200 | static 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 | |
---|
229 | static 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 | |
---|
249 | static 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 | |
---|
279 | out_exception: |
---|
280 | PyErr_SetFromErrno(xc_error_obj); |
---|
281 | return NULL; |
---|
282 | } |
---|
283 | |
---|
284 | |
---|
285 | static 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 | |
---|
353 | static 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 | |
---|
396 | static 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 | |
---|
470 | static 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, ¶m) ) |
---|
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 | |
---|
490 | static 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 | |
---|
545 | static 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 | |
---|
564 | static 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 | |
---|
582 | static 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 | |
---|
604 | static 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 | |
---|
626 | static unsigned long pages_to_kib(unsigned long pages) |
---|
627 | { |
---|
628 | return pages * (XC_PAGE_SIZE / 1024); |
---|
629 | } |
---|
630 | |
---|
631 | |
---|
632 | static 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 | |
---|
643 | static 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 | |
---|
674 | static 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 | |
---|
723 | static 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 | |
---|
745 | static 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 | |
---|
767 | static 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 | |
---|
790 | static 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 | |
---|
820 | static 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 | |
---|
829 | static 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 | |
---|
856 | static 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 | |
---|
872 | static 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 | |
---|
887 | static 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 | |
---|
902 | static 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 | |
---|
929 | static 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 | |
---|
951 | static 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 | |
---|
974 | static 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 | |
---|
997 | static 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 | |
---|
1022 | static 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 | |
---|
1042 | static 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 | |
---|
1060 | static 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__ |
---|
1076 | static 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 | |
---|
1097 | static 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 | |
---|
1461 | static PyObject *PyXc_getattr(PyObject *obj, char *name) |
---|
1462 | { |
---|
1463 | return Py_FindMethod(pyxc_methods, obj, name); |
---|
1464 | } |
---|
1465 | |
---|
1466 | static 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 | |
---|
1478 | static int |
---|
1479 | PyXc_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 | |
---|
1489 | static 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 | |
---|
1499 | static 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 | |
---|
1541 | static PyMethodDef xc_methods[] = { { NULL } }; |
---|
1542 | |
---|
1543 | PyMODINIT_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 | */ |
---|