diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 32c36f1b8d5d983b1b16f74b6e64fe12ef4361a1..01dc3a7302e66de44bfae9e4c087e6e5ff022189 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1575,6 +1575,11 @@ virConnectPtr virDomainGetConnect (virDomainPtr domain); virDomainPtr virDomainCreateXML (virConnectPtr conn, const char *xmlDesc, unsigned int flags); +virDomainPtr virDomainCreateXMLWithFiles(virConnectPtr conn, + const char *xmlDesc, + unsigned int nfiles, + int *files, + unsigned int flags); virDomainPtr virDomainLookupByName (virConnectPtr conn, const char *name); virDomainPtr virDomainLookupByID (virConnectPtr conn, @@ -2178,6 +2183,11 @@ int virDomainCreate (virDomainPtr domain); int virDomainCreateWithFlags (virDomainPtr domain, unsigned int flags); +int virDomainCreateWithFiles (virDomainPtr domain, + unsigned int nfiles, + int *files, + unsigned int flags); + int virDomainGetAutostart (virDomainPtr domain, int *autostart); int virDomainSetAutostart (virDomainPtr domain, diff --git a/python/generator.py b/python/generator.py index da642eb677bb0d9b0acdf7b6357b18ee32860e56..427cebce3888d438d4ca9391141533d3f33c9eef 100755 --- a/python/generator.py +++ b/python/generator.py @@ -513,6 +513,9 @@ skip_function = ( 'virConnectUnregisterCloseCallback', # overriden in virConnect.py 'virConnectRegisterCloseCallback', # overriden in virConnect.py + 'virDomainCreateXMLWithFiles', # overriden in virConnect.py + 'virDomainCreateWithFiles', # overriden in virDomain.py + # 'Ref' functions have no use for bindings users. "virConnectRef", "virDomainRef", diff --git a/python/libvirt-override-virConnect.py b/python/libvirt-override-virConnect.py index 5495b70f267f49fbe92ba162d5c12ca54e4dc435..a0f579d56e095b239fcb80f56bd1a5390b0481c6 100644 --- a/python/libvirt-override-virConnect.py +++ b/python/libvirt-override-virConnect.py @@ -310,3 +310,33 @@ if ret == -1: raise libvirtError ('virConnectRegisterCloseCallback() failed', conn=self) return ret + + def createXMLWithFiles(self, xmlDesc, files, flags=0): + """Launch a new guest domain, based on an XML description similar + to the one returned by virDomainGetXMLDesc() + This function may require privileged access to the hypervisor. + The domain is not persistent, so its definition will disappear when it + is destroyed, or if the host is restarted (see virDomainDefineXML() to + define persistent domains). + + @files provides an array of file descriptors which will be + made available to the 'init' process of the guest. The file + handles exposed to the guest will be renumbered to start + from 3 (ie immediately following stderr). This is only + supported for guests which use container based virtualization + technology. + + If the VIR_DOMAIN_START_PAUSED flag is set, the guest domain + will be started, but its CPUs will remain paused. The CPUs + can later be manually started using virDomainResume. + + If the VIR_DOMAIN_START_AUTODESTROY flag is set, the guest + domain will be automatically destroyed when the virConnectPtr + object is finally released. This will also happen if the + client application crashes / loses its connection to the + libvirtd daemon. Any domains marked for auto destroy will + block attempts at migration, save-to-file, or snapshots. """ + ret = libvirtmod.virDomainCreateXMLWithFiles(self._o, xmlDesc, files, flags) + if ret is None:raise libvirtError('virDomainCreateXMLWithFiles() failed', conn=self) + __tmp = virDomain(self,_obj=ret) + return __tmp diff --git a/python/libvirt-override-virDomain.py b/python/libvirt-override-virDomain.py index 142b1d461783eefe7ba856c5659eb3a64a1fa3ef..c96cc5e0002c372f2d869369be5e6f62fb2b2635 100644 --- a/python/libvirt-override-virDomain.py +++ b/python/libvirt-override-virDomain.py @@ -9,3 +9,41 @@ retlist.append(virDomainSnapshot(self, _obj=snapptr)) return retlist + + + def createWithFiles(self, files, flags=0): + """Launch a defined domain. If the call succeeds the domain moves from the + defined to the running domains pools. + + @files provides an array of file descriptors which will be + made available to the 'init' process of the guest. The file + handles exposed to the guest will be renumbered to start + from 3 (ie immediately following stderr). This is only + supported for guests which use container based virtualization + technology. + + If the VIR_DOMAIN_START_PAUSED flag is set, or if the guest domain + has a managed save image that requested paused state (see + virDomainManagedSave()) the guest domain will be started, but its + CPUs will remain paused. The CPUs can later be manually started + using virDomainResume(). In all other cases, the guest domain will + be running. + + If the VIR_DOMAIN_START_AUTODESTROY flag is set, the guest + domain will be automatically destroyed when the virConnectPtr + object is finally released. This will also happen if the + client application crashes / loses its connection to the + libvirtd daemon. Any domains marked for auto destroy will + block attempts at migration, save-to-file, or snapshots. + + If the VIR_DOMAIN_START_BYPASS_CACHE flag is set, and there is a + managed save file for this domain (created by virDomainManagedSave()), + then libvirt will attempt to bypass the file system cache while restoring + the file, or fail if it cannot do so for the given system; this can allow + less pressure on file system cache, but also risks slowing loads from NFS. + + If the VIR_DOMAIN_START_FORCE_BOOT flag is set, then any managed save + file for this domain is discarded, and the domain boots from scratch. """ + ret = libvirtmod.virDomainCreateWithFiles(self._o, files, flags) + if ret == -1: raise libvirtError ('virDomainCreateWithFiles() failed', dom=self) + return ret diff --git a/python/libvirt-override.c b/python/libvirt-override.c index 01c941e0b9a0217440f3bd153480b2577fc35246..0a108877fbc567322e703df7240b1ca95b2c0320 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -7025,6 +7025,93 @@ error: } +static PyObject * +libvirt_virDomainCreateWithFiles(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval = NULL; + int c_retval; + virDomainPtr domain; + PyObject *pyobj_domain; + PyObject *pyobj_files; + unsigned int flags; + unsigned int nfiles; + int *files = NULL; + size_t i; + + if (!PyArg_ParseTuple(args, (char *)"OOi:virDomainCreateWithFiles", + &pyobj_domain, &pyobj_files, &flags)) + return NULL; + domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); + + nfiles = PyList_Size(pyobj_files); + + if (VIR_ALLOC_N_QUIET(files, nfiles) < 0) + return PyErr_NoMemory(); + + for (i = 0; i < nfiles; i++) { + PyObject *pyfd; + int fd; + + pyfd = PyList_GetItem(pyobj_files, i); + + if (libvirt_intUnwrap(pyfd, &fd) < 0) + goto cleanup; + } + + LIBVIRT_BEGIN_ALLOW_THREADS; + c_retval = virDomainCreateWithFiles(domain, nfiles, files, flags); + LIBVIRT_END_ALLOW_THREADS; + py_retval = libvirt_intWrap((int) c_retval); + +cleanup: + VIR_FREE(files); + return py_retval; +} + + +static PyObject * +libvirt_virDomainCreateXMLWithFiles(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval = NULL; + virDomainPtr c_retval; + virConnectPtr conn; + PyObject *pyobj_conn; + char * xmlDesc; + PyObject *pyobj_files; + unsigned int flags; + unsigned int nfiles; + int *files = NULL; + size_t i; + + if (!PyArg_ParseTuple(args, (char *)"OzOi:virDomainCreateXMLWithFiles", + &pyobj_conn, &xmlDesc, &pyobj_files, &flags)) + return NULL; + conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); + + nfiles = PyList_Size(pyobj_files); + + if (VIR_ALLOC_N_QUIET(files, nfiles) < 0) + return PyErr_NoMemory(); + + for (i = 0; i < nfiles; i++) { + PyObject *pyfd; + int fd; + + pyfd = PyList_GetItem(pyobj_files, i); + + if (libvirt_intUnwrap(pyfd, &fd) < 0) + goto cleanup; + } + + LIBVIRT_BEGIN_ALLOW_THREADS; + c_retval = virDomainCreateXMLWithFiles(conn, xmlDesc, nfiles, files, flags); + LIBVIRT_END_ALLOW_THREADS; + py_retval = libvirt_virDomainPtrWrap((virDomainPtr) c_retval); + +cleanup: + VIR_FREE(files); + return py_retval; +} + + /************************************************************************ * * * The registration stuff * @@ -7150,6 +7237,8 @@ static PyMethodDef libvirtMethods[] = { {(char *) "virNodeGetMemoryParameters", libvirt_virNodeGetMemoryParameters, METH_VARARGS, NULL}, {(char *) "virNodeSetMemoryParameters", libvirt_virNodeSetMemoryParameters, METH_VARARGS, NULL}, {(char *) "virNodeGetCPUMap", libvirt_virNodeGetCPUMap, METH_VARARGS, NULL}, + {(char *) "virDomainCreateXMLWithFiles", libvirt_virDomainCreateXMLWithFiles, METH_VARARGS, NULL}, + {(char *) "virDomainCreateWithFiles", libvirt_virDomainCreateWithFiles, METH_VARARGS, NULL}, {NULL, NULL, 0, NULL} }; diff --git a/src/driver.h b/src/driver.h index da030215c573670320fafe0951f3b5d5b4195b57..cc03e9f768208484a076fdef71599e35c9f38404 100644 --- a/src/driver.h +++ b/src/driver.h @@ -136,6 +136,12 @@ typedef virDomainPtr (*virDrvDomainCreateXML)(virConnectPtr conn, const char *xmlDesc, unsigned int flags); +typedef virDomainPtr +(*virDrvDomainCreateXMLWithFiles)(virConnectPtr conn, + const char *xmlDesc, + unsigned int nfiles, + int *files, + unsigned int flags); typedef virDomainPtr (*virDrvDomainLookupByID)(virConnectPtr conn, @@ -339,6 +345,11 @@ typedef int typedef int (*virDrvDomainCreateWithFlags)(virDomainPtr dom, unsigned int flags); +typedef int +(*virDrvDomainCreateWithFiles)(virDomainPtr dom, + unsigned int nfiles, + int *files, + unsigned int flags); typedef virDomainPtr (*virDrvDomainDefineXML)(virConnectPtr conn, @@ -1144,6 +1155,7 @@ struct _virDriver { virDrvConnectNumOfDomains connectNumOfDomains; virDrvConnectListAllDomains connectListAllDomains; virDrvDomainCreateXML domainCreateXML; + virDrvDomainCreateXMLWithFiles domainCreateXMLWithFiles; virDrvDomainLookupByID domainLookupByID; virDrvDomainLookupByUUID domainLookupByUUID; virDrvDomainLookupByName domainLookupByName; @@ -1201,6 +1213,7 @@ struct _virDriver { virDrvConnectNumOfDefinedDomains connectNumOfDefinedDomains; virDrvDomainCreate domainCreate; virDrvDomainCreateWithFlags domainCreateWithFlags; + virDrvDomainCreateWithFiles domainCreateWithFiles; virDrvDomainDefineXML domainDefineXML; virDrvDomainUndefine domainUndefine; virDrvDomainUndefineFlags domainUndefineFlags; diff --git a/src/libvirt.c b/src/libvirt.c index 0cdac0d2afe50c338d90d6a35695e10dc0e75609..873b4e17caffa03bb06325f3879ee494cb6b50d8 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -2003,6 +2003,79 @@ error: return NULL; } +/** + * virDomainCreateXMLWithFiles: + * @conn: pointer to the hypervisor connection + * @xmlDesc: string containing an XML description of the domain + * @nfiles: number of file descriptors passed + * @files: list of file descriptors passed + * @flags: bitwise-OR of supported virDomainCreateFlags + * + * Launch a new guest domain, based on an XML description similar + * to the one returned by virDomainGetXMLDesc() + * This function may require privileged access to the hypervisor. + * The domain is not persistent, so its definition will disappear when it + * is destroyed, or if the host is restarted (see virDomainDefineXML() to + * define persistent domains). + * + * @files provides an array of file descriptors which will be + * made available to the 'init' process of the guest. The file + * handles exposed to the guest will be renumbered to start + * from 3 (ie immediately following stderr). This is only + * supported for guests which use container based virtualization + * technology. + * + * If the VIR_DOMAIN_START_PAUSED flag is set, the guest domain + * will be started, but its CPUs will remain paused. The CPUs + * can later be manually started using virDomainResume. + * + * If the VIR_DOMAIN_START_AUTODESTROY flag is set, the guest + * domain will be automatically destroyed when the virConnectPtr + * object is finally released. This will also happen if the + * client application crashes / loses its connection to the + * libvirtd daemon. Any domains marked for auto destroy will + * block attempts at migration, save-to-file, or snapshots. + * + * Returns a new domain object or NULL in case of failure + */ +virDomainPtr +virDomainCreateXMLWithFiles(virConnectPtr conn, const char *xmlDesc, + unsigned int nfiles, + int *files, + unsigned int flags) +{ + VIR_DEBUG("conn=%p, xmlDesc=%s, nfiles=%u, files=%p, flags=%x", + conn, xmlDesc, nfiles, files, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__); + virDispatchError(NULL); + return NULL; + } + virCheckNonNullArgGoto(xmlDesc, error); + if (conn->flags & VIR_CONNECT_RO) { + virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + + if (conn->driver->domainCreateXMLWithFiles) { + virDomainPtr ret; + ret = conn->driver->domainCreateXMLWithFiles(conn, xmlDesc, + nfiles, files, + flags); + if (!ret) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); +error: + virDispatchError(conn); + return NULL; +} + /** * virDomainCreateLinux: * @conn: pointer to the hypervisor connection @@ -9424,6 +9497,87 @@ error: return -1; } +/** + * virDomainCreateWithFiles: + * @domain: pointer to a defined domain + * @nfiles: number of file descriptors passed + * @files: list of file descriptors passed + * @flags: bitwise-OR of supported virDomainCreateFlags + * + * Launch a defined domain. If the call succeeds the domain moves from the + * defined to the running domains pools. + * + * @files provides an array of file descriptors which will be + * made available to the 'init' process of the guest. The file + * handles exposed to the guest will be renumbered to start + * from 3 (ie immediately following stderr). This is only + * supported for guests which use container based virtualization + * technology. + * + * If the VIR_DOMAIN_START_PAUSED flag is set, or if the guest domain + * has a managed save image that requested paused state (see + * virDomainManagedSave()) the guest domain will be started, but its + * CPUs will remain paused. The CPUs can later be manually started + * using virDomainResume(). In all other cases, the guest domain will + * be running. + * + * If the VIR_DOMAIN_START_AUTODESTROY flag is set, the guest + * domain will be automatically destroyed when the virConnectPtr + * object is finally released. This will also happen if the + * client application crashes / loses its connection to the + * libvirtd daemon. Any domains marked for auto destroy will + * block attempts at migration, save-to-file, or snapshots. + * + * If the VIR_DOMAIN_START_BYPASS_CACHE flag is set, and there is a + * managed save file for this domain (created by virDomainManagedSave()), + * then libvirt will attempt to bypass the file system cache while restoring + * the file, or fail if it cannot do so for the given system; this can allow + * less pressure on file system cache, but also risks slowing loads from NFS. + * + * If the VIR_DOMAIN_START_FORCE_BOOT flag is set, then any managed save + * file for this domain is discarded, and the domain boots from scratch. + * + * Returns 0 in case of success, -1 in case of error + */ +int +virDomainCreateWithFiles(virDomainPtr domain, unsigned int nfiles, + int *files, unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "nfiles=%u, files=%p, flags=%x", + nfiles, files, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + conn = domain->conn; + if (conn->flags & VIR_CONNECT_RO) { + virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + + if (conn->driver->domainCreateWithFiles) { + int ret; + ret = conn->driver->domainCreateWithFiles(domain, + nfiles, files, + flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} + /** * virDomainGetAutostart: * @domain: a domain object diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 4be5104db19fd40c6ec69741e01c2c0eed7bda42..bbdf78ac222f14c39a5bd3cc264dc9aa7f54a70b 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -629,6 +629,8 @@ LIBVIRT_1.1.0 { LIBVIRT_1.1.1 { global: + virDomainCreateWithFiles; + virDomainCreateXMLWithFiles; virDomainSetMemoryStatsPeriod; } LIBVIRT_1.1.0;