diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 0b1a2d6dd4..3a835717ed 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -1422,6 +1422,10 @@ int virDomainMemoryPeek (virDomainPtr dom, */ virDomainPtr virDomainDefineXML (virConnectPtr conn, const char *xml); + +virDomainPtr virDomainDefineXMLFlags (virConnectPtr conn, + const char *xml, + unsigned int flags); int virDomainUndefine (virDomainPtr domain); typedef enum { diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 9f26b13c5a..a1d2a0aec2 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -314,6 +314,10 @@ typedef int typedef virDomainPtr (*virDrvDomainDefineXML)(virConnectPtr conn, const char *xml); +typedef virDomainPtr +(*virDrvDomainDefineXMLFlags)(virConnectPtr conn, + const char *xml, + unsigned int flags); typedef int (*virDrvDomainUndefine)(virDomainPtr dom); @@ -1265,6 +1269,7 @@ struct _virHypervisorDriver { virDrvDomainCreateWithFlags domainCreateWithFlags; virDrvDomainCreateWithFiles domainCreateWithFiles; virDrvDomainDefineXML domainDefineXML; + virDrvDomainDefineXMLFlags domainDefineXMLFlags; virDrvDomainUndefine domainUndefine; virDrvDomainUndefineFlags domainUndefineFlags; virDrvDomainAttachDevice domainAttachDevice; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 6ec68aa717..0b4c09722b 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -6475,6 +6475,54 @@ virDomainDefineXML(virConnectPtr conn, const char *xml) } +/** + * virDomainDefineXMLFlags: + * @conn: pointer to the hypervisor connection + * @xml: the XML description for the domain, preferably in UTF-8 + * @flags: currently unused, pass 0 + * + * Defines a domain, but does not start it. + * This definition is persistent, until explicitly undefined with + * virDomainUndefine(). A previous definition for this domain would be + * overridden if it already exists. + * + * Some hypervisors may prevent this operation if there is a current + * block copy operation on a transient domain with the same id as the + * domain being defined; in that case, use virDomainBlockJobAbort() to + * stop the block copy first. + * + * virDomainFree should be used to free the resources after the + * domain object is no longer needed. + * + * Returns NULL in case of error, a pointer to the domain otherwise + */ +virDomainPtr +virDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags) +{ + VIR_DEBUG("conn=%p, xml=%s flags=%x", conn, xml, flags); + + virResetLastError(); + + virCheckConnectReturn(conn, NULL); + virCheckReadOnlyGoto(conn->flags, error); + virCheckNonNullArgGoto(xml, error); + + if (conn->driver->domainDefineXMLFlags) { + virDomainPtr ret; + ret = conn->driver->domainDefineXMLFlags(conn, xml, flags); + if (!ret) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(conn); + return NULL; +} + + /** * virDomainUndefine: * @domain: pointer to a defined domain diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index e4c2df198f..4ea5cff655 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -690,4 +690,9 @@ LIBVIRT_1.2.11 { virDomainGetFSInfo; } LIBVIRT_1.2.9; +LIBVIRT_1.2.12 { + global: + virDomainDefineXMLFlags; +} LIBVIRT_1.2.11; + # .... define new API here using predicted next version number .... diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 999f16d0e1..3cc603f973 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8151,6 +8151,7 @@ static virHypervisorDriver hypervisor_driver = { .domainCreateWithFlags = remoteDomainCreateWithFlags, /* 0.8.2 */ .domainCreateWithFiles = remoteDomainCreateWithFiles, /* 1.1.1 */ .domainDefineXML = remoteDomainDefineXML, /* 0.3.0 */ + .domainDefineXMLFlags = remoteDomainDefineXMLFlags, /* 1.2.12 */ .domainUndefine = remoteDomainUndefine, /* 0.3.0 */ .domainUndefineFlags = remoteDomainUndefineFlags, /* 0.9.4 */ .domainAttachDevice = remoteDomainAttachDevice, /* 0.3.0 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index cbd3ec733e..d91fbe0ee4 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -1062,6 +1062,15 @@ struct remote_domain_define_xml_ret { remote_nonnull_domain dom; }; +struct remote_domain_define_xml_flags_args { + remote_nonnull_string xml; + unsigned int flags; +}; + +struct remote_domain_define_xml_flags_ret { + remote_nonnull_domain dom; +}; + struct remote_domain_undefine_args { remote_nonnull_domain dom; }; @@ -5550,5 +5559,13 @@ enum remote_procedure { * @generate: none * @acl: domain:fs_freeze */ - REMOTE_PROC_DOMAIN_GET_FSINFO = 349 + REMOTE_PROC_DOMAIN_GET_FSINFO = 349, + + /** + * @priority: high + * @generate: both + * @acl: domain:write + * @acl: domain:save + */ + REMOTE_PROC_DOMAIN_DEFINE_XML_FLAGS = 350 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 2907fd53bd..df6eaf3755 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -686,6 +686,13 @@ struct remote_domain_define_xml_args { struct remote_domain_define_xml_ret { remote_nonnull_domain dom; }; +struct remote_domain_define_xml_flags_args { + remote_nonnull_string xml; + u_int flags; +}; +struct remote_domain_define_xml_flags_ret { + remote_nonnull_domain dom; +}; struct remote_domain_undefine_args { remote_nonnull_domain dom; }; @@ -2955,4 +2962,5 @@ enum remote_procedure { REMOTE_PROC_NODE_ALLOC_PAGES = 347, REMOTE_PROC_DOMAIN_EVENT_CALLBACK_AGENT_LIFECYCLE = 348, REMOTE_PROC_DOMAIN_GET_FSINFO = 349, + REMOTE_PROC_DOMAIN_DEFINE_XML_FLAGS = 350, };