mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-02 01:45:17 +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.'/>
|
||||
<return type='unsigned long' info='current max migration speed, or None in case of error'/>
|
||||
</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'>
|
||||
<info>Change the I/O tunables for a block device</info>
|
||||
<arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
|
||||
|
@ -258,6 +258,160 @@ cleanup:
|
||||
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.
|
||||
* It first tries virGetNodeCPUMap, which will return the
|
||||
@ -6494,6 +6648,68 @@ libvirt_virDomainMigrateGetMaxSpeed(PyObject *self ATTRIBUTE_UNUSED, PyObject *a
|
||||
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 *
|
||||
libvirt_virDomainBlockPeek(PyObject *self ATTRIBUTE_UNUSED,
|
||||
PyObject *args) {
|
||||
@ -6876,6 +7092,8 @@ static PyMethodDef libvirtMethods[] = {
|
||||
{(char *) "virDomainSendKey", libvirt_virDomainSendKey, METH_VARARGS, NULL},
|
||||
{(char *) "virDomainMigrateGetCompressionCache", libvirt_virDomainMigrateGetCompressionCache, 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 *) "virDomainMemoryPeek", libvirt_virDomainMemoryPeek, METH_VARARGS, NULL},
|
||||
{(char *) "virDomainGetDiskErrors", libvirt_virDomainGetDiskErrors, METH_VARARGS, NULL},
|
||||
|
Loading…
x
Reference in New Issue
Block a user