2 * libvirt-utils.c: misc helper APIs for python binding
4 * Copyright (C) 2013 Red Hat, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see
18 * <http://www.gnu.org/licenses/>.
24 /* Ugly python defines that, which is also defined in errno.h */
25 #undef _POSIC_C_SOURCE
27 /* We want to see *_LAST enums. */
28 #define VIR_ENUM_SENTINELS
34 #include <libvirt/libvirt.h>
35 #include "libvirt-utils.h"
36 #include "typewrappers.h"
40 * @ptrptr: pointer to pointer for address of allocated memory
41 * @size: number of bytes to allocate
43 * Allocate 'size' bytes of memory. Return the address of the
44 * allocated memory in 'ptrptr'. The newly allocated memory is
47 * Returns -1 on failure to allocate, zero on success
50 virAlloc(void *ptrptr
,
53 *(void **)ptrptr
= calloc(1, size
);
54 if (*(void **)ptrptr
== NULL
) {
62 * @ptrptr: pointer to pointer for address of allocated memory
63 * @size: number of bytes to allocate
64 * @count: number of elements to allocate
66 * Allocate an array of memory 'count' elements long,
67 * each with 'size' bytes. Return the address of the
68 * allocated memory in 'ptrptr'. The newly allocated
69 * memory is filled with zeros.
71 * Returns -1 on failure to allocate, zero on success
74 virAllocN(void *ptrptr
,
78 *(void**)ptrptr
= calloc(count
, size
);
79 if (*(void**)ptrptr
== NULL
) {
87 * @ptrptr: pointer to pointer for address of allocated memory
88 * @size: number of bytes to allocate
89 * @count: number of elements in array
91 * Resize the block of memory in 'ptrptr' to be an array of
92 * 'count' elements, each 'size' bytes in length. Update 'ptrptr'
93 * with the address of the newly allocated memory. On failure,
94 * 'ptrptr' is not changed and still points to the original memory
95 * block. Any newly allocated memory in 'ptrptr' is uninitialized.
97 * Returns -1 on failure to allocate, zero on success
100 virReallocN(void *ptrptr
,
106 if (xalloc_oversized(count
, size
)) {
110 tmp
= realloc(*(void**)ptrptr
, size
* count
);
111 if (!tmp
&& ((size
* count
) != 0)) {
114 *(void**)ptrptr
= tmp
;
121 * @ptrptr: pointer to pointer for address of memory to be freed
123 * Release the chunk of memory in the pointer pointed to by
124 * the 'ptrptr' variable. After release, 'ptrptr' will be
125 * updated to point to NULL.
128 virFree(void *ptrptr
)
130 int save_errno
= errno
;
132 free(*(void**)ptrptr
);
133 *(void**)ptrptr
= NULL
;
139 virFileClose(int *fdptr
)
157 #if ! LIBVIR_CHECK_VERSION(1, 0, 2)
159 * virTypedParamsClear:
160 * @params: the array of the typed parameters
161 * @nparams: number of parameters in the @params array
163 * Frees all memory used by string parameters. The memory occupied by @params
164 * is not free; use virTypedParamsFree if you want it to be freed too.
169 virTypedParamsClear(virTypedParameterPtr params
,
177 for (i
= 0; i
< nparams
; i
++) {
178 if (params
[i
].type
== VIR_TYPED_PARAM_STRING
)
179 VIR_FREE(params
[i
].value
.s
);
184 * virTypedParamsFree:
185 * @params: the array of the typed parameters
186 * @nparams: number of parameters in the @params array
188 * Frees all memory used by string parameters and the memory occuiped by
194 virTypedParamsFree(virTypedParameterPtr params
,
197 virTypedParamsClear(params
, nparams
);
200 #endif /* ! LIBVIR_CHECK_VERSION(1, 0, 2) */
202 /* Helper function to convert a virTypedParameter output array into a
203 * Python dictionary for return to the user. Return NULL on failure,
204 * after raising a python exception. */
206 getPyVirTypedParameter(const virTypedParameter
*params
,
209 PyObject
*key
, *val
, *info
;
212 if ((info
= PyDict_New()) == NULL
)
215 for (i
= 0; i
< nparams
; i
++) {
216 switch (params
[i
].type
) {
217 case VIR_TYPED_PARAM_INT
:
218 val
= libvirt_intWrap(params
[i
].value
.i
);
221 case VIR_TYPED_PARAM_UINT
:
222 val
= libvirt_intWrap(params
[i
].value
.ui
);
225 case VIR_TYPED_PARAM_LLONG
:
226 val
= libvirt_longlongWrap(params
[i
].value
.l
);
229 case VIR_TYPED_PARAM_ULLONG
:
230 val
= libvirt_ulonglongWrap(params
[i
].value
.ul
);
233 case VIR_TYPED_PARAM_DOUBLE
:
234 val
= PyFloat_FromDouble(params
[i
].value
.d
);
237 case VIR_TYPED_PARAM_BOOLEAN
:
238 val
= PyBool_FromLong(params
[i
].value
.b
);
241 case VIR_TYPED_PARAM_STRING
:
242 val
= libvirt_constcharPtrWrap(params
[i
].value
.s
);
246 /* Possible if a newer server has a bug and sent stuff we
247 * don't recognize. */
248 PyErr_Format(PyExc_LookupError
,
249 "Type value \"%d\" not recognized",
255 key
= libvirt_constcharPtrWrap(params
[i
].field
);
257 VIR_PY_DICT_SET_GOTO(info
, key
, val
, cleanup
);
266 /* Allocate a new typed parameter array with the same contents and
267 * length as info, and using the array params of length nparams as
268 * hints on what types to use when creating the new array. The caller
269 * must clear the array before freeing it. Return NULL on failure,
270 * after raising a python exception. */
272 setPyVirTypedParameter(PyObject
*info
,
273 const virTypedParameter
*params
,
276 PyObject
*key
, *value
;
277 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 4
282 virTypedParameterPtr temp
= NULL
, ret
= NULL
;
286 if ((size
= PyDict_Size(info
)) < 0)
289 /* Libvirt APIs use NULL array and 0 size as a special case;
290 * setting should have at least one parameter. */
292 PyErr_Format(PyExc_LookupError
, "Dictionary must not be empty");
296 if (VIR_ALLOC_N(ret
, size
) < 0) {
302 while (PyDict_Next(info
, &pos
, &key
, &value
)) {
305 if (libvirt_charPtrUnwrap(key
, &keystr
) < 0)
308 for (i
= 0; i
< nparams
; i
++) {
309 if (STREQ(params
[i
].field
, keystr
))
313 PyErr_Format(PyExc_LookupError
,
314 "Attribute name \"%s\" could not be recognized",
320 strncpy(temp
->field
, keystr
, VIR_TYPED_PARAM_FIELD_LENGTH
- 1);
321 temp
->type
= params
[i
].type
;
324 switch (params
[i
].type
) {
325 case VIR_TYPED_PARAM_INT
:
326 if (libvirt_intUnwrap(value
, &temp
->value
.i
) < 0)
330 case VIR_TYPED_PARAM_UINT
:
331 if (libvirt_uintUnwrap(value
, &temp
->value
.ui
) < 0)
335 case VIR_TYPED_PARAM_LLONG
:
336 if (libvirt_longlongUnwrap(value
, &temp
->value
.l
) < 0)
340 case VIR_TYPED_PARAM_ULLONG
:
341 if (libvirt_ulonglongUnwrap(value
, &temp
->value
.ul
) < 0)
345 case VIR_TYPED_PARAM_DOUBLE
:
346 if (libvirt_doubleUnwrap(value
, &temp
->value
.d
) < 0)
350 case VIR_TYPED_PARAM_BOOLEAN
:
353 if (libvirt_boolUnwrap(value
, &b
) < 0)
358 case VIR_TYPED_PARAM_STRING
:
361 if (libvirt_charPtrUnwrap(value
, &string_val
) < 0)
363 temp
->value
.s
= string_val
;
368 /* Possible if a newer server has a bug and sent stuff we
369 * don't recognize. */
370 PyErr_Format(PyExc_LookupError
,
371 "Type value \"%d\" not recognized",
381 virTypedParamsFree(ret
, size
);
386 /* While these appeared in libvirt in 1.0.2, we only
387 * need them in the python from 1.1.0 onwards */
388 #if LIBVIR_CHECK_VERSION(1, 1, 0)
390 virPyDictToTypedParamOne(virTypedParameterPtr
*params
,
393 virPyTypedParamsHintPtr hints
,
398 int rv
= -1, type
= -1;
401 for (i
= 0; i
< nhints
; i
++) {
402 if (STREQ(hints
[i
].name
, keystr
)) {
403 type
= hints
[i
].type
;
409 if (libvirt_PyString_Check(value
)) {
410 type
= VIR_TYPED_PARAM_STRING
;
411 } else if (PyBool_Check(value
)) {
412 type
= VIR_TYPED_PARAM_BOOLEAN
;
413 } else if (PyLong_Check(value
)) {
414 unsigned long long ull
= PyLong_AsUnsignedLongLong(value
);
415 if (ull
== (unsigned long long) -1 && PyErr_Occurred())
416 type
= VIR_TYPED_PARAM_LLONG
;
418 type
= VIR_TYPED_PARAM_ULLONG
;
419 #if PY_MAJOR_VERSION < 3
420 } else if (PyInt_Check(value
)) {
421 if (PyInt_AS_LONG(value
) < 0)
422 type
= VIR_TYPED_PARAM_LLONG
;
424 type
= VIR_TYPED_PARAM_ULLONG
;
426 } else if (PyFloat_Check(value
)) {
427 type
= VIR_TYPED_PARAM_DOUBLE
;
432 PyErr_Format(PyExc_TypeError
,
433 "Unknown type of \"%s\" field", keystr
);
437 switch ((virTypedParameterType
) type
) {
438 case VIR_TYPED_PARAM_INT
:
441 if (libvirt_intUnwrap(value
, &val
) < 0 ||
442 virTypedParamsAddInt(params
, n
, max
, keystr
, val
) < 0)
446 case VIR_TYPED_PARAM_UINT
:
449 if (libvirt_uintUnwrap(value
, &val
) < 0 ||
450 virTypedParamsAddUInt(params
, n
, max
, keystr
, val
) < 0)
454 case VIR_TYPED_PARAM_LLONG
:
457 if (libvirt_longlongUnwrap(value
, &val
) < 0 ||
458 virTypedParamsAddLLong(params
, n
, max
, keystr
, val
) < 0)
462 case VIR_TYPED_PARAM_ULLONG
:
464 unsigned long long val
;
465 if (libvirt_ulonglongUnwrap(value
, &val
) < 0 ||
466 virTypedParamsAddULLong(params
, n
, max
, keystr
, val
) < 0)
470 case VIR_TYPED_PARAM_DOUBLE
:
473 if (libvirt_doubleUnwrap(value
, &val
) < 0 ||
474 virTypedParamsAddDouble(params
, n
, max
, keystr
, val
) < 0)
478 case VIR_TYPED_PARAM_BOOLEAN
:
481 if (libvirt_boolUnwrap(value
, &val
) < 0 ||
482 virTypedParamsAddBoolean(params
, n
, max
, keystr
, val
) < 0)
486 case VIR_TYPED_PARAM_STRING
:
489 if (libvirt_charPtrUnwrap(value
, &val
) < 0 ||
490 virTypedParamsAddString(params
, n
, max
, keystr
, val
) < 0) {
497 case VIR_TYPED_PARAM_LAST
:
498 break; /* unreachable */
508 /* Automatically convert dict into type parameters based on types reported
509 * by python. All integer types are converted into LLONG (in case of a negative
510 * value) or ULLONG (in case of a positive value). If you need different
511 * handling, use @hints to explicitly specify what types should be used for
512 * specific parameters.
515 virPyDictToTypedParams(PyObject
*dict
,
516 virTypedParameterPtr
*ret_params
,
518 virPyTypedParamsHintPtr hints
,
523 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 4
528 virTypedParameterPtr params
= NULL
;
537 if (PyDict_Size(dict
) < 0)
540 while (PyDict_Next(dict
, &pos
, &key
, &value
)) {
541 if (libvirt_charPtrUnwrap(key
, &keystr
) < 0)
544 if (PyList_Check(value
) || PyTuple_Check(value
)) {
545 Py_ssize_t i
, size
= PySequence_Size(value
);
547 for (i
= 0; i
< size
; i
++) {
548 PyObject
*v
= PySequence_ITEM(value
, i
);
549 if (virPyDictToTypedParamOne(¶ms
, &n
, &max
,
550 hints
, nhints
, keystr
, v
) < 0)
553 } else if (virPyDictToTypedParamOne(¶ms
, &n
, &max
,
554 hints
, nhints
, keystr
, value
) < 0)
560 *ret_params
= params
;
567 virTypedParamsFree(params
, n
);
570 #endif /* LIBVIR_CHECK_VERSION(1, 1, 0) */
573 /* virPyCpumapConvert
574 * @cpunum: the number of physical cpus of the host.
575 * @pycpumap: source cpu map, python tuple of bools.
576 * @cpumapptr: destination cpu map.
577 * @cpumaplen: destination cpu map length.
579 * Helper function to convert a pycpumap to char*.
581 * Returns 0 on success, -1 on failure with error set.
584 virPyCpumapConvert(int cpunum
,
586 unsigned char **cpumapptr
,
593 if (!PyTuple_Check(pycpumap
)) {
594 PyErr_SetString(PyExc_TypeError
, "Unexpected type, tuple is required");
598 *cpumaplen
= VIR_CPU_MAPLEN(cpunum
);
600 if ((tuple_size
= PyTuple_Size(pycpumap
)) == -1)
603 if (VIR_ALLOC_N(*cpumapptr
, *cpumaplen
) < 0) {
608 for (i
= 0; i
< cpunum
&& i
< tuple_size
; i
++) {
609 PyObject
*flag
= PyTuple_GetItem(pycpumap
, i
);
612 if (!flag
|| libvirt_boolUnwrap(flag
, &b
) < 0) {
613 VIR_FREE(*cpumapptr
);
618 VIR_USE_CPU(*cpumapptr
, i
);