mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-07-30 21:47:18 +00:00
python: Add bindings for extensible migration APIs
The patch implements wrappers for virDomainMigrate3 and virDomainMigrateToURI3.
This commit is contained in:
parent
4bf62f44a9
commit
6f4c6af6ed
@ -527,6 +527,24 @@
|
|||||||
<arg name='flags' type='unsigned int' info='flags, currently unused, pass 0.'/>
|
<arg name='flags' type='unsigned int' info='flags, currently unused, pass 0.'/>
|
||||||
<return type='unsigned long' info='current max migration speed, or None in case of error'/>
|
<return type='unsigned long' info='current max migration speed, or None in case of error'/>
|
||||||
</function>
|
</function>
|
||||||
|
<function name='virDomainMigrate3' file='python'>
|
||||||
|
<info>Migrate the domain object from its current host to the destination host
|
||||||
|
given by dconn (a connection to the destination host).</info>
|
||||||
|
<arg name='domain' type='virDomainPtr' info='a domain object'/>
|
||||||
|
<arg name='dconn' type='virConnectPtr' info='pointer to the destination host connection'/>
|
||||||
|
<arg name='params' type='char *' info='dictionary with migration parameters'/>
|
||||||
|
<arg name='flags' type='unsigned int' info='an OR'ed set of virDomainMigrateFlags'/>
|
||||||
|
<return type='virDomainPtr' info='a new domain object or NULL in case of failure'/>
|
||||||
|
</function>
|
||||||
|
<function name='virDomainMigrateToURI3' file='python'>
|
||||||
|
<info>Migrate the domain object from its current host to the destination host
|
||||||
|
given by URI.</info>
|
||||||
|
<arg name='domain' type='virDomainPtr' info='a domain object'/>
|
||||||
|
<arg name='dconnuri' type='virConnectPtr' info='URI for target libvirtd if @flags includes VIR_MIGRATE_PEER2PEER'/>
|
||||||
|
<arg name='params' type='char *' info='dictionary with migration parameters'/>
|
||||||
|
<arg name='flags' type='unsigned int' info='an OR'ed set of virDomainMigrateFlags'/>
|
||||||
|
<return type='int' info='0 in case of success, -1 in case of failure.'/>
|
||||||
|
</function>
|
||||||
<function name='virDomainSetBlockIoTune' file='python'>
|
<function name='virDomainSetBlockIoTune' file='python'>
|
||||||
<info>Change the I/O tunables for a block device</info>
|
<info>Change the I/O tunables for a block device</info>
|
||||||
<arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
|
<arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
|
||||||
|
@ -258,6 +258,160 @@ cleanup:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *name;
|
||||||
|
int type;
|
||||||
|
} virPyTypedParamsHint;
|
||||||
|
typedef virPyTypedParamsHint *virPyTypedParamsHintPtr;
|
||||||
|
|
||||||
|
/* Automatically convert dict into type parameters based on types reported
|
||||||
|
* by python. All integer types are converted into LLONG (in case of a negative
|
||||||
|
* value) or ULLONG (in case of a positive value). If you need different
|
||||||
|
* handling, use @hints to explicitly specify what types should be used for
|
||||||
|
* specific parameters.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
|
||||||
|
virPyDictToTypedParams(PyObject *dict,
|
||||||
|
virTypedParameterPtr *ret_params,
|
||||||
|
int *ret_nparams,
|
||||||
|
virPyTypedParamsHintPtr hints,
|
||||||
|
int nhints)
|
||||||
|
{
|
||||||
|
PyObject *key;
|
||||||
|
PyObject *value;
|
||||||
|
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 4
|
||||||
|
int pos = 0;
|
||||||
|
#else
|
||||||
|
Py_ssize_t pos = 0;
|
||||||
|
#endif
|
||||||
|
virTypedParameterPtr params = NULL;
|
||||||
|
int i;
|
||||||
|
int n = 0;
|
||||||
|
int max = 0;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
*ret_params = NULL;
|
||||||
|
*ret_nparams = 0;
|
||||||
|
|
||||||
|
if (PyDict_Size(dict) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
while (PyDict_Next(dict, &pos, &key, &value)) {
|
||||||
|
char *keystr;
|
||||||
|
int type = -1;
|
||||||
|
|
||||||
|
if (!(keystr = PyString_AsString(key)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
for (i = 0; i < nhints; i++) {
|
||||||
|
if (STREQ(hints[i].name, keystr)) {
|
||||||
|
type = hints[i].type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == -1) {
|
||||||
|
if (PyString_Check(value)) {
|
||||||
|
type = VIR_TYPED_PARAM_STRING;
|
||||||
|
} else if (PyBool_Check(value)) {
|
||||||
|
type = VIR_TYPED_PARAM_BOOLEAN;
|
||||||
|
} else if (PyLong_Check(value)) {
|
||||||
|
unsigned long long ull = PyLong_AsUnsignedLongLong(value);
|
||||||
|
if (ull == (unsigned long long) -1 && PyErr_Occurred())
|
||||||
|
type = VIR_TYPED_PARAM_LLONG;
|
||||||
|
else
|
||||||
|
type = VIR_TYPED_PARAM_ULLONG;
|
||||||
|
} else if (PyInt_Check(value)) {
|
||||||
|
if (PyInt_AS_LONG(value) < 0)
|
||||||
|
type = VIR_TYPED_PARAM_LLONG;
|
||||||
|
else
|
||||||
|
type = VIR_TYPED_PARAM_ULLONG;
|
||||||
|
} else if (PyFloat_Check(value)) {
|
||||||
|
type = VIR_TYPED_PARAM_DOUBLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == -1) {
|
||||||
|
PyErr_Format(PyExc_TypeError,
|
||||||
|
"Unknown type of \"%s\" field", keystr);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ((virTypedParameterType) type) {
|
||||||
|
case VIR_TYPED_PARAM_INT:
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
if (libvirt_intUnwrap(value, &val) < 0 ||
|
||||||
|
virTypedParamsAddInt(¶ms, &n, &max, keystr, val) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VIR_TYPED_PARAM_UINT:
|
||||||
|
{
|
||||||
|
unsigned int val;
|
||||||
|
if (libvirt_uintUnwrap(value, &val) < 0 ||
|
||||||
|
virTypedParamsAddUInt(¶ms, &n, &max, keystr, val) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VIR_TYPED_PARAM_LLONG:
|
||||||
|
{
|
||||||
|
long long val;
|
||||||
|
if (libvirt_longlongUnwrap(value, &val) < 0 ||
|
||||||
|
virTypedParamsAddLLong(¶ms, &n, &max, keystr, val) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VIR_TYPED_PARAM_ULLONG:
|
||||||
|
{
|
||||||
|
unsigned long long val;
|
||||||
|
if (libvirt_ulonglongUnwrap(value, &val) < 0 ||
|
||||||
|
virTypedParamsAddULLong(¶ms, &n, &max, keystr, val) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VIR_TYPED_PARAM_DOUBLE:
|
||||||
|
{
|
||||||
|
double val;
|
||||||
|
if (libvirt_doubleUnwrap(value, &val) < 0 ||
|
||||||
|
virTypedParamsAddDouble(¶ms, &n, &max, keystr, val) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VIR_TYPED_PARAM_BOOLEAN:
|
||||||
|
{
|
||||||
|
bool val;
|
||||||
|
if (libvirt_boolUnwrap(value, &val) < 0 ||
|
||||||
|
virTypedParamsAddBoolean(¶ms, &n, &max, keystr, val) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VIR_TYPED_PARAM_STRING:
|
||||||
|
{
|
||||||
|
char *val = PyString_AsString(value);
|
||||||
|
if (!val ||
|
||||||
|
virTypedParamsAddString(¶ms, &n, &max, keystr, val) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VIR_TYPED_PARAM_LAST:
|
||||||
|
break; /* unreachable */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret_params = params;
|
||||||
|
*ret_nparams = n;
|
||||||
|
params = NULL;
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virTypedParamsFree(params, n);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility function to retrieve the number of node CPUs present.
|
* Utility function to retrieve the number of node CPUs present.
|
||||||
* It first tries virGetNodeCPUMap, which will return the
|
* It first tries virGetNodeCPUMap, which will return the
|
||||||
@ -6494,6 +6648,68 @@ libvirt_virDomainMigrateGetMaxSpeed(PyObject *self ATTRIBUTE_UNUSED, PyObject *a
|
|||||||
return py_retval;
|
return py_retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
libvirt_virDomainMigrate3(PyObject *self ATTRIBUTE_UNUSED,
|
||||||
|
PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *pyobj_domain;
|
||||||
|
virDomainPtr domain;
|
||||||
|
PyObject *pyobj_dconn;
|
||||||
|
virConnectPtr dconn;
|
||||||
|
PyObject *dict;
|
||||||
|
unsigned int flags;
|
||||||
|
virTypedParameterPtr params;
|
||||||
|
int nparams;
|
||||||
|
virDomainPtr ddom = NULL;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, (char *) "OOOi:virDomainMigrate3",
|
||||||
|
&pyobj_domain, &pyobj_dconn, &dict, &flags))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
|
||||||
|
dconn = (virConnectPtr) PyvirConnect_Get(pyobj_dconn);
|
||||||
|
|
||||||
|
if (virPyDictToTypedParams(dict, ¶ms, &nparams, NULL, 0) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
LIBVIRT_BEGIN_ALLOW_THREADS;
|
||||||
|
ddom = virDomainMigrate3(domain, dconn, params, nparams, flags);
|
||||||
|
LIBVIRT_END_ALLOW_THREADS;
|
||||||
|
|
||||||
|
virTypedParamsFree(params, nparams);
|
||||||
|
return libvirt_virDomainPtrWrap(ddom);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
libvirt_virDomainMigrateToURI3(PyObject *self ATTRIBUTE_UNUSED,
|
||||||
|
PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *pyobj_domain;
|
||||||
|
virDomainPtr domain;
|
||||||
|
char *dconnuri;
|
||||||
|
PyObject *dict;
|
||||||
|
unsigned int flags;
|
||||||
|
virTypedParameterPtr params;
|
||||||
|
int nparams;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, (char *) "OzOi:virDomainMigrate3",
|
||||||
|
&pyobj_domain, &dconnuri, &dict, &flags))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
|
||||||
|
|
||||||
|
if (virPyDictToTypedParams(dict, ¶ms, &nparams, NULL, 0) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
LIBVIRT_BEGIN_ALLOW_THREADS;
|
||||||
|
ret = virDomainMigrateToURI3(domain, dconnuri, params, nparams, flags);
|
||||||
|
LIBVIRT_END_ALLOW_THREADS;
|
||||||
|
|
||||||
|
virTypedParamsFree(params, nparams);
|
||||||
|
return libvirt_intWrap(ret);
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
libvirt_virDomainBlockPeek(PyObject *self ATTRIBUTE_UNUSED,
|
libvirt_virDomainBlockPeek(PyObject *self ATTRIBUTE_UNUSED,
|
||||||
PyObject *args) {
|
PyObject *args) {
|
||||||
@ -6876,6 +7092,8 @@ static PyMethodDef libvirtMethods[] = {
|
|||||||
{(char *) "virDomainSendKey", libvirt_virDomainSendKey, METH_VARARGS, NULL},
|
{(char *) "virDomainSendKey", libvirt_virDomainSendKey, METH_VARARGS, NULL},
|
||||||
{(char *) "virDomainMigrateGetCompressionCache", libvirt_virDomainMigrateGetCompressionCache, METH_VARARGS, NULL},
|
{(char *) "virDomainMigrateGetCompressionCache", libvirt_virDomainMigrateGetCompressionCache, METH_VARARGS, NULL},
|
||||||
{(char *) "virDomainMigrateGetMaxSpeed", libvirt_virDomainMigrateGetMaxSpeed, METH_VARARGS, NULL},
|
{(char *) "virDomainMigrateGetMaxSpeed", libvirt_virDomainMigrateGetMaxSpeed, METH_VARARGS, NULL},
|
||||||
|
{(char *) "virDomainMigrate3", libvirt_virDomainMigrate3, METH_VARARGS, NULL},
|
||||||
|
{(char *) "virDomainMigrateToURI3", libvirt_virDomainMigrateToURI3, METH_VARARGS, NULL},
|
||||||
{(char *) "virDomainBlockPeek", libvirt_virDomainBlockPeek, METH_VARARGS, NULL},
|
{(char *) "virDomainBlockPeek", libvirt_virDomainBlockPeek, METH_VARARGS, NULL},
|
||||||
{(char *) "virDomainMemoryPeek", libvirt_virDomainMemoryPeek, METH_VARARGS, NULL},
|
{(char *) "virDomainMemoryPeek", libvirt_virDomainMemoryPeek, METH_VARARGS, NULL},
|
||||||
{(char *) "virDomainGetDiskErrors", libvirt_virDomainGetDiskErrors, METH_VARARGS, NULL},
|
{(char *) "virDomainGetDiskErrors", libvirt_virDomainGetDiskErrors, METH_VARARGS, NULL},
|
||||||
|
Loading…
Reference in New Issue
Block a user