Introduce a src/libvirt-domain.c file to hold all the
methods related to the virDomain type.
---
docs/apibuild.py | 2 +
po/POTFILES.in | 1 +
src/Makefile.am | 2 +
src/libvirt-domain.c | 11112 ++++++++++++++++++++++++++++++++++++++++++
src/libvirt.c | 12388 +++--------------------------------------------
src/libvirt_internal.h | 6 +
6 files changed, 11774 insertions(+), 11737 deletions(-)
create mode 100644 src/libvirt-domain.c
diff --git a/docs/apibuild.py b/docs/apibuild.py
index 1eb6fcf..a96260f 100755
--- a/docs/apibuild.py
+++ b/docs/apibuild.py
@@ -24,6 +24,7 @@ included_files = {
"libvirt.h": "header with general libvirt API definitions",
"virterror.h": "header with error specific API definitions",
"libvirt.c": "Main interfaces for the libvirt library",
+ "libvirt-domain.c": "Domain interfaces for the libvirt library",
"libvirt-domain-snapshot.c": "Domain snapshot interfaces for the libvirt
library",
"libvirt-interface.c": "Interface interfaces for the libvirt
library",
"libvirt-network.c": "Network interfaces for the libvirt library",
@@ -73,6 +74,7 @@ ignored_functions = {
"virDomainMigratePrepareTunnel3": "private function for tunnelled
migration",
"DllMain": "specific function for Win32",
"virTypedParamsValidate": "internal function in virtypedparam.c",
+ "virTypedParameterValidateSet": "internal function in
virtypedparam.c",
"virTypedParameterAssign": "internal function in virtypedparam.c",
"virTypedParameterAssignFromStr": "internal function in
virtypedparam.c",
"virTypedParameterToString": "internal function in
virtypedparam.c",
diff --git a/po/POTFILES.in b/po/POTFILES.in
index ade9fdb..d9c9af7 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -57,6 +57,7 @@ src/interface/interface_backend_netcf.c
src/interface/interface_backend_udev.c
src/internal.h
src/libvirt.c
+src/libvirt-domain.c
src/libvirt-domain-snapshot.c
src/libvirt-lxc.c
src/libvirt-network.c
diff --git a/src/Makefile.am b/src/Makefile.am
index f246a23..7da9abd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -189,6 +189,7 @@ DRIVER_SOURCES = \
fdstream.c fdstream.h \
$(NODE_INFO_SOURCES) \
libvirt.c libvirt_internal.h \
+ libvirt-domain.c \
libvirt-domain-snapshot.c \
libvirt-interface.c \
libvirt-network.c \
@@ -2194,6 +2195,7 @@ libvirt_setuid_rpc_client_la_SOURCES = \
remote/lxc_protocol.c \
datatypes.c \
libvirt.c \
+ libvirt-domain.c \
libvirt-domain-snapshot.c \
libvirt-interface.c \
libvirt-network.c \
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
new file mode 100644
index 0000000..37b8927
--- /dev/null
+++ b/src/libvirt-domain.c
@@ -0,0 +1,11112 @@
+/*
+ * libvirt-domain.c: entry points for virDomainPtr APIs
+ *
+ * Copyright (C) 2006-2014 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <sys/stat.h>
+
+#include "intprops.h"
+
+#include "datatypes.h"
+#include "viralloc.h"
+#include "virfile.h"
+#include "virlog.h"
+#include "virtypedparam.h"
+
+VIR_LOG_INIT("libvirt.domain");
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+
+/**
+ * virConnectListDomains:
+ * @conn: pointer to the hypervisor connection
+ * @ids: array to collect the list of IDs of active domains
+ * @maxids: size of @ids
+ *
+ * Collect the list of active domains, and store their IDs in array @ids
+ *
+ * For inactive domains, see virConnectListDefinedDomains(). For more
+ * control over the results, see virConnectListAllDomains().
+ *
+ * Returns the number of domains found or -1 in case of error. Note that
+ * this command is inherently racy; a domain can be started between a
+ * call to virConnectNumOfDomains() and this call; you are only guaranteed
+ * that all currently active domains were listed if the return is less
+ * than @maxids.
+ */
+int
+virConnectListDomains(virConnectPtr conn, int *ids, int maxids)
+{
+ VIR_DEBUG("conn=%p, ids=%p, maxids=%d", conn, ids, maxids);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+ virCheckNonNullArgGoto(ids, error);
+ virCheckNonNegativeArgGoto(maxids, error);
+
+ if (conn->driver->connectListDomains) {
+ int ret = conn->driver->connectListDomains(conn, ids, maxids);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virConnectNumOfDomains:
+ * @conn: pointer to the hypervisor connection
+ *
+ * Provides the number of active domains.
+ *
+ * Returns the number of domain found or -1 in case of error
+ */
+int
+virConnectNumOfDomains(virConnectPtr conn)
+{
+ VIR_DEBUG("conn=%p", conn);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+
+ if (conn->driver->connectNumOfDomains) {
+ int ret = conn->driver->connectNumOfDomains(conn);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetConnect:
+ * @dom: pointer to a domain
+ *
+ * Provides the connection pointer associated with a domain. The
+ * reference counter on the connection is not increased by this
+ * call.
+ *
+ * WARNING: When writing libvirt bindings in other languages, do
+ * not use this function. Instead, store the connection and
+ * the domain object together.
+ *
+ * Returns the virConnectPtr or NULL in case of failure.
+ */
+virConnectPtr
+virDomainGetConnect(virDomainPtr dom)
+{
+ VIR_DOMAIN_DEBUG(dom);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, NULL);
+
+ return dom->conn;
+}
+
+
+/**
+ * virDomainCreateXML:
+ * @conn: pointer to the hypervisor connection
+ * @xmlDesc: string containing an XML description of the domain
+ * @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).
+ *
+ * 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.
+ *
+ * virDomainFree should be used to free the resources after the
+ * domain object is no longer needed.
+ *
+ * Returns a new domain object or NULL in case of failure
+ */
+virDomainPtr
+virDomainCreateXML(virConnectPtr conn, const char *xmlDesc,
+ unsigned int flags)
+{
+ VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, xmlDesc, flags);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, NULL);
+ virCheckNonNullArgGoto(xmlDesc, error);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainCreateXML) {
+ virDomainPtr ret;
+ ret = conn->driver->domainCreateXML(conn, xmlDesc, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ 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.
+ *
+ * virDomainFree should be used to free the resources after the
+ * domain object is no longer needed.
+ *
+ * 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();
+
+ virCheckConnectReturn(conn, NULL);
+ virCheckNonNullArgGoto(xmlDesc, error);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainCreateXMLWithFiles) {
+ virDomainPtr ret;
+ ret = conn->driver->domainCreateXMLWithFiles(conn, xmlDesc,
+ nfiles, files,
+ flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainCreateLinux:
+ * @conn: pointer to the hypervisor connection
+ * @xmlDesc: string containing an XML description of the domain
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Deprecated after 0.4.6.
+ * Renamed to virDomainCreateXML() providing identical functionality.
+ * This existing name will left indefinitely for API compatibility.
+ *
+ * Returns a new domain object or NULL in case of failure
+ */
+virDomainPtr
+virDomainCreateLinux(virConnectPtr conn, const char *xmlDesc,
+ unsigned int flags)
+{
+ return virDomainCreateXML(conn, xmlDesc, flags);
+}
+
+
+/**
+ * virDomainLookupByID:
+ * @conn: pointer to the hypervisor connection
+ * @id: the domain ID number
+ *
+ * Try to find a domain based on the hypervisor ID number
+ * Note that this won't work for inactive domains which have an ID of -1,
+ * in that case a lookup based on the Name or UUId need to be done instead.
+ *
+ * virDomainFree should be used to free the resources after the
+ * domain object is no longer needed.
+ *
+ * Returns a new domain object or NULL in case of failure. If the
+ * domain cannot be found, then VIR_ERR_NO_DOMAIN error is raised.
+ */
+virDomainPtr
+virDomainLookupByID(virConnectPtr conn, int id)
+{
+ VIR_DEBUG("conn=%p, id=%d", conn, id);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, NULL);
+ virCheckNonNegativeArgGoto(id, error);
+
+ if (conn->driver->domainLookupByID) {
+ virDomainPtr ret;
+ ret = conn->driver->domainLookupByID(conn, id);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainLookupByUUID:
+ * @conn: pointer to the hypervisor connection
+ * @uuid: the raw UUID for the domain
+ *
+ * Try to lookup a domain on the given hypervisor based on its UUID.
+ *
+ * virDomainFree should be used to free the resources after the
+ * domain object is no longer needed.
+ *
+ * Returns a new domain object or NULL in case of failure. If the
+ * domain cannot be found, then VIR_ERR_NO_DOMAIN error is raised.
+ */
+virDomainPtr
+virDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
+{
+ VIR_UUID_DEBUG(conn, uuid);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, NULL);
+ virCheckNonNullArgGoto(uuid, error);
+
+ if (conn->driver->domainLookupByUUID) {
+ virDomainPtr ret;
+ ret = conn->driver->domainLookupByUUID(conn, uuid);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainLookupByUUIDString:
+ * @conn: pointer to the hypervisor connection
+ * @uuidstr: the string UUID for the domain
+ *
+ * Try to lookup a domain on the given hypervisor based on its UUID.
+ *
+ * virDomainFree should be used to free the resources after the
+ * domain object is no longer needed.
+ *
+ * Returns a new domain object or NULL in case of failure. If the
+ * domain cannot be found, then VIR_ERR_NO_DOMAIN error is raised.
+ */
+virDomainPtr
+virDomainLookupByUUIDString(virConnectPtr conn, const char *uuidstr)
+{
+ unsigned char uuid[VIR_UUID_BUFLEN];
+ VIR_DEBUG("conn=%p, uuidstr=%s", conn, NULLSTR(uuidstr));
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, NULL);
+ virCheckNonNullArgGoto(uuidstr, error);
+
+ if (virUUIDParse(uuidstr, uuid) < 0) {
+ virReportInvalidArg(uuidstr,
+ _("uuidstr in %s must be a valid UUID"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ return virDomainLookupByUUID(conn, &uuid[0]);
+
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainLookupByName:
+ * @conn: pointer to the hypervisor connection
+ * @name: name for the domain
+ *
+ * Try to lookup a domain on the given hypervisor based on its name.
+ *
+ * virDomainFree should be used to free the resources after the
+ * domain object is no longer needed.
+ *
+ * Returns a new domain object or NULL in case of failure. If the
+ * domain cannot be found, then VIR_ERR_NO_DOMAIN error is raised.
+ */
+virDomainPtr
+virDomainLookupByName(virConnectPtr conn, const char *name)
+{
+ VIR_DEBUG("conn=%p, name=%s", conn, name);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, NULL);
+ virCheckNonNullArgGoto(name, error);
+
+ if (conn->driver->domainLookupByName) {
+ virDomainPtr dom;
+ dom = conn->driver->domainLookupByName(conn, name);
+ if (!dom)
+ goto error;
+ return dom;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainDestroy:
+ * @domain: a domain object
+ *
+ * Destroy the domain object. The running instance is shutdown if not down
+ * already and all resources used by it are given back to the hypervisor. This
+ * does not free the associated virDomainPtr object.
+ * This function may require privileged access.
+ *
+ * virDomainDestroy first requests that a guest terminate
+ * (e.g. SIGTERM), then waits for it to comply. After a reasonable
+ * timeout, if the guest still exists, virDomainDestroy will
+ * forcefully terminate the guest (e.g. SIGKILL) if necessary (which
+ * may produce undesirable results, for example unflushed disk cache
+ * in the guest). To avoid this possibility, it's recommended to
+ * instead call virDomainDestroyFlags, sending the
+ * VIR_DOMAIN_DESTROY_GRACEFUL flag.
+ *
+ * If the domain is transient and has any snapshot metadata (see
+ * virDomainSnapshotNum()), then that metadata will automatically
+ * be deleted when the domain quits.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainDestroy(virDomainPtr domain)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainDestroy) {
+ int ret;
+ ret = conn->driver->domainDestroy(domain);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainDestroyFlags:
+ * @domain: a domain object
+ * @flags: bitwise-OR of virDomainDestroyFlagsValues
+ *
+ * Destroy the domain object. The running instance is shutdown if not down
+ * already and all resources used by it are given back to the hypervisor.
+ * This does not free the associated virDomainPtr object.
+ * This function may require privileged access.
+ *
+ * Calling this function with no @flags set (equal to zero) is
+ * equivalent to calling virDomainDestroy, and after a reasonable
+ * timeout will forcefully terminate the guest (e.g. SIGKILL) if
+ * necessary (which may produce undesirable results, for example
+ * unflushed disk cache in the guest). Including
+ * VIR_DOMAIN_DESTROY_GRACEFUL in the flags will prevent the forceful
+ * termination of the guest, and virDomainDestroyFlags will instead
+ * return an error if the guest doesn't terminate by the end of the
+ * timeout; at that time, the management application can decide if
+ * calling again without VIR_DOMAIN_DESTROY_GRACEFUL is appropriate.
+ *
+ * Another alternative which may produce cleaner results for the
+ * guest's disks is to use virDomainShutdown() instead, but that
+ * depends on guest support (some hypervisor/guest combinations may
+ * ignore the shutdown request).
+ *
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainDestroyFlags(virDomainPtr domain,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainDestroyFlags) {
+ int ret;
+ ret = conn->driver->domainDestroyFlags(domain, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainFree:
+ * @domain: a domain object
+ *
+ * Free the domain object. The running instance is kept alive.
+ * The data structure is freed and should not be used thereafter.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainFree(virDomainPtr domain)
+{
+ VIR_DOMAIN_DEBUG(domain);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+
+ virObjectUnref(domain);
+ return 0;
+}
+
+
+/**
+ * virDomainRef:
+ * @domain: the domain to hold a reference on
+ *
+ * Increment the reference count on the domain. For each
+ * additional call to this method, there shall be a corresponding
+ * call to virDomainFree to release the reference count, once
+ * the caller no longer needs the reference to this object.
+ *
+ * This method is typically useful for applications where multiple
+ * threads are using a connection, and it is required that the
+ * connection remain open until all threads have finished using
+ * it. ie, each new thread using a domain would increment
+ * the reference count.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainRef(virDomainPtr domain)
+{
+ VIR_DOMAIN_DEBUG(domain, "refs=%d", domain ? domain->object.u.s.refs :
0);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+
+ virObjectRef(domain);
+ return 0;
+}
+
+
+/**
+ * virDomainSuspend:
+ * @domain: a domain object
+ *
+ * Suspends an active domain, the process is frozen without further access
+ * to CPU resources and I/O but the memory used by the domain at the
+ * hypervisor level will stay allocated. Use virDomainResume() to reactivate
+ * the domain.
+ * This function may require privileged access.
+ * Moreover, suspend may not be supported if domain is in some
+ * special state like VIR_DOMAIN_PMSUSPENDED.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainSuspend(virDomainPtr domain)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainSuspend) {
+ int ret;
+ ret = conn->driver->domainSuspend(domain);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainResume:
+ * @domain: a domain object
+ *
+ * Resume a suspended domain, the process is restarted from the state where
+ * it was frozen by calling virDomainSuspend().
+ * This function may require privileged access
+ * Moreover, resume may not be supported if domain is in some
+ * special state like VIR_DOMAIN_PMSUSPENDED.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainResume(virDomainPtr domain)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainResume) {
+ int ret;
+ ret = conn->driver->domainResume(domain);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainPMSuspendForDuration:
+ * @dom: a domain object
+ * @target: a value from virNodeSuspendTarget
+ * @duration: duration in seconds to suspend, or 0 for indefinite
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Attempt to have the guest enter the given @target power management
+ * suspension level. If @duration is non-zero, also schedule the guest to
+ * resume normal operation after that many seconds, if nothing else has
+ * resumed it earlier. Some hypervisors require that @duration be 0, for
+ * an indefinite suspension.
+ *
+ * Dependent on hypervisor used, this may require a
+ * guest agent to be available, e.g. QEMU.
+ *
+ * Beware that at least for QEMU, the domain's process will be terminated
+ * when VIR_NODE_SUSPEND_TARGET_DISK is used and a new process will be
+ * launched when libvirt is asked to wake up the domain. As a result of
+ * this, any runtime changes, such as device hotplug or memory settings,
+ * are lost unless such changes were made with VIR_DOMAIN_AFFECT_CONFIG
+ * flag.
+ *
+ * Returns: 0 on success,
+ * -1 on failure.
+ */
+int
+virDomainPMSuspendForDuration(virDomainPtr dom,
+ unsigned int target,
+ unsigned long long duration,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "target=%u duration=%llu flags=%x",
+ target, duration, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainPMSuspendForDuration) {
+ int ret;
+ ret = conn->driver->domainPMSuspendForDuration(dom, target,
+ duration, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainPMWakeup:
+ * @dom: a domain object
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Inject a wakeup into the guest that previously used
+ * virDomainPMSuspendForDuration, rather than waiting for the
+ * previously requested duration (if any) to elapse.
+ *
+ * Returns: 0 on success,
+ * -1 on failure.
+ */
+int
+virDomainPMWakeup(virDomainPtr dom,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainPMWakeup) {
+ int ret;
+ ret = conn->driver->domainPMWakeup(dom, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSave:
+ * @domain: a domain object
+ * @to: path for the output file
+ *
+ * This method will suspend a domain and save its memory contents to
+ * a file on disk. After the call, if successful, the domain is not
+ * listed as running anymore (this ends the life of a transient domain).
+ * Use virDomainRestore() to restore a domain after saving.
+ *
+ * See virDomainSaveFlags() for more control. Also, a save file can
+ * be inspected or modified slightly with virDomainSaveImageGetXMLDesc()
+ * and virDomainSaveImageDefineXML().
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainSave(virDomainPtr domain, const char *to)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "to=%s", to);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(to, error);
+
+ if (conn->driver->domainSave) {
+ int ret;
+ char *absolute_to;
+
+ /* We must absolutize the file path as the save is done out of process */
+ if (virFileAbsPath(to, &absolute_to) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("could not build absolute output file path"));
+ goto error;
+ }
+
+ ret = conn->driver->domainSave(domain, absolute_to);
+
+ VIR_FREE(absolute_to);
+
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSaveFlags:
+ * @domain: a domain object
+ * @to: path for the output file
+ * @dxml: (optional) XML config for adjusting guest xml used on restore
+ * @flags: bitwise-OR of virDomainSaveRestoreFlags
+ *
+ * This method will suspend a domain and save its memory contents to
+ * a file on disk. After the call, if successful, the domain is not
+ * listed as running anymore (this ends the life of a transient domain).
+ * Use virDomainRestore() to restore a domain after saving.
+ *
+ * If the hypervisor supports it, @dxml can be used to alter
+ * host-specific portions of the domain XML that will be used when
+ * restoring an image. For example, it is possible to alter the
+ * backing filename that is associated with a disk device, in order to
+ * prepare for file renaming done as part of backing up the disk
+ * device while the domain is stopped.
+ *
+ * If @flags includes VIR_DOMAIN_SAVE_BYPASS_CACHE, then libvirt will
+ * attempt to bypass the file system cache while creating 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 saves to NFS.
+ *
+ * Normally, the saved state file will remember whether the domain was
+ * running or paused, and restore defaults to the same state.
+ * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in
+ * @flags will override what state gets saved into the file. These
+ * two flags are mutually exclusive.
+ *
+ * A save file can be inspected or modified slightly with
+ * virDomainSaveImageGetXMLDesc() and virDomainSaveImageDefineXML().
+ *
+ * Some hypervisors may prevent this operation if there is a current
+ * block copy operation; in that case, use virDomainBlockJobAbort()
+ * to stop the block copy first.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainSaveFlags(virDomainPtr domain, const char *to,
+ const char *dxml, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "to=%s, dxml=%s, flags=%x",
+ to, NULLSTR(dxml), flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(to, error);
+
+ if ((flags & VIR_DOMAIN_SAVE_RUNNING) && (flags &
VIR_DOMAIN_SAVE_PAUSED)) {
+ virReportInvalidArg(flags, "%s",
+ _("running and paused flags are mutually "
+ "exclusive"));
+ goto error;
+ }
+
+ if (conn->driver->domainSaveFlags) {
+ int ret;
+ char *absolute_to;
+
+ /* We must absolutize the file path as the save is done out of process */
+ if (virFileAbsPath(to, &absolute_to) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("could not build absolute output file path"));
+ goto error;
+ }
+
+ ret = conn->driver->domainSaveFlags(domain, absolute_to, dxml, flags);
+
+ VIR_FREE(absolute_to);
+
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainRestore:
+ * @conn: pointer to the hypervisor connection
+ * @from: path to the input file
+ *
+ * This method will restore a domain saved to disk by virDomainSave().
+ *
+ * See virDomainRestoreFlags() for more control.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainRestore(virConnectPtr conn, const char *from)
+{
+ VIR_DEBUG("conn=%p, from=%s", conn, from);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(from, error);
+
+ if (conn->driver->domainRestore) {
+ int ret;
+ char *absolute_from;
+
+ /* We must absolutize the file path as the restore is done out of process */
+ if (virFileAbsPath(from, &absolute_from) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("could not build absolute input file path"));
+ goto error;
+ }
+
+ ret = conn->driver->domainRestore(conn, absolute_from);
+
+ VIR_FREE(absolute_from);
+
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainRestoreFlags:
+ * @conn: pointer to the hypervisor connection
+ * @from: path to the input file
+ * @dxml: (optional) XML config for adjusting guest xml used on restore
+ * @flags: bitwise-OR of virDomainSaveRestoreFlags
+ *
+ * This method will restore a domain saved to disk by virDomainSave().
+ *
+ * If the hypervisor supports it, @dxml can be used to alter
+ * host-specific portions of the domain XML that will be used when
+ * restoring an image. For example, it is possible to alter the
+ * backing filename that is associated with a disk device, in order to
+ * prepare for file renaming done as part of backing up the disk
+ * device while the domain is stopped.
+ *
+ * If @flags includes VIR_DOMAIN_SAVE_BYPASS_CACHE, 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 restores from NFS.
+ *
+ * Normally, the saved state file will remember whether the domain was
+ * running or paused, and restore defaults to the same state.
+ * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in
+ * @flags will override the default read from the file. These two
+ * flags are mutually exclusive.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainRestoreFlags(virConnectPtr conn, const char *from, const char *dxml,
+ unsigned int flags)
+{
+ VIR_DEBUG("conn=%p, from=%s, dxml=%s, flags=%x",
+ conn, from, NULLSTR(dxml), flags);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(from, error);
+
+ if ((flags & VIR_DOMAIN_SAVE_RUNNING) && (flags &
VIR_DOMAIN_SAVE_PAUSED)) {
+ virReportInvalidArg(flags, "%s",
+ _("running and paused flags are mutually "
+ "exclusive"));
+ goto error;
+ }
+
+ if (conn->driver->domainRestoreFlags) {
+ int ret;
+ char *absolute_from;
+
+ /* We must absolutize the file path as the restore is done out of process */
+ if (virFileAbsPath(from, &absolute_from) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("could not build absolute input file path"));
+ goto error;
+ }
+
+ ret = conn->driver->domainRestoreFlags(conn, absolute_from, dxml,
+ flags);
+
+ VIR_FREE(absolute_from);
+
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSaveImageGetXMLDesc:
+ * @conn: pointer to the hypervisor connection
+ * @file: path to saved state file
+ * @flags: bitwise-OR of subset of virDomainXMLFlags
+ *
+ * This method will extract the XML describing the domain at the time
+ * a saved state file was created. @file must be a file created
+ * previously by virDomainSave() or virDomainSaveFlags().
+ *
+ * No security-sensitive data will be included unless @flags contains
+ * VIR_DOMAIN_XML_SECURE; this flag is rejected on read-only
+ * connections. For this API, @flags should not contain either
+ * VIR_DOMAIN_XML_INACTIVE or VIR_DOMAIN_XML_UPDATE_CPU.
+ *
+ * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of
+ * error. The caller must free() the returned value.
+ */
+char *
+virDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *file,
+ unsigned int flags)
+{
+ VIR_DEBUG("conn=%p, file=%s, flags=%x",
+ conn, file, flags);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, NULL);
+ virCheckNonNullArgGoto(file, error);
+
+ if ((conn->flags & VIR_CONNECT_RO) && (flags &
VIR_DOMAIN_XML_SECURE)) {
+ virReportError(VIR_ERR_OPERATION_DENIED, "%s",
+ _("virDomainSaveImageGetXMLDesc with secure flag"));
+ goto error;
+ }
+
+ if (conn->driver->domainSaveImageGetXMLDesc) {
+ char *ret;
+ char *absolute_file;
+
+ /* We must absolutize the file path as the read is done out of process */
+ if (virFileAbsPath(file, &absolute_file) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("could not build absolute input file path"));
+ goto error;
+ }
+
+ ret = conn->driver->domainSaveImageGetXMLDesc(conn, absolute_file,
+ flags);
+
+ VIR_FREE(absolute_file);
+
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainSaveImageDefineXML:
+ * @conn: pointer to the hypervisor connection
+ * @file: path to saved state file
+ * @dxml: XML config for adjusting guest xml used on restore
+ * @flags: bitwise-OR of virDomainSaveRestoreFlags
+ *
+ * This updates the definition of a domain stored in a saved state
+ * file. @file must be a file created previously by virDomainSave()
+ * or virDomainSaveFlags().
+ *
+ * @dxml can be used to alter host-specific portions of the domain XML
+ * that will be used when restoring an image. For example, it is
+ * possible to alter the backing filename that is associated with a
+ * disk device, to match renaming done as part of backing up the disk
+ * device while the domain is stopped.
+ *
+ * Normally, the saved state file will remember whether the domain was
+ * running or paused, and restore defaults to the same state.
+ * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in
+ * @flags will override the default saved into the file; omitting both
+ * leaves the file's default unchanged. These two flags are mutually
+ * exclusive.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainSaveImageDefineXML(virConnectPtr conn, const char *file,
+ const char *dxml, unsigned int flags)
+{
+ VIR_DEBUG("conn=%p, file=%s, dxml=%s, flags=%x",
+ conn, file, dxml, flags);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(file, error);
+ virCheckNonNullArgGoto(dxml, error);
+
+ if ((flags & VIR_DOMAIN_SAVE_RUNNING) && (flags &
VIR_DOMAIN_SAVE_PAUSED)) {
+ virReportInvalidArg(flags, "%s",
+ _("running and paused flags are mutually "
+ "exclusive"));
+ goto error;
+ }
+
+ if (conn->driver->domainSaveImageDefineXML) {
+ int ret;
+ char *absolute_file;
+
+ /* We must absolutize the file path as the read is done out of process */
+ if (virFileAbsPath(file, &absolute_file) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("could not build absolute input file path"));
+ goto error;
+ }
+
+ ret = conn->driver->domainSaveImageDefineXML(conn, absolute_file,
+ dxml, flags);
+
+ VIR_FREE(absolute_file);
+
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainCoreDump:
+ * @domain: a domain object
+ * @to: path for the core file
+ * @flags: bitwise-OR of virDomainCoreDumpFlags
+ *
+ * This method will dump the core of a domain on a given file for analysis.
+ * Note that for remote Xen Daemon the file path will be interpreted in
+ * the remote host. Hypervisors may require the user to manually ensure
+ * proper permissions on the file named by @to.
+ *
+ * If @flags includes VIR_DUMP_CRASH, then leave the guest shut off with
+ * a crashed state after the dump completes. If @flags includes
+ * VIR_DUMP_LIVE, then make the core dump while continuing to allow
+ * the guest to run; otherwise, the guest is suspended during the dump.
+ * VIR_DUMP_RESET flag forces reset of the guest after dump.
+ * The above three flags are mutually exclusive.
+ *
+ * Additionally, if @flags includes VIR_DUMP_BYPASS_CACHE, then libvirt
+ * will attempt to bypass the file system cache while creating 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 saves to NFS.
+ *
+ * For more control over the output format, see virDomainCoreDumpWithFormat().
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainCoreDump(virDomainPtr domain, const char *to, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "to=%s, flags=%x", to, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(to, error);
+
+ if ((flags & VIR_DUMP_CRASH) && (flags & VIR_DUMP_LIVE)) {
+ virReportInvalidArg(flags, "%s",
+ _("crash and live flags are mutually exclusive"));
+ goto error;
+ }
+
+ if ((flags & VIR_DUMP_CRASH) && (flags & VIR_DUMP_RESET)) {
+ virReportInvalidArg(flags, "%s",
+ _("crash and reset flags are mutually exclusive"));
+ goto error;
+ }
+
+ if ((flags & VIR_DUMP_LIVE) && (flags & VIR_DUMP_RESET)) {
+ virReportInvalidArg(flags, "%s",
+ _("live and reset flags are mutually exclusive"));
+ goto error;
+ }
+
+ if (conn->driver->domainCoreDump) {
+ int ret;
+ char *absolute_to;
+
+ /* We must absolutize the file path as the save is done out of process */
+ if (virFileAbsPath(to, &absolute_to) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("could not build absolute core file path"));
+ goto error;
+ }
+
+ ret = conn->driver->domainCoreDump(domain, absolute_to, flags);
+
+ VIR_FREE(absolute_to);
+
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+/**
+ * virDomainCoreDumpWithFormat:
+ * @domain: a domain object
+ * @to: path for the core file
+ * @dumpformat: format of domain memory's dump
+ * @flags: bitwise-OR of virDomainCoreDumpFlags
+ *
+ * This method will dump the core of a domain on a given file for analysis.
+ * Note that for remote Xen Daemon the file path will be interpreted in
+ * the remote host. Hypervisors may require the user to manually ensure
+ * proper permissions on the file named by @to.
+ *
+ * @dumpformat controls which format the dump will have; use of
+ * VIR_DOMAIN_CORE_DUMP_FORMAT_RAW mirrors what virDomainCoreDump() will
+ * perform. Not all hypervisors are able to support all formats.
+ *
+ * If @flags includes VIR_DUMP_CRASH, then leave the guest shut off with
+ * a crashed state after the dump completes. If @flags includes
+ * VIR_DUMP_LIVE, then make the core dump while continuing to allow
+ * the guest to run; otherwise, the guest is suspended during the dump.
+ * VIR_DUMP_RESET flag forces reset of the guest after dump.
+ * The above three flags are mutually exclusive.
+ *
+ * Additionally, if @flags includes VIR_DUMP_BYPASS_CACHE, then libvirt
+ * will attempt to bypass the file system cache while creating 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 saves to NFS.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainCoreDumpWithFormat(virDomainPtr domain, const char *to,
+ unsigned int dumpformat, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "to=%s, dumpformat=%u, flags=%x",
+ to, dumpformat, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(to, error);
+
+ if (dumpformat >= VIR_DOMAIN_CORE_DUMP_FORMAT_LAST) {
+ virReportInvalidArg(flags, _("dumpformat '%d' is not
supported"),
+ dumpformat);
+ goto error;
+ }
+
+ if ((flags & VIR_DUMP_CRASH) && (flags & VIR_DUMP_LIVE)) {
+ virReportInvalidArg(flags, "%s",
+ _("crash and live flags are mutually exclusive"));
+ goto error;
+ }
+
+ if ((flags & VIR_DUMP_CRASH) && (flags & VIR_DUMP_RESET)) {
+ virReportInvalidArg(flags, "%s",
+ _("crash and reset flags are mutually
exclusive"));
+ goto error;
+ }
+
+ if ((flags & VIR_DUMP_LIVE) && (flags & VIR_DUMP_RESET)) {
+ virReportInvalidArg(flags, "%s",
+ _("live and reset flags are mutually exclusive"));
+ goto error;
+ }
+
+ if (conn->driver->domainCoreDumpWithFormat) {
+ int ret;
+ char *absolute_to;
+
+ /* We must absolutize the file path as the save is done out of process */
+ if (virFileAbsPath(to, &absolute_to) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("could not build absolute core file path"));
+ goto error;
+ }
+
+ ret = conn->driver->domainCoreDumpWithFormat(domain, absolute_to,
+ dumpformat, flags);
+
+ VIR_FREE(absolute_to);
+
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainScreenshot:
+ * @domain: a domain object
+ * @stream: stream to use as output
+ * @screen: monitor ID to take screenshot from
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Take a screenshot of current domain console as a stream. The image format
+ * is hypervisor specific. Moreover, some hypervisors supports multiple
+ * displays per domain. These can be distinguished by @screen argument.
+ *
+ * This call sets up a stream; subsequent use of stream API is necessary
+ * to transfer actual data, determine how much data is successfully
+ * transferred, and detect any errors.
+ *
+ * The screen ID is the sequential number of screen. In case of multiple
+ * graphics cards, heads are enumerated before devices, e.g. having
+ * two graphics cards, both with four heads, screen ID 5 addresses
+ * the second head on the second card.
+ *
+ * Returns a string representing the mime-type of the image format, or
+ * NULL upon error. The caller must free() the returned value.
+ */
+char *
+virDomainScreenshot(virDomainPtr domain,
+ virStreamPtr stream,
+ unsigned int screen,
+ unsigned int flags)
+{
+ VIR_DOMAIN_DEBUG(domain, "stream=%p, flags=%x", stream, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, NULL);
+ virCheckStreamGoto(stream, error);
+ virCheckReadOnlyGoto(domain->conn->flags, error);
+
+ if (domain->conn != stream->conn) {
+ virReportInvalidArg(stream,
+ _("stream in %s must match connection of domain
'%s'"),
+ __FUNCTION__, domain->name);
+ goto error;
+ }
+
+ if (domain->conn->driver->domainScreenshot) {
+ char *ret;
+ ret = domain->conn->driver->domainScreenshot(domain, stream,
+ screen, flags);
+
+ if (ret == NULL)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainShutdown:
+ * @domain: a domain object
+ *
+ * Shutdown a domain, the domain object is still usable thereafter, but
+ * the domain OS is being stopped. Note that the guest OS may ignore the
+ * request. Additionally, the hypervisor may check and support the domain
+ * 'on_poweroff' XML setting resulting in a domain that reboots instead of
+ * shutting down. For guests that react to a shutdown request, the differences
+ * from virDomainDestroy() are that the guests disk storage will be in a
+ * stable state rather than having the (virtual) power cord pulled, and
+ * this command returns as soon as the shutdown request is issued rather
+ * than blocking until the guest is no longer running.
+ *
+ * If the domain is transient and has any snapshot metadata (see
+ * virDomainSnapshotNum()), then that metadata will automatically
+ * be deleted when the domain quits.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainShutdown(virDomainPtr domain)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainShutdown) {
+ int ret;
+ ret = conn->driver->domainShutdown(domain);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainShutdownFlags:
+ * @domain: a domain object
+ * @flags: bitwise-OR of virDomainShutdownFlagValues
+ *
+ * Shutdown a domain, the domain object is still usable thereafter but
+ * the domain OS is being stopped. Note that the guest OS may ignore the
+ * request. Additionally, the hypervisor may check and support the domain
+ * 'on_poweroff' XML setting resulting in a domain that reboots instead of
+ * shutting down. For guests that react to a shutdown request, the differences
+ * from virDomainDestroy() are that the guest's disk storage will be in a
+ * stable state rather than having the (virtual) power cord pulled, and
+ * this command returns as soon as the shutdown request is issued rather
+ * than blocking until the guest is no longer running.
+ *
+ * If the domain is transient and has any snapshot metadata (see
+ * virDomainSnapshotNum()), then that metadata will automatically
+ * be deleted when the domain quits.
+ *
+ * If @flags is set to zero, then the hypervisor will choose the
+ * method of shutdown it considers best. To have greater control
+ * pass one or more of the virDomainShutdownFlagValues. The order
+ * in which the hypervisor tries each shutdown method is undefined,
+ * and a hypervisor is not required to support all methods.
+ *
+ * To use guest agent (VIR_DOMAIN_SHUTDOWN_GUEST_AGENT) the domain XML
+ * must have <channel> configured.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainShutdownFlags(virDomainPtr domain, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainShutdownFlags) {
+ int ret;
+ ret = conn->driver->domainShutdownFlags(domain, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainReboot:
+ * @domain: a domain object
+ * @flags: bitwise-OR of virDomainRebootFlagValues
+ *
+ * Reboot a domain, the domain object is still usable thereafter, but
+ * the domain OS is being stopped for a restart.
+ * Note that the guest OS may ignore the request.
+ * Additionally, the hypervisor may check and support the domain
+ * 'on_reboot' XML setting resulting in a domain that shuts down instead
+ * of rebooting.
+ *
+ * If @flags is set to zero, then the hypervisor will choose the
+ * method of shutdown it considers best. To have greater control
+ * pass one or more of the virDomainRebootFlagValues. The order
+ * in which the hypervisor tries each shutdown method is undefined,
+ * and a hypervisor is not required to support all methods.
+ *
+ * To use guest agent (VIR_DOMAIN_REBOOT_GUEST_AGENT) the domain XML
+ * must have <channel> configured.
+ *
+ * Due to implementation limitations in some drivers (the qemu driver,
+ * for instance) it is not advised to migrate or save a guest that is
+ * rebooting as a result of this API. Migrating such a guest can lead
+ * to a plain shutdown on the destination.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainReboot(virDomainPtr domain, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainReboot) {
+ int ret;
+ ret = conn->driver->domainReboot(domain, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainReset:
+ * @domain: a domain object
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Reset a domain immediately without any guest OS shutdown.
+ * Reset emulates the power reset button on a machine, where all
+ * hardware sees the RST line set and reinitializes internal state.
+ *
+ * Note that there is a risk of data loss caused by reset without any
+ * guest OS shutdown.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainReset(virDomainPtr domain, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainReset) {
+ int ret;
+ ret = conn->driver->domainReset(domain, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetName:
+ * @domain: a domain object
+ *
+ * Get the public name for that domain
+ *
+ * Returns a pointer to the name or NULL, the string need not be deallocated
+ * its lifetime will be the same as the domain object.
+ */
+const char *
+virDomainGetName(virDomainPtr domain)
+{
+ VIR_DEBUG("domain=%p", domain);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, NULL);
+
+ return domain->name;
+}
+
+
+/**
+ * virDomainGetUUID:
+ * @domain: a domain object
+ * @uuid: pointer to a VIR_UUID_BUFLEN bytes array
+ *
+ * Get the UUID for a domain
+ *
+ * Returns -1 in case of error, 0 in case of success
+ */
+int
+virDomainGetUUID(virDomainPtr domain, unsigned char *uuid)
+{
+ VIR_DOMAIN_DEBUG(domain, "uuid=%p", uuid);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ virCheckNonNullArgGoto(uuid, error);
+
+ memcpy(uuid, &domain->uuid[0], VIR_UUID_BUFLEN);
+
+ return 0;
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetUUIDString:
+ * @domain: a domain object
+ * @buf: pointer to a VIR_UUID_STRING_BUFLEN bytes array
+ *
+ * Get the UUID for a domain as string. For more information about
+ * UUID see RFC4122.
+ *
+ * Returns -1 in case of error, 0 in case of success
+ */
+int
+virDomainGetUUIDString(virDomainPtr domain, char *buf)
+{
+ VIR_DOMAIN_DEBUG(domain, "buf=%p", buf);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ virCheckNonNullArgGoto(buf, error);
+
+ virUUIDFormat(domain->uuid, buf);
+ return 0;
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetID:
+ * @domain: a domain object
+ *
+ * Get the hypervisor ID number for the domain
+ *
+ * Returns the domain ID number or (unsigned int) -1 in case of error
+ */
+unsigned int
+virDomainGetID(virDomainPtr domain)
+{
+ VIR_DOMAIN_DEBUG(domain);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, (unsigned int)-1);
+
+ return domain->id;
+}
+
+
+/**
+ * virDomainGetOSType:
+ * @domain: a domain object
+ *
+ * Get the type of domain operation system.
+ *
+ * Returns the new string or NULL in case of error, the string must be
+ * freed by the caller.
+ */
+char *
+virDomainGetOSType(virDomainPtr domain)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, NULL);
+ conn = domain->conn;
+
+ if (conn->driver->domainGetOSType) {
+ char *ret;
+ ret = conn->driver->domainGetOSType(domain);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainGetMaxMemory:
+ * @domain: a domain object or NULL
+ *
+ * Retrieve the maximum amount of physical memory allocated to a
+ * domain. If domain is NULL, then this get the amount of memory reserved
+ * to Domain0 i.e. the domain where the application runs.
+ *
+ * Returns the memory size in kibibytes (blocks of 1024 bytes), or 0 in
+ * case of error.
+ */
+unsigned long
+virDomainGetMaxMemory(virDomainPtr domain)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, 0);
+ conn = domain->conn;
+
+ if (conn->driver->domainGetMaxMemory) {
+ unsigned long long ret;
+ ret = conn->driver->domainGetMaxMemory(domain);
+ if (ret == 0)
+ goto error;
+ if ((unsigned long) ret != ret) {
+ virReportError(VIR_ERR_OVERFLOW, _("result too large: %llu"),
+ ret);
+ goto error;
+ }
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return 0;
+}
+
+
+/**
+ * virDomainSetMaxMemory:
+ * @domain: a domain object or NULL
+ * @memory: the memory size in kibibytes (blocks of 1024 bytes)
+ *
+ * Dynamically change the maximum amount of physical memory allocated to a
+ * domain. If domain is NULL, then this change the amount of memory reserved
+ * to Domain0 i.e. the domain where the application runs.
+ * This function may require privileged access to the hypervisor.
+ *
+ * This command is hypervisor-specific for whether active, persistent,
+ * or both configurations are changed; for more control, use
+ * virDomainSetMemoryFlags().
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "memory=%lu", memory);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonZeroArgGoto(memory, error);
+
+ if (conn->driver->domainSetMaxMemory) {
+ int ret;
+ ret = conn->driver->domainSetMaxMemory(domain, memory);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSetMemory:
+ * @domain: a domain object or NULL
+ * @memory: the memory size in kibibytes (blocks of 1024 bytes)
+ *
+ * Dynamically change the target amount of physical memory allocated to a
+ * domain. If domain is NULL, then this change the amount of memory reserved
+ * to Domain0 i.e. the domain where the application runs.
+ * This function may require privileged access to the hypervisor.
+ *
+ * This command only changes the runtime configuration of the domain,
+ * so can only be called on an active domain.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainSetMemory(virDomainPtr domain, unsigned long memory)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "memory=%lu", memory);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonZeroArgGoto(memory, error);
+
+ if (conn->driver->domainSetMemory) {
+ int ret;
+ ret = conn->driver->domainSetMemory(domain, memory);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSetMemoryFlags:
+ * @domain: a domain object or NULL
+ * @memory: the memory size in kibibytes (blocks of 1024 bytes)
+ * @flags: bitwise-OR of virDomainMemoryModFlags
+ *
+ * Dynamically change the target amount of physical memory allocated to a
+ * domain. If domain is NULL, then this change the amount of memory reserved
+ * to Domain0 i.e. the domain where the application runs.
+ * This function may require privileged access to the hypervisor.
+ *
+ * @flags may include VIR_DOMAIN_AFFECT_LIVE or VIR_DOMAIN_AFFECT_CONFIG.
+ * Both flags may be set. If VIR_DOMAIN_AFFECT_LIVE is set, the change affects
+ * a running domain and will fail if domain is not active.
+ * If VIR_DOMAIN_AFFECT_CONFIG is set, the change affects persistent state,
+ * and will fail for transient domains. If neither flag is specified
+ * (that is, @flags is VIR_DOMAIN_AFFECT_CURRENT), then an inactive domain
+ * modifies persistent setup, while an active domain is hypervisor-dependent
+ * on whether just live or both live and persistent state is changed.
+ * If VIR_DOMAIN_MEM_MAXIMUM is set, the change affects domain's maximum memory
+ * size rather than current memory size.
+ * Not all hypervisors can support all flag combinations.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virDomainSetMemoryFlags(virDomainPtr domain, unsigned long memory,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "memory=%lu, flags=%x", memory, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonZeroArgGoto(memory, error);
+
+ if (conn->driver->domainSetMemoryFlags) {
+ int ret;
+ ret = conn->driver->domainSetMemoryFlags(domain, memory, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSetMemoryStatsPeriod:
+ * @domain: a domain object or NULL
+ * @period: the period in seconds for stats collection
+ * @flags: bitwise-OR of virDomainMemoryModFlags
+ *
+ * Dynamically change the domain memory balloon driver statistics collection
+ * period. Use 0 to disable and a positive value to enable.
+ *
+ * @flags may include VIR_DOMAIN_AFFECT_LIVE or VIR_DOMAIN_AFFECT_CONFIG.
+ * Both flags may be set. If VIR_DOMAIN_AFFECT_LIVE is set, the change affects
+ * a running domain and will fail if domain is not active.
+ * If VIR_DOMAIN_AFFECT_CONFIG is set, the change affects persistent state,
+ * and will fail for transient domains. If neither flag is specified
+ * (that is, @flags is VIR_DOMAIN_AFFECT_CURRENT), then an inactive domain
+ * modifies persistent setup, while an active domain is hypervisor-dependent
+ * on whether just live or both live and persistent state is changed.
+ *
+ * Not all hypervisors can support all flag combinations.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virDomainSetMemoryStatsPeriod(virDomainPtr domain, int period,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "peroid=%d, flags=%x", period, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ /* This must be positive to set the balloon collection period */
+ virCheckNonNegativeArgGoto(period, error);
+
+ if (conn->driver->domainSetMemoryStatsPeriod) {
+ int ret;
+ ret = conn->driver->domainSetMemoryStatsPeriod(domain, period, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSetMemoryParameters:
+ * @domain: pointer to domain object
+ * @params: pointer to memory parameter objects
+ * @nparams: number of memory parameter (this value can be the same or
+ * less than the number of parameters supported)
+ * @flags: bitwise-OR of virDomainModificationImpact
+ *
+ * Change all or a subset of the memory tunables.
+ * This function may require privileged access to the hypervisor.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainSetMemoryParameters(virDomainPtr domain,
+ virTypedParameterPtr params,
+ int nparams, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
+ params, nparams, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(params, error);
+ virCheckPositiveArgGoto(nparams, error);
+
+ if (virTypedParameterValidateSet(conn, params, nparams) < 0)
+ goto error;
+
+ if (conn->driver->domainSetMemoryParameters) {
+ int ret;
+ ret = conn->driver->domainSetMemoryParameters(domain, params, nparams,
flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetMemoryParameters:
+ * @domain: pointer to domain object
+ * @params: pointer to memory parameter object
+ * (return value, allocated by the caller)
+ * @nparams: pointer to number of memory parameters; input and output
+ * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
+ *
+ * Get all memory parameters. On input, @nparams gives the size of the
+ * @params array; on output, @nparams gives how many slots were filled
+ * with parameter information, which might be less but will not exceed
+ * the input value.
+ *
+ * As a special case, calling with @params as NULL and @nparams as 0 on
+ * input will cause @nparams on output to contain the number of parameters
+ * supported by the hypervisor. The caller should then allocate @params
+ * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
+ * again.
+ *
+ * Here is a sample code snippet:
+ *
+ * if (virDomainGetMemoryParameters(dom, NULL, &nparams, 0) == 0 &&
+ * nparams != 0) {
+ * if ((params = malloc(sizeof(*params) * nparams)) == NULL)
+ * goto error;
+ * memset(params, 0, sizeof(*params) * nparams);
+ * if (virDomainGetMemoryParameters(dom, params, &nparams, 0))
+ * goto error;
+ * }
+ *
+ * This function may require privileged access to the hypervisor. This function
+ * expects the caller to allocate the @params.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainGetMemoryParameters(virDomainPtr domain,
+ virTypedParameterPtr params,
+ int *nparams, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
+ params, (nparams) ? *nparams : -1, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ virCheckNonNullArgGoto(nparams, error);
+ virCheckNonNegativeArgGoto(*nparams, error);
+ if (*nparams != 0)
+ virCheckNonNullArgGoto(params, error);
+
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_TYPED_PARAM_STRING))
+ flags |= VIR_TYPED_PARAM_STRING_OKAY;
+
+ /* At most one of these two flags should be set. */
+ if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
+ (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
+ virReportInvalidArg(flags,
+ _("flags 'affect live' and 'affect
config' in %s "
+ "are mutually exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+ conn = domain->conn;
+
+ if (conn->driver->domainGetMemoryParameters) {
+ int ret;
+ ret = conn->driver->domainGetMemoryParameters(domain, params, nparams,
flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSetNumaParameters:
+ * @domain: pointer to domain object
+ * @params: pointer to numa parameter objects
+ * @nparams: number of numa parameters (this value can be the same or
+ * less than the number of parameters supported)
+ * @flags: bitwise-OR of virDomainModificationImpact
+ *
+ * Change all or a subset of the numa tunables.
+ * This function may require privileged access to the hypervisor.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainSetNumaParameters(virDomainPtr domain,
+ virTypedParameterPtr params,
+ int nparams, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
+ params, nparams, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ virCheckReadOnlyGoto(domain->conn->flags, error);
+ virCheckNonNullArgGoto(params, error);
+ virCheckPositiveArgGoto(nparams, error);
+ if (virTypedParameterValidateSet(domain->conn, params, nparams) < 0)
+ goto error;
+
+ conn = domain->conn;
+
+ if (conn->driver->domainSetNumaParameters) {
+ int ret;
+ ret = conn->driver->domainSetNumaParameters(domain, params, nparams,
+ flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetNumaParameters:
+ * @domain: pointer to domain object
+ * @params: pointer to numa parameter object
+ * (return value, allocated by the caller)
+ * @nparams: pointer to number of numa parameters
+ * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
+ *
+ * Get all numa parameters. On input, @nparams gives the size of the
+ * @params array; on output, @nparams gives how many slots were filled
+ * with parameter information, which might be less but will not exceed
+ * the input value.
+ *
+ * As a special case, calling with @params as NULL and @nparams as 0 on
+ * input will cause @nparams on output to contain the number of parameters
+ * supported by the hypervisor. The caller should then allocate @params
+ * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
+ * again.
+ *
+ * See virDomainGetMemoryParameters() for an equivalent usage example.
+ *
+ * This function may require privileged access to the hypervisor. This function
+ * expects the caller to allocate the @params.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainGetNumaParameters(virDomainPtr domain,
+ virTypedParameterPtr params,
+ int *nparams, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
+ params, (nparams) ? *nparams : -1, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ virCheckNonNullArgGoto(nparams, error);
+ virCheckNonNegativeArgGoto(*nparams, error);
+ if (*nparams != 0)
+ virCheckNonNullArgGoto(params, error);
+
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_TYPED_PARAM_STRING))
+ flags |= VIR_TYPED_PARAM_STRING_OKAY;
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetNumaParameters) {
+ int ret;
+ ret = conn->driver->domainGetNumaParameters(domain, params, nparams,
+ flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSetBlkioParameters:
+ * @domain: pointer to domain object
+ * @params: pointer to blkio parameter objects
+ * @nparams: number of blkio parameters (this value can be the same or
+ * less than the number of parameters supported)
+ * @flags: bitwise-OR of virDomainModificationImpact
+ *
+ * Change all or a subset of the blkio tunables.
+ * This function may require privileged access to the hypervisor.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainSetBlkioParameters(virDomainPtr domain,
+ virTypedParameterPtr params,
+ int nparams, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
+ params, nparams, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(params, error);
+ virCheckNonNegativeArgGoto(nparams, error);
+
+ if (virTypedParameterValidateSet(conn, params, nparams) < 0)
+ goto error;
+
+ if (conn->driver->domainSetBlkioParameters) {
+ int ret;
+ ret = conn->driver->domainSetBlkioParameters(domain, params, nparams,
flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetBlkioParameters:
+ * @domain: pointer to domain object
+ * @params: pointer to blkio parameter object
+ * (return value, allocated by the caller)
+ * @nparams: pointer to number of blkio parameters; input and output
+ * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
+ *
+ * Get all blkio parameters. On input, @nparams gives the size of the
+ * @params array; on output, @nparams gives how many slots were filled
+ * with parameter information, which might be less but will not exceed
+ * the input value.
+ *
+ * As a special case, calling with @params as NULL and @nparams as 0 on
+ * input will cause @nparams on output to contain the number of parameters
+ * supported by the hypervisor. The caller should then allocate @params
+ * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
+ * again.
+ *
+ * See virDomainGetMemoryParameters() for an equivalent usage example.
+ *
+ * This function may require privileged access to the hypervisor. This function
+ * expects the caller to allocate the @params.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainGetBlkioParameters(virDomainPtr domain,
+ virTypedParameterPtr params,
+ int *nparams, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
+ params, (nparams) ? *nparams : -1, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ virCheckNonNullArgGoto(nparams, error);
+ virCheckNonNegativeArgGoto(*nparams, error);
+ if (*nparams != 0)
+ virCheckNonNullArgGoto(params, error);
+
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_TYPED_PARAM_STRING))
+ flags |= VIR_TYPED_PARAM_STRING_OKAY;
+
+ /* At most one of these two flags should be set. */
+ if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
+ (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
+ virReportInvalidArg(flags,
+ _("flags 'affect live' and 'affect
config' in %s "
+ "are mutually exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+ conn = domain->conn;
+
+ if (conn->driver->domainGetBlkioParameters) {
+ int ret;
+ ret = conn->driver->domainGetBlkioParameters(domain, params, nparams,
flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetInfo:
+ * @domain: a domain object
+ * @info: pointer to a virDomainInfo structure allocated by the user
+ *
+ * Extract information about a domain. Note that if the connection
+ * used to get the domain is limited only a partial set of the information
+ * can be extracted.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "info=%p", info);
+
+ virResetLastError();
+
+ if (info)
+ memset(info, 0, sizeof(*info));
+
+ virCheckDomainReturn(domain, -1);
+ virCheckNonNullArgGoto(info, error);
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetInfo) {
+ int ret;
+ ret = conn->driver->domainGetInfo(domain, info);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetState:
+ * @domain: a domain object
+ * @state: returned state of the domain (one of virDomainState)
+ * @reason: returned reason which led to @state (one of virDomain*Reason
+ * corresponding to the current state); it is allowed to be NULL
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Extract domain state. Each state can be accompanied with a reason (if known)
+ * which led to the state.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainGetState(virDomainPtr domain,
+ int *state,
+ int *reason,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "state=%p, reason=%p, flags=%x",
+ state, reason, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ virCheckNonNullArgGoto(state, error);
+
+ conn = domain->conn;
+ if (conn->driver->domainGetState) {
+ int ret;
+ ret = conn->driver->domainGetState(domain, state, reason, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetControlInfo:
+ * @domain: a domain object
+ * @info: pointer to a virDomainControlInfo structure allocated by the user
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Extract details about current state of control interface to a domain.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainGetControlInfo(virDomainPtr domain,
+ virDomainControlInfoPtr info,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "info=%p, flags=%x", info, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ virCheckNonNullArgGoto(info, error);
+
+ conn = domain->conn;
+ if (conn->driver->domainGetControlInfo) {
+ int ret;
+ ret = conn->driver->domainGetControlInfo(domain, info, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetXMLDesc:
+ * @domain: a domain object
+ * @flags: bitwise-OR of virDomainXMLFlags
+ *
+ * Provide an XML description of the domain. The description may be reused
+ * later to relaunch the domain with virDomainCreateXML().
+ *
+ * No security-sensitive data will be included unless @flags contains
+ * VIR_DOMAIN_XML_SECURE; this flag is rejected on read-only
+ * connections. If @flags includes VIR_DOMAIN_XML_INACTIVE, then the
+ * XML represents the configuration that will be used on the next boot
+ * of a persistent domain; otherwise, the configuration represents the
+ * currently running domain. If @flags contains
+ * VIR_DOMAIN_XML_UPDATE_CPU, then the portion of the domain XML
+ * describing CPU capabilities is modified to match actual
+ * capabilities of the host.
+ *
+ * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
+ * the caller must free() the returned value.
+ */
+char *
+virDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, NULL);
+ conn = domain->conn;
+
+ if ((conn->flags & VIR_CONNECT_RO) && (flags &
VIR_DOMAIN_XML_SECURE)) {
+ virReportError(VIR_ERR_OPERATION_DENIED, "%s",
+ _("virDomainGetXMLDesc with secure flag"));
+ goto error;
+ }
+
+ if (conn->driver->domainGetXMLDesc) {
+ char *ret;
+ ret = conn->driver->domainGetXMLDesc(domain, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return NULL;
+}
+
+
+/**
+ * virConnectDomainXMLFromNative:
+ * @conn: a connection object
+ * @nativeFormat: configuration format importing from
+ * @nativeConfig: the configuration data to import
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Reads native configuration data describing a domain, and
+ * generates libvirt domain XML. The format of the native
+ * data is hypervisor dependant.
+ *
+ * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
+ * the caller must free() the returned value.
+ */
+char *
+virConnectDomainXMLFromNative(virConnectPtr conn,
+ const char *nativeFormat,
+ const char *nativeConfig,
+ unsigned int flags)
+{
+ VIR_DEBUG("conn=%p, format=%s, config=%s, flags=%x",
+ conn, nativeFormat, nativeConfig, flags);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, NULL);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ virCheckNonNullArgGoto(nativeFormat, error);
+ virCheckNonNullArgGoto(nativeConfig, error);
+
+ if (conn->driver->connectDomainXMLFromNative) {
+ char *ret;
+ ret = conn->driver->connectDomainXMLFromNative(conn,
+ nativeFormat,
+ nativeConfig,
+ flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/**
+ * virConnectDomainXMLToNative:
+ * @conn: a connection object
+ * @nativeFormat: configuration format exporting to
+ * @domainXml: the domain configuration to export
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Reads a domain XML configuration document, and generates
+ * a native configuration file describing the domain.
+ * The format of the native data is hypervisor dependant.
+ *
+ * Returns a 0 terminated UTF-8 encoded native config datafile, or NULL in case of
error.
+ * the caller must free() the returned value.
+ */
+char *
+virConnectDomainXMLToNative(virConnectPtr conn,
+ const char *nativeFormat,
+ const char *domainXml,
+ unsigned int flags)
+{
+ VIR_DEBUG("conn=%p, format=%s, xml=%s, flags=%x",
+ conn, nativeFormat, domainXml, flags);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, NULL);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ virCheckNonNullArgGoto(nativeFormat, error);
+ virCheckNonNullArgGoto(domainXml, error);
+
+ if (conn->driver->connectDomainXMLToNative) {
+ char *ret;
+ ret = conn->driver->connectDomainXMLToNative(conn,
+ nativeFormat,
+ domainXml,
+ flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/*
+ * Sequence v1:
+ *
+ * Dst: Prepare
+ * - Get ready to accept incoming VM
+ * - Generate optional cookie to pass to src
+ *
+ * Src: Perform
+ * - Start migration and wait for send completion
+ * - Kill off VM if successful, resume if failed
+ *
+ * Dst: Finish
+ * - Wait for recv completion and check status
+ * - Kill off VM if unsuccessful
+ *
+ */
+static virDomainPtr
+virDomainMigrateVersion1(virDomainPtr domain,
+ virConnectPtr dconn,
+ unsigned long flags,
+ const char *dname,
+ const char *uri,
+ unsigned long bandwidth)
+{
+ virDomainPtr ddomain = NULL;
+ char *uri_out = NULL;
+ char *cookie = NULL;
+ int cookielen = 0, ret;
+ virDomainInfo info;
+ unsigned int destflags;
+
+ VIR_DOMAIN_DEBUG(domain,
+ "dconn=%p, flags=%lx, dname=%s, uri=%s, bandwidth=%lu",
+ dconn, flags, NULLSTR(dname), NULLSTR(uri), bandwidth);
+
+ ret = virDomainGetInfo(domain, &info);
+ if (ret == 0 && info.state == VIR_DOMAIN_PAUSED)
+ flags |= VIR_MIGRATE_PAUSED;
+
+ destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR |
+ VIR_MIGRATE_AUTO_CONVERGE);
+
+ /* Prepare the migration.
+ *
+ * The destination host may return a cookie, or leave cookie as
+ * NULL.
+ *
+ * The destination host MUST set uri_out if uri_in is NULL.
+ *
+ * If uri_in is non-NULL, then the destination host may modify
+ * the URI by setting uri_out. If it does not wish to modify
+ * the URI, it should leave uri_out as NULL.
+ */
+ if (dconn->driver->domainMigratePrepare
+ (dconn, &cookie, &cookielen, uri, &uri_out, destflags, dname,
+ bandwidth) == -1)
+ goto done;
+
+ if (uri == NULL && uri_out == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("domainMigratePrepare did not set uri"));
+ goto done;
+ }
+ if (uri_out)
+ uri = uri_out; /* Did domainMigratePrepare change URI? */
+
+ /* Perform the migration. The driver isn't supposed to return
+ * until the migration is complete.
+ */
+ if (domain->conn->driver->domainMigratePerform
+ (domain, cookie, cookielen, uri, flags, dname, bandwidth) == -1)
+ goto done;
+
+ /* Get the destination domain and return it or error.
+ * 'domain' no longer actually exists at this point
+ * (or so we hope), but we still use the object in memory
+ * in order to get the name.
+ */
+ dname = dname ? dname : domain->name;
+ if (dconn->driver->domainMigrateFinish)
+ ddomain = dconn->driver->domainMigrateFinish
+ (dconn, dname, cookie, cookielen, uri, destflags);
+ else
+ ddomain = virDomainLookupByName(dconn, dname);
+
+ done:
+ VIR_FREE(uri_out);
+ VIR_FREE(cookie);
+ return ddomain;
+}
+
+
+/*
+ * Sequence v2:
+ *
+ * Src: DumpXML
+ * - Generate XML to pass to dst
+ *
+ * Dst: Prepare
+ * - Get ready to accept incoming VM
+ * - Generate optional cookie to pass to src
+ *
+ * Src: Perform
+ * - Start migration and wait for send completion
+ * - Kill off VM if successful, resume if failed
+ *
+ * Dst: Finish
+ * - Wait for recv completion and check status
+ * - Kill off VM if unsuccessful
+ *
+ */
+static virDomainPtr
+virDomainMigrateVersion2(virDomainPtr domain,
+ virConnectPtr dconn,
+ unsigned long flags,
+ const char *dname,
+ const char *uri,
+ unsigned long bandwidth)
+{
+ virDomainPtr ddomain = NULL;
+ char *uri_out = NULL;
+ char *cookie = NULL;
+ char *dom_xml = NULL;
+ int cookielen = 0, ret;
+ virDomainInfo info;
+ virErrorPtr orig_err = NULL;
+ unsigned int getxml_flags = 0;
+ int cancelled;
+ unsigned long destflags;
+
+ VIR_DOMAIN_DEBUG(domain,
+ "dconn=%p, flags=%lx, dname=%s, uri=%s, bandwidth=%lu",
+ dconn, flags, NULLSTR(dname), NULLSTR(uri), bandwidth);
+
+ /* Prepare the migration.
+ *
+ * The destination host may return a cookie, or leave cookie as
+ * NULL.
+ *
+ * The destination host MUST set uri_out if uri_in is NULL.
+ *
+ * If uri_in is non-NULL, then the destination host may modify
+ * the URI by setting uri_out. If it does not wish to modify
+ * the URI, it should leave uri_out as NULL.
+ */
+
+ /* In version 2 of the protocol, the prepare step is slightly
+ * different. We fetch the domain XML of the source domain
+ * and pass it to Prepare2.
+ */
+ if (!domain->conn->driver->domainGetXMLDesc) {
+ virReportUnsupportedError();
+ return NULL;
+ }
+
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_XML_MIGRATABLE)) {
+ getxml_flags |= VIR_DOMAIN_XML_MIGRATABLE;
+ } else {
+ getxml_flags |= VIR_DOMAIN_XML_SECURE | VIR_DOMAIN_XML_UPDATE_CPU;
+ }
+
+ dom_xml = domain->conn->driver->domainGetXMLDesc(domain, getxml_flags);
+ if (!dom_xml)
+ return NULL;
+
+ ret = virDomainGetInfo(domain, &info);
+ if (ret == 0 && info.state == VIR_DOMAIN_PAUSED)
+ flags |= VIR_MIGRATE_PAUSED;
+
+ destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR |
+ VIR_MIGRATE_AUTO_CONVERGE);
+
+ VIR_DEBUG("Prepare2 %p flags=%lx", dconn, destflags);
+ ret = dconn->driver->domainMigratePrepare2
+ (dconn, &cookie, &cookielen, uri, &uri_out, destflags, dname,
+ bandwidth, dom_xml);
+ VIR_FREE(dom_xml);
+ if (ret == -1)
+ goto done;
+
+ if (uri == NULL && uri_out == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("domainMigratePrepare2 did not set uri"));
+ cancelled = 1;
+ /* Make sure Finish doesn't overwrite the error */
+ orig_err = virSaveLastError();
+ goto finish;
+ }
+ if (uri_out)
+ uri = uri_out; /* Did domainMigratePrepare2 change URI? */
+
+ /* Perform the migration. The driver isn't supposed to return
+ * until the migration is complete.
+ */
+ VIR_DEBUG("Perform %p", domain->conn);
+ ret = domain->conn->driver->domainMigratePerform
+ (domain, cookie, cookielen, uri, flags, dname, bandwidth);
+
+ /* Perform failed. Make sure Finish doesn't overwrite the error */
+ if (ret < 0)
+ orig_err = virSaveLastError();
+
+ /* If Perform returns < 0, then we need to cancel the VM
+ * startup on the destination
+ */
+ cancelled = ret < 0 ? 1 : 0;
+
+ finish:
+ /* In version 2 of the migration protocol, we pass the
+ * status code from the sender to the destination host,
+ * so it can do any cleanup if the migration failed.
+ */
+ dname = dname ? dname : domain->name;
+ VIR_DEBUG("Finish2 %p ret=%d", dconn, ret);
+ ddomain = dconn->driver->domainMigrateFinish2
+ (dconn, dname, cookie, cookielen, uri, destflags, cancelled);
+ if (cancelled && ddomain)
+ VIR_ERROR(_("finish step ignored that migration was cancelled"));
+
+ done:
+ if (orig_err) {
+ virSetError(orig_err);
+ virFreeError(orig_err);
+ }
+ VIR_FREE(uri_out);
+ VIR_FREE(cookie);
+ return ddomain;
+}
+
+
+/*
+ * Sequence v3:
+ *
+ * Src: Begin
+ * - Generate XML to pass to dst
+ * - Generate optional cookie to pass to dst
+ *
+ * Dst: Prepare
+ * - Get ready to accept incoming VM
+ * - Generate optional cookie to pass to src
+ *
+ * Src: Perform
+ * - Start migration and wait for send completion
+ * - Generate optional cookie to pass to dst
+ *
+ * Dst: Finish
+ * - Wait for recv completion and check status
+ * - Kill off VM if failed, resume if success
+ * - Generate optional cookie to pass to src
+ *
+ * Src: Confirm
+ * - Kill off VM if success, resume if failed
+ *
+ * If useParams is true, params and nparams contain migration parameters and
+ * we know it's safe to call the API which supports extensible parameters.
+ * Otherwise, we have to use xmlin, dname, uri, and bandwidth and pass them
+ * to the old-style APIs.
+ */
+static virDomainPtr
+virDomainMigrateVersion3Full(virDomainPtr domain,
+ virConnectPtr dconn,
+ const char *xmlin,
+ const char *dname,
+ const char *uri,
+ unsigned long long bandwidth,
+ virTypedParameterPtr params,
+ int nparams,
+ bool useParams,
+ unsigned int flags)
+{
+ virDomainPtr ddomain = NULL;
+ char *uri_out = NULL;
+ char *cookiein = NULL;
+ char *cookieout = NULL;
+ char *dom_xml = NULL;
+ int cookieinlen = 0;
+ int cookieoutlen = 0;
+ int ret;
+ virDomainInfo info;
+ virErrorPtr orig_err = NULL;
+ int cancelled = 1;
+ unsigned long protection = 0;
+ bool notify_source = true;
+ unsigned int destflags;
+ int state;
+ virTypedParameterPtr tmp;
+
+ VIR_DOMAIN_DEBUG(domain,
+ "dconn=%p, xmlin=%s, dname=%s, uri=%s, bandwidth=%llu, "
+ "params=%p, nparams=%d, useParams=%d, flags=%x",
+ dconn, NULLSTR(xmlin), NULLSTR(dname), NULLSTR(uri),
+ bandwidth, params, nparams, useParams, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ if ((!useParams &&
+ (!domain->conn->driver->domainMigrateBegin3 ||
+ !domain->conn->driver->domainMigratePerform3 ||
+ !domain->conn->driver->domainMigrateConfirm3 ||
+ !dconn->driver->domainMigratePrepare3 ||
+ !dconn->driver->domainMigrateFinish3)) ||
+ (useParams &&
+ (!domain->conn->driver->domainMigrateBegin3Params ||
+ !domain->conn->driver->domainMigratePerform3Params ||
+ !domain->conn->driver->domainMigrateConfirm3Params ||
+ !dconn->driver->domainMigratePrepare3Params ||
+ !dconn->driver->domainMigrateFinish3Params))) {
+ virReportUnsupportedError();
+ return NULL;
+ }
+
+ if (virTypedParamsCopy(&tmp, params, nparams) < 0)
+ return NULL;
+ params = tmp;
+
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION))
+ protection = VIR_MIGRATE_CHANGE_PROTECTION;
+
+ VIR_DEBUG("Begin3 %p", domain->conn);
+ if (useParams) {
+ dom_xml = domain->conn->driver->domainMigrateBegin3Params
+ (domain, params, nparams, &cookieout, &cookieoutlen,
+ flags | protection);
+ } else {
+ dom_xml = domain->conn->driver->domainMigrateBegin3
+ (domain, xmlin, &cookieout, &cookieoutlen,
+ flags | protection, dname, bandwidth);
+ }
+ if (!dom_xml)
+ goto done;
+
+ if (useParams) {
+ /* If source is new enough to support extensible migration parameters,
+ * it's certainly new enough to support virDomainGetState. */
+ ret = virDomainGetState(domain, &state, NULL, 0);
+ } else {
+ ret = virDomainGetInfo(domain, &info);
+ state = info.state;
+ }
+ if (ret == 0 && state == VIR_DOMAIN_PAUSED)
+ flags |= VIR_MIGRATE_PAUSED;
+
+ destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR |
+ VIR_MIGRATE_AUTO_CONVERGE);
+
+ VIR_DEBUG("Prepare3 %p flags=%x", dconn, destflags);
+ cookiein = cookieout;
+ cookieinlen = cookieoutlen;
+ cookieout = NULL;
+ cookieoutlen = 0;
+ if (useParams) {
+ if (virTypedParamsReplaceString(¶ms, &nparams,
+ VIR_MIGRATE_PARAM_DEST_XML,
+ dom_xml) < 0)
+ goto done;
+ ret = dconn->driver->domainMigratePrepare3Params
+ (dconn, params, nparams, cookiein, cookieinlen,
+ &cookieout, &cookieoutlen, &uri_out, destflags);
+ } else {
+ ret = dconn->driver->domainMigratePrepare3
+ (dconn, cookiein, cookieinlen, &cookieout, &cookieoutlen,
+ uri, &uri_out, destflags, dname, bandwidth, dom_xml);
+ }
+ if (ret == -1) {
+ if (protection) {
+ /* Begin already started a migration job so we need to cancel it by
+ * calling Confirm while making sure it doesn't overwrite the error
+ */
+ orig_err = virSaveLastError();
+ goto confirm;
+ } else {
+ goto done;
+ }
+ }
+
+ /* Did domainMigratePrepare3 change URI? */
+ if (uri_out) {
+ uri = uri_out;
+ if (useParams &&
+ virTypedParamsReplaceString(¶ms, &nparams,
+ VIR_MIGRATE_PARAM_URI,
+ uri_out) < 0) {
+ cancelled = 1;
+ orig_err = virSaveLastError();
+ goto finish;
+ }
+ } else if (!uri &&
+ virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_URI, &uri) <= 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("domainMigratePrepare3 did not set uri"));
+ cancelled = 1;
+ orig_err = virSaveLastError();
+ goto finish;
+ }
+
+ if (flags & VIR_MIGRATE_OFFLINE) {
+ VIR_DEBUG("Offline migration, skipping Perform phase");
+ VIR_FREE(cookieout);
+ cookieoutlen = 0;
+ cancelled = 0;
+ goto finish;
+ }
+
+ /* Perform the migration. The driver isn't supposed to return
+ * until the migration is complete. The src VM should remain
+ * running, but in paused state until the destination can
+ * confirm migration completion.
+ */
+ VIR_DEBUG("Perform3 %p uri=%s", domain->conn, uri);
+ VIR_FREE(cookiein);
+ cookiein = cookieout;
+ cookieinlen = cookieoutlen;
+ cookieout = NULL;
+ cookieoutlen = 0;
+ /* dconnuri not relevant in non-P2P modes, so left NULL here */
+ if (useParams) {
+ ret = domain->conn->driver->domainMigratePerform3Params
+ (domain, NULL, params, nparams, cookiein, cookieinlen,
+ &cookieout, &cookieoutlen, flags | protection);
+ } else {
+ ret = domain->conn->driver->domainMigratePerform3
+ (domain, NULL, cookiein, cookieinlen,
+ &cookieout, &cookieoutlen, NULL,
+ uri, flags | protection, dname, bandwidth);
+ }
+
+ /* Perform failed. Make sure Finish doesn't overwrite the error */
+ if (ret < 0) {
+ orig_err = virSaveLastError();
+ /* Perform failed so we don't need to call confirm to let source know
+ * about the failure.
+ */
+ notify_source = false;
+ }
+
+ /* If Perform returns < 0, then we need to cancel the VM
+ * startup on the destination
+ */
+ cancelled = ret < 0 ? 1 : 0;
+
+ finish:
+ /*
+ * The status code from the source is passed to the destination.
+ * The dest can cleanup if the source indicated it failed to
+ * send all migration data. Returns NULL for ddomain if
+ * the dest was unable to complete migration.
+ */
+ VIR_DEBUG("Finish3 %p ret=%d", dconn, ret);
+ VIR_FREE(cookiein);
+ cookiein = cookieout;
+ cookieinlen = cookieoutlen;
+ cookieout = NULL;
+ cookieoutlen = 0;
+ if (useParams) {
+ if (virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_DEST_NAME, NULL) <= 0
&&
+ virTypedParamsReplaceString(¶ms, &nparams,
+ VIR_MIGRATE_PARAM_DEST_NAME,
+ domain->name) < 0) {
+ ddomain = NULL;
+ } else {
+ ddomain = dconn->driver->domainMigrateFinish3Params
+ (dconn, params, nparams, cookiein, cookieinlen,
+ &cookieout, &cookieoutlen, destflags, cancelled);
+ }
+ } else {
+ dname = dname ? dname : domain->name;
+ ddomain = dconn->driver->domainMigrateFinish3
+ (dconn, dname, cookiein, cookieinlen, &cookieout, &cookieoutlen,
+ NULL, uri, destflags, cancelled);
+ }
+ if (cancelled && ddomain)
+ VIR_ERROR(_("finish step ignored that migration was cancelled"));
+
+ /* If ddomain is NULL, then we were unable to start
+ * the guest on the target, and must restart on the
+ * source. There is a small chance that the ddomain
+ * is NULL due to an RPC failure, in which case
+ * ddomain could in fact be running on the dest.
+ * The lock manager plugins should take care of
+ * safety in this scenario.
+ */
+ cancelled = ddomain == NULL ? 1 : 0;
+
+ /* If finish3 set an error, and we don't have an earlier
+ * one we need to preserve it in case confirm3 overwrites
+ */
+ if (!orig_err)
+ orig_err = virSaveLastError();
+
+ confirm:
+ /*
+ * If cancelled, then src VM will be restarted, else it will be killed.
+ * Don't do this if migration failed on source and thus it was already
+ * cancelled there.
+ */
+ if (notify_source) {
+ VIR_DEBUG("Confirm3 %p ret=%d domain=%p", domain->conn, ret,
domain);
+ VIR_FREE(cookiein);
+ cookiein = cookieout;
+ cookieinlen = cookieoutlen;
+ cookieout = NULL;
+ cookieoutlen = 0;
+ if (useParams) {
+ ret = domain->conn->driver->domainMigrateConfirm3Params
+ (domain, params, nparams, cookiein, cookieinlen,
+ flags | protection, cancelled);
+ } else {
+ ret = domain->conn->driver->domainMigrateConfirm3
+ (domain, cookiein, cookieinlen,
+ flags | protection, cancelled);
+ }
+ /* If Confirm3 returns -1, there's nothing more we can
+ * do, but fortunately worst case is that there is a
+ * domain left in 'paused' state on source.
+ */
+ if (ret < 0) {
+ VIR_WARN("Guest %s probably left in 'paused' state on
source",
+ domain->name);
+ }
+ }
+
+ done:
+ if (orig_err) {
+ virSetError(orig_err);
+ virFreeError(orig_err);
+ }
+ VIR_FREE(dom_xml);
+ VIR_FREE(uri_out);
+ VIR_FREE(cookiein);
+ VIR_FREE(cookieout);
+ virTypedParamsFree(params, nparams);
+ return ddomain;
+}
+
+
+static virDomainPtr
+virDomainMigrateVersion3(virDomainPtr domain,
+ virConnectPtr dconn,
+ const char *xmlin,
+ unsigned long flags,
+ const char *dname,
+ const char *uri,
+ unsigned long bandwidth)
+{
+ return virDomainMigrateVersion3Full(domain, dconn, xmlin, dname, uri,
+ bandwidth, NULL, 0, false, flags);
+}
+
+
+static virDomainPtr
+virDomainMigrateVersion3Params(virDomainPtr domain,
+ virConnectPtr dconn,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags)
+{
+ return virDomainMigrateVersion3Full(domain, dconn, NULL, NULL, NULL, 0,
+ params, nparams, true, flags);
+}
+
+
+/*
+ * In normal migration, the libvirt client co-ordinates communication
+ * between the 2 libvirtd instances on source & dest hosts.
+ *
+ * In this peer-2-peer migration alternative, the libvirt client
+ * only talks to the source libvirtd instance. The source libvirtd
+ * then opens its own connection to the destination and co-ordinates
+ * migration itself.
+ *
+ * If useParams is true, params and nparams contain migration parameters and
+ * we know it's safe to call the API which supports extensible parameters.
+ * Otherwise, we have to use xmlin, dname, uri, and bandwidth and pass them
+ * to the old-style APIs.
+ */
+static int
+virDomainMigratePeer2PeerFull(virDomainPtr domain,
+ const char *dconnuri,
+ const char *xmlin,
+ const char *dname,
+ const char *uri,
+ unsigned long long bandwidth,
+ virTypedParameterPtr params,
+ int nparams,
+ bool useParams,
+ unsigned int flags)
+{
+ virURIPtr tempuri = NULL;
+
+ VIR_DOMAIN_DEBUG(domain,
+ "dconnuri=%s, xmlin=%s, dname=%s, uri=%s, bandwidth=%llu
"
+ "params=%p, nparams=%d, useParams=%d, flags=%x",
+ dconnuri, NULLSTR(xmlin), NULLSTR(dname), NULLSTR(uri),
+ bandwidth, params, nparams, useParams, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ if ((useParams &&
!domain->conn->driver->domainMigratePerform3Params) ||
+ (!useParams &&
+ !domain->conn->driver->domainMigratePerform &&
+ !domain->conn->driver->domainMigratePerform3)) {
+ virReportUnsupportedError();
+ return -1;
+ }
+
+ if (!(tempuri = virURIParse(dconnuri)))
+ return -1;
+ if (!tempuri->server || STRPREFIX(tempuri->server, "localhost")) {
+ virReportInvalidArg(dconnuri,
+ _("unable to parse server from dconnuri in %s"),
+ __FUNCTION__);
+ virURIFree(tempuri);
+ return -1;
+ }
+ virURIFree(tempuri);
+
+ if (useParams) {
+ VIR_DEBUG("Using migration protocol 3 with extensible parameters");
+ return domain->conn->driver->domainMigratePerform3Params
+ (domain, dconnuri, params, nparams,
+ NULL, 0, NULL, NULL, flags);
+ } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_V3)) {
+ VIR_DEBUG("Using migration protocol 3");
+ return domain->conn->driver->domainMigratePerform3
+ (domain, xmlin, NULL, 0, NULL, NULL, dconnuri,
+ uri, flags, dname, bandwidth);
+ } else {
+ VIR_DEBUG("Using migration protocol 2");
+ if (xmlin) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Unable to change target guest XML during "
+ "migration"));
+ return -1;
+ }
+ if (uri) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to override peer2peer migration URI"));
+ return -1;
+ }
+ return domain->conn->driver->domainMigratePerform
+ (domain, NULL, 0, dconnuri, flags, dname, bandwidth);
+ }
+}
+
+
+static int
+virDomainMigratePeer2Peer(virDomainPtr domain,
+ const char *xmlin,
+ unsigned long flags,
+ const char *dname,
+ const char *dconnuri,
+ const char *uri,
+ unsigned long bandwidth)
+{
+ return virDomainMigratePeer2PeerFull(domain, dconnuri, xmlin, dname, uri,
+ bandwidth, NULL, 0, false, flags);
+}
+
+
+static int
+virDomainMigratePeer2PeerParams(virDomainPtr domain,
+ const char *dconnuri,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags)
+{
+ return virDomainMigratePeer2PeerFull(domain, dconnuri, NULL, NULL, NULL, 0,
+ params, nparams, true, flags);
+}
+
+
+/*
+ * In normal migration, the libvirt client co-ordinates communication
+ * between the 2 libvirtd instances on source & dest hosts.
+ *
+ * Some hypervisors support an alternative, direct migration where
+ * there is no requirement for a libvirtd instance on the dest host.
+ * In this case
+ *
+ * eg, XenD can talk direct to XenD, so libvirtd on dest does not
+ * need to be involved at all, or even running
+ */
+static int
+virDomainMigrateDirect(virDomainPtr domain,
+ const char *xmlin,
+ unsigned long flags,
+ const char *dname,
+ const char *uri,
+ unsigned long bandwidth)
+{
+ VIR_DOMAIN_DEBUG(domain,
+ "xmlin=%s, flags=%lx, dname=%s, uri=%s, bandwidth=%lu",
+ NULLSTR(xmlin), flags, NULLSTR(dname), NULLSTR(uri),
+ bandwidth);
+
+ if (!domain->conn->driver->domainMigratePerform) {
+ virReportUnsupportedError();
+ return -1;
+ }
+
+ /* Perform the migration. The driver isn't supposed to return
+ * until the migration is complete.
+ */
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_V3)) {
+ VIR_DEBUG("Using migration protocol 3");
+ /* dconn URI not relevant in direct migration, since no
+ * target libvirtd is involved */
+ return domain->conn->driver->domainMigratePerform3(domain,
+ xmlin,
+ NULL, /* cookiein */
+ 0, /* cookieinlen */
+ NULL, /* cookieoutlen */
+ NULL, /* cookieoutlen */
+ NULL, /* dconnuri */
+ uri,
+ flags,
+ dname,
+ bandwidth);
+ } else {
+ VIR_DEBUG("Using migration protocol 2");
+ if (xmlin) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Unable to change target guest XML during
migration"));
+ return -1;
+ }
+ return domain->conn->driver->domainMigratePerform(domain,
+ NULL, /* cookie */
+ 0, /* cookielen */
+ uri,
+ flags,
+ dname,
+ bandwidth);
+ }
+}
+
+
+/**
+ * virDomainMigrate:
+ * @domain: a domain object
+ * @dconn: destination host (a connection object)
+ * @flags: bitwise-OR of virDomainMigrateFlags
+ * @dname: (optional) rename domain to this at destination
+ * @uri: (optional) dest hostname/URI as seen from the source host
+ * @bandwidth: (optional) specify migration bandwidth limit in MiB/s
+ *
+ * Migrate the domain object from its current host to the destination
+ * host given by dconn (a connection to the destination host).
+ *
+ * Flags may be one of more of the following:
+ * VIR_MIGRATE_LIVE Do not pause the VM during migration
+ * VIR_MIGRATE_PEER2PEER Direct connection between source & destination hosts
+ * VIR_MIGRATE_TUNNELLED Tunnel migration data over the libvirt RPC channel
+ * VIR_MIGRATE_PERSIST_DEST If the migration is successful, persist the domain
+ * on the destination host.
+ * VIR_MIGRATE_UNDEFINE_SOURCE If the migration is successful, undefine the
+ * domain on the source host.
+ * VIR_MIGRATE_PAUSED Leave the domain suspended on the remote side.
+ * VIR_MIGRATE_NON_SHARED_DISK Migration with non-shared storage with full
+ * disk copy
+ * VIR_MIGRATE_NON_SHARED_INC Migration with non-shared storage with
+ * incremental disk copy
+ * VIR_MIGRATE_CHANGE_PROTECTION Protect against domain configuration
+ * changes during the migration process (set
+ * automatically when supported).
+ * VIR_MIGRATE_UNSAFE Force migration even if it is considered unsafe.
+ * VIR_MIGRATE_OFFLINE Migrate offline
+ *
+ * VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set.
+ * Applications using the VIR_MIGRATE_PEER2PEER flag will probably
+ * prefer to invoke virDomainMigrateToURI, avoiding the need to
+ * open connection to the destination host themselves.
+ *
+ * If a hypervisor supports renaming domains during migration,
+ * then you may set the dname parameter to the new name (otherwise
+ * it keeps the same name). If this is not supported by the
+ * hypervisor, dname must be NULL or else you will get an error.
+ *
+ * If the VIR_MIGRATE_PEER2PEER flag is set, the uri parameter
+ * must be a valid libvirt connection URI, by which the source
+ * libvirt driver can connect to the destination libvirt. If
+ * omitted, the dconn connection object will be queried for its
+ * current URI.
+ *
+ * If the VIR_MIGRATE_PEER2PEER flag is NOT set, the URI parameter
+ * takes a hypervisor specific format. The hypervisor capabilities
+ * XML includes details of the support URI schemes. If omitted
+ * the dconn will be asked for a default URI.
+ *
+ * If you want to copy non-shared storage within migration you
+ * can use either VIR_MIGRATE_NON_SHARED_DISK or
+ * VIR_MIGRATE_NON_SHARED_INC as they are mutually exclusive.
+ *
+ * In either case it is typically only necessary to specify a
+ * URI if the destination host has multiple interfaces and a
+ * specific interface is required to transmit migration data.
+ *
+ * The maximum bandwidth (in MiB/s) that will be used to do migration
+ * can be specified with the bandwidth parameter. If set to 0,
+ * libvirt will choose a suitable default. Some hypervisors do
+ * not support this feature and will return an error if bandwidth
+ * is not 0.
+ *
+ * To see which features are supported by the current hypervisor,
+ * see virConnectGetCapabilities, /capabilities/host/migration_features.
+ *
+ * There are many limitations on migration imposed by the underlying
+ * technology - for example it may not be possible to migrate between
+ * different processors even with the same architecture, or between
+ * different types of hypervisor.
+ *
+ * virDomainFree should be used to free the resources after the
+ * returned domain object is no longer needed.
+ *
+ * Returns the new domain object if the migration was successful,
+ * or NULL in case of error. Note that the new domain object
+ * exists in the scope of the destination connection (dconn).
+ */
+virDomainPtr
+virDomainMigrate(virDomainPtr domain,
+ virConnectPtr dconn,
+ unsigned long flags,
+ const char *dname,
+ const char *uri,
+ unsigned long bandwidth)
+{
+ virDomainPtr ddomain = NULL;
+
+ VIR_DOMAIN_DEBUG(domain,
+ "dconn=%p, flags=%lx, dname=%s, uri=%s, bandwidth=%lu",
+ dconn, flags, NULLSTR(dname), NULLSTR(uri), bandwidth);
+
+ virResetLastError();
+
+ /* First checkout the source */
+ virCheckDomainReturn(domain, NULL);
+ virCheckReadOnlyGoto(domain->conn->flags, error);
+
+ /* Now checkout the destination */
+ virCheckConnectGoto(dconn, error);
+ virCheckReadOnlyGoto(dconn->flags, error);
+
+ if (flags & VIR_MIGRATE_NON_SHARED_DISK &&
+ flags & VIR_MIGRATE_NON_SHARED_INC) {
+ virReportInvalidArg(flags,
+ _("flags 'shared disk' and 'shared
incremental' "
+ "in %s are mutually exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ if (flags & VIR_MIGRATE_OFFLINE) {
+ if (!VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("offline migration is not supported by "
+ "the source host"));
+ goto error;
+ }
+ if (!VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
+ VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("offline migration is not supported by "
+ "the destination host"));
+ goto error;
+ }
+ }
+
+ if (flags & VIR_MIGRATE_PEER2PEER) {
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_P2P)) {
+ char *dstURI = NULL;
+ if (uri == NULL) {
+ dstURI = virConnectGetURI(dconn);
+ if (!dstURI)
+ return NULL;
+ }
+
+ VIR_DEBUG("Using peer2peer migration");
+ if (virDomainMigratePeer2Peer(domain, NULL, flags, dname,
+ uri ? uri : dstURI, NULL, bandwidth) < 0) {
+ VIR_FREE(dstURI);
+ goto error;
+ }
+ VIR_FREE(dstURI);
+
+ ddomain = virDomainLookupByName(dconn, dname ? dname : domain->name);
+ } else {
+ /* This driver does not support peer to peer migration */
+ virReportUnsupportedError();
+ goto error;
+ }
+ } else {
+ /* Change protection requires support only on source side, and
+ * is only needed in v3 migration, which automatically re-adds
+ * the flag for just the source side. We mask it out for
+ * non-peer2peer to allow migration from newer source to an
+ * older destination that rejects the flag. */
+ if (flags & VIR_MIGRATE_CHANGE_PROTECTION &&
+ !VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION)) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("cannot enforce change protection"));
+ goto error;
+ }
+ flags &= ~VIR_MIGRATE_CHANGE_PROTECTION;
+ if (flags & VIR_MIGRATE_TUNNELLED) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("cannot perform tunnelled migration without using
peer2peer flag"));
+ goto error;
+ }
+
+ /* Check that migration is supported by both drivers. */
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_V3) &&
+ VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
+ VIR_DRV_FEATURE_MIGRATION_V3)) {
+ VIR_DEBUG("Using migration protocol 3");
+ ddomain = virDomainMigrateVersion3(domain, dconn, NULL,
+ flags, dname, uri, bandwidth);
+ } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_V2) &&
+ VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
+ VIR_DRV_FEATURE_MIGRATION_V2)) {
+ VIR_DEBUG("Using migration protocol 2");
+ ddomain = virDomainMigrateVersion2(domain, dconn, flags,
+ dname, uri, bandwidth);
+ } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_V1) &&
+ VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
+ VIR_DRV_FEATURE_MIGRATION_V1)) {
+ VIR_DEBUG("Using migration protocol 1");
+ ddomain = virDomainMigrateVersion1(domain, dconn, flags,
+ dname, uri, bandwidth);
+ } else {
+ /* This driver does not support any migration method */
+ virReportUnsupportedError();
+ goto error;
+ }
+ }
+
+ if (ddomain == NULL)
+ goto error;
+
+ return ddomain;
+
+ error:
+ virDispatchError(domain->conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainMigrate2:
+ * @domain: a domain object
+ * @dconn: destination host (a connection object)
+ * @flags: bitwise-OR of virDomainMigrateFlags
+ * @dxml: (optional) XML config for launching guest on target
+ * @dname: (optional) rename domain to this at destination
+ * @uri: (optional) dest hostname/URI as seen from the source host
+ * @bandwidth: (optional) specify migration bandwidth limit in MiB/s
+ *
+ * Migrate the domain object from its current host to the destination
+ * host given by dconn (a connection to the destination host).
+ *
+ * Flags may be one of more of the following:
+ * VIR_MIGRATE_LIVE Do not pause the VM during migration
+ * VIR_MIGRATE_PEER2PEER Direct connection between source & destination hosts
+ * VIR_MIGRATE_TUNNELLED Tunnel migration data over the libvirt RPC channel
+ * VIR_MIGRATE_PERSIST_DEST If the migration is successful, persist the domain
+ * on the destination host.
+ * VIR_MIGRATE_UNDEFINE_SOURCE If the migration is successful, undefine the
+ * domain on the source host.
+ * VIR_MIGRATE_PAUSED Leave the domain suspended on the remote side.
+ * VIR_MIGRATE_NON_SHARED_DISK Migration with non-shared storage with full
+ * disk copy
+ * VIR_MIGRATE_NON_SHARED_INC Migration with non-shared storage with
+ * incremental disk copy
+ * VIR_MIGRATE_CHANGE_PROTECTION Protect against domain configuration
+ * changes during the migration process (set
+ * automatically when supported).
+ * VIR_MIGRATE_UNSAFE Force migration even if it is considered unsafe.
+ * VIR_MIGRATE_OFFLINE Migrate offline
+ *
+ * VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set.
+ * Applications using the VIR_MIGRATE_PEER2PEER flag will probably
+ * prefer to invoke virDomainMigrateToURI, avoiding the need to
+ * open connection to the destination host themselves.
+ *
+ * If a hypervisor supports renaming domains during migration,
+ * then you may set the dname parameter to the new name (otherwise
+ * it keeps the same name). If this is not supported by the
+ * hypervisor, dname must be NULL or else you will get an error.
+ *
+ * If the VIR_MIGRATE_PEER2PEER flag is set, the uri parameter
+ * must be a valid libvirt connection URI, by which the source
+ * libvirt driver can connect to the destination libvirt. If
+ * omitted, the dconn connection object will be queried for its
+ * current URI.
+ *
+ * If the VIR_MIGRATE_PEER2PEER flag is NOT set, the URI parameter
+ * takes a hypervisor specific format. The hypervisor capabilities
+ * XML includes details of the support URI schemes. If omitted
+ * the dconn will be asked for a default URI.
+ *
+ * If you want to copy non-shared storage within migration you
+ * can use either VIR_MIGRATE_NON_SHARED_DISK or
+ * VIR_MIGRATE_NON_SHARED_INC as they are mutually exclusive.
+ *
+ * In either case it is typically only necessary to specify a
+ * URI if the destination host has multiple interfaces and a
+ * specific interface is required to transmit migration data.
+ *
+ * The maximum bandwidth (in MiB/s) that will be used to do migration
+ * can be specified with the bandwidth parameter. If set to 0,
+ * libvirt will choose a suitable default. Some hypervisors do
+ * not support this feature and will return an error if bandwidth
+ * is not 0.
+ *
+ * To see which features are supported by the current hypervisor,
+ * see virConnectGetCapabilities, /capabilities/host/migration_features.
+ *
+ * There are many limitations on migration imposed by the underlying
+ * technology - for example it may not be possible to migrate between
+ * different processors even with the same architecture, or between
+ * different types of hypervisor.
+ *
+ * If the hypervisor supports it, @dxml can be used to alter
+ * host-specific portions of the domain XML that will be used on
+ * the destination. For example, it is possible to alter the
+ * backing filename that is associated with a disk device, in order
+ * to account for naming differences between source and destination
+ * in accessing the underlying storage. The migration will fail
+ * if @dxml would cause any guest-visible changes. Pass NULL
+ * if no changes are needed to the XML between source and destination.
+ * @dxml cannot be used to rename the domain during migration (use
+ * @dname for that purpose). Domain name in @dxml must match the
+ * original domain name.
+ *
+ * virDomainFree should be used to free the resources after the
+ * returned domain object is no longer needed.
+ *
+ * Returns the new domain object if the migration was successful,
+ * or NULL in case of error. Note that the new domain object
+ * exists in the scope of the destination connection (dconn).
+ */
+virDomainPtr
+virDomainMigrate2(virDomainPtr domain,
+ virConnectPtr dconn,
+ const char *dxml,
+ unsigned long flags,
+ const char *dname,
+ const char *uri,
+ unsigned long bandwidth)
+{
+ virDomainPtr ddomain = NULL;
+
+ VIR_DOMAIN_DEBUG(domain,
+ "dconn=%p, flags=%lx, dname=%s, uri=%s, bandwidth=%lu",
+ dconn, flags, NULLSTR(dname), NULLSTR(uri), bandwidth);
+
+ virResetLastError();
+
+ /* First checkout the source */
+ virCheckDomainReturn(domain, NULL);
+ virCheckReadOnlyGoto(domain->conn->flags, error);
+
+ /* Now checkout the destination */
+ virCheckConnectGoto(dconn, error);
+ virCheckReadOnlyGoto(dconn->flags, error);
+
+ if (flags & VIR_MIGRATE_NON_SHARED_DISK &&
+ flags & VIR_MIGRATE_NON_SHARED_INC) {
+ virReportInvalidArg(flags,
+ _("flags 'shared disk' and 'shared
incremental' "
+ "in %s are mutually exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ if (flags & VIR_MIGRATE_OFFLINE) {
+ if (!VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("offline migration is not supported by "
+ "the source host"));
+ goto error;
+ }
+ if (!VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
+ VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("offline migration is not supported by "
+ "the destination host"));
+ goto error;
+ }
+ }
+
+ if (flags & VIR_MIGRATE_PEER2PEER) {
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_P2P)) {
+ char *dstURI = virConnectGetURI(dconn);
+ if (!dstURI)
+ return NULL;
+
+ VIR_DEBUG("Using peer2peer migration");
+ if (virDomainMigratePeer2Peer(domain, dxml, flags, dname,
+ dstURI, uri, bandwidth) < 0) {
+ VIR_FREE(dstURI);
+ goto error;
+ }
+ VIR_FREE(dstURI);
+
+ ddomain = virDomainLookupByName(dconn, dname ? dname : domain->name);
+ } else {
+ /* This driver does not support peer to peer migration */
+ virReportUnsupportedError();
+ goto error;
+ }
+ } else {
+ /* Change protection requires support only on source side, and
+ * is only needed in v3 migration, which automatically re-adds
+ * the flag for just the source side. We mask it out for
+ * non-peer2peer to allow migration from newer source to an
+ * older destination that rejects the flag. */
+ if (flags & VIR_MIGRATE_CHANGE_PROTECTION &&
+ !VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION)) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("cannot enforce change protection"));
+ goto error;
+ }
+ flags &= ~VIR_MIGRATE_CHANGE_PROTECTION;
+ if (flags & VIR_MIGRATE_TUNNELLED) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("cannot perform tunnelled migration without using
peer2peer flag"));
+ goto error;
+ }
+
+ /* Check that migration is supported by both drivers. */
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_V3) &&
+ VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
+ VIR_DRV_FEATURE_MIGRATION_V3)) {
+ VIR_DEBUG("Using migration protocol 3");
+ ddomain = virDomainMigrateVersion3(domain, dconn, dxml,
+ flags, dname, uri, bandwidth);
+ } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_V2) &&
+ VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
+ VIR_DRV_FEATURE_MIGRATION_V2)) {
+ VIR_DEBUG("Using migration protocol 2");
+ if (dxml) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Unable to change target guest XML during
migration"));
+ goto error;
+ }
+ ddomain = virDomainMigrateVersion2(domain, dconn, flags,
+ dname, uri, bandwidth);
+ } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_V1) &&
+ VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
+ VIR_DRV_FEATURE_MIGRATION_V1)) {
+ VIR_DEBUG("Using migration protocol 1");
+ if (dxml) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Unable to change target guest XML during
migration"));
+ goto error;
+ }
+ ddomain = virDomainMigrateVersion1(domain, dconn, flags,
+ dname, uri, bandwidth);
+ } else {
+ /* This driver does not support any migration method */
+ virReportUnsupportedError();
+ goto error;
+ }
+ }
+
+ if (ddomain == NULL)
+ goto error;
+
+ return ddomain;
+
+ error:
+ virDispatchError(domain->conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainMigrate3:
+ * @domain: a domain object
+ * @dconn: destination host (a connection object)
+ * @params: (optional) migration parameters
+ * @nparams: (optional) number of migration parameters in @params
+ * @flags: bitwise-OR of virDomainMigrateFlags
+ *
+ * Migrate the domain object from its current host to the destination host
+ * given by dconn (a connection to the destination host).
+ *
+ * See virDomainMigrateFlags documentation for description of individual flags.
+ *
+ * VIR_MIGRATE_TUNNELLED and VIR_MIGRATE_PEER2PEER are not supported by this
+ * API, use virDomainMigrateToURI3 instead.
+ *
+ * If you want to copy non-shared storage within migration you
+ * can use either VIR_MIGRATE_NON_SHARED_DISK or
+ * VIR_MIGRATE_NON_SHARED_INC as they are mutually exclusive.
+ *
+ * There are many limitations on migration imposed by the underlying
+ * technology - for example it may not be possible to migrate between
+ * different processors even with the same architecture, or between
+ * different types of hypervisor.
+ *
+ * virDomainFree should be used to free the resources after the
+ * returned domain object is no longer needed.
+ *
+ * Returns the new domain object if the migration was successful,
+ * or NULL in case of error. Note that the new domain object
+ * exists in the scope of the destination connection (dconn).
+ */
+virDomainPtr
+virDomainMigrate3(virDomainPtr domain,
+ virConnectPtr dconn,
+ virTypedParameterPtr params,
+ unsigned int nparams,
+ unsigned int flags)
+{
+ virDomainPtr ddomain = NULL;
+ const char *compatParams[] = { VIR_MIGRATE_PARAM_URI,
+ VIR_MIGRATE_PARAM_DEST_NAME,
+ VIR_MIGRATE_PARAM_DEST_XML,
+ VIR_MIGRATE_PARAM_BANDWIDTH };
+ const char *uri = NULL;
+ const char *dname = NULL;
+ const char *dxml = NULL;
+ unsigned long long bandwidth = 0;
+
+ VIR_DOMAIN_DEBUG(domain, "dconn=%p, params=%p, nparms=%u flags=%x",
+ dconn, params, nparams, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ /* First checkout the source */
+ virCheckDomainReturn(domain, NULL);
+ virCheckReadOnlyGoto(domain->conn->flags, error);
+
+ /* Now checkout the destination */
+ virCheckConnectGoto(dconn, error);
+ virCheckReadOnlyGoto(dconn->flags, error);
+
+ if (flags & VIR_MIGRATE_NON_SHARED_DISK &&
+ flags & VIR_MIGRATE_NON_SHARED_INC) {
+ virReportInvalidArg(flags,
+ _("flags 'shared disk' and 'shared
incremental' "
+ "in %s are mutually exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+ if (flags & VIR_MIGRATE_PEER2PEER) {
+ virReportInvalidArg(flags, "%s",
+ _("use virDomainMigrateToURI3 for peer-to-peer "
+ "migration"));
+ goto error;
+ }
+ if (flags & VIR_MIGRATE_TUNNELLED) {
+ virReportInvalidArg(flags, "%s",
+ _("cannot perform tunnelled migration "
+ "without using peer2peer flag"));
+ goto error;
+ }
+
+ if (flags & VIR_MIGRATE_OFFLINE) {
+ if (!VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("offline migration is not supported by "
+ "the source host"));
+ goto error;
+ }
+ if (!VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
+ VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("offline migration is not supported by "
+ "the destination host"));
+ goto error;
+ }
+ }
+
+ /* Change protection requires support only on source side, and
+ * is only needed in v3 migration, which automatically re-adds
+ * the flag for just the source side. We mask it out to allow
+ * migration from newer source to an older destination that
+ * rejects the flag. */
+ if (flags & VIR_MIGRATE_CHANGE_PROTECTION &&
+ !VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION)) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("cannot enforce change protection"));
+ goto error;
+ }
+ flags &= ~VIR_MIGRATE_CHANGE_PROTECTION;
+
+ /* Prefer extensible API but fall back to older migration APIs if params
+ * only contains parameters which were supported by the older API. */
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_PARAMS) &&
+ VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
+ VIR_DRV_FEATURE_MIGRATION_PARAMS)) {
+ VIR_DEBUG("Using migration protocol 3 with extensible parameters");
+ ddomain = virDomainMigrateVersion3Params(domain, dconn, params,
+ nparams, flags);
+ goto done;
+ }
+
+ if (!virTypedParamsCheck(params, nparams, compatParams,
+ ARRAY_CARDINALITY(compatParams))) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Migration APIs with extensible parameters are not "
+ "supported but extended parameters were passed"));
+ goto error;
+ }
+
+ if (virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_URI, &uri) < 0 ||
+ virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_DEST_NAME, &dname) < 0 ||
+ virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_DEST_XML, &dxml) < 0 ||
+ virTypedParamsGetULLong(params, nparams,
+ VIR_MIGRATE_PARAM_BANDWIDTH, &bandwidth) < 0) {
+ goto error;
+ }
+
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_V3) &&
+ VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
+ VIR_DRV_FEATURE_MIGRATION_V3)) {
+ VIR_DEBUG("Using migration protocol 3");
+ ddomain = virDomainMigrateVersion3(domain, dconn, dxml, flags,
+ dname, uri, bandwidth);
+ } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_V2) &&
+ VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
+ VIR_DRV_FEATURE_MIGRATION_V2)) {
+ VIR_DEBUG("Using migration protocol 2");
+ if (dxml) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Unable to change target guest XML during "
+ "migration"));
+ goto error;
+ }
+ ddomain = virDomainMigrateVersion2(domain, dconn, flags,
+ dname, uri, bandwidth);
+ } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_V1) &&
+ VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
+ VIR_DRV_FEATURE_MIGRATION_V1)) {
+ VIR_DEBUG("Using migration protocol 1");
+ if (dxml) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Unable to change target guest XML during "
+ "migration"));
+ goto error;
+ }
+ ddomain = virDomainMigrateVersion1(domain, dconn, flags,
+ dname, uri, bandwidth);
+ } else {
+ /* This driver does not support any migration method */
+ virReportUnsupportedError();
+ goto error;
+ }
+
+ done:
+ if (ddomain == NULL)
+ goto error;
+
+ return ddomain;
+
+ error:
+ virDispatchError(domain->conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainMigrateToURI:
+ * @domain: a domain object
+ * @duri: mandatory URI for the destination host
+ * @flags: bitwise-OR of virDomainMigrateFlags
+ * @dname: (optional) rename domain to this at destination
+ * @bandwidth: (optional) specify migration bandwidth limit in MiB/s
+ *
+ * Migrate the domain object from its current host to the destination
+ * host given by duri.
+ *
+ * Flags may be one of more of the following:
+ * VIR_MIGRATE_LIVE Do not pause the VM during migration
+ * VIR_MIGRATE_PEER2PEER Direct connection between source & destination hosts
+ * VIR_MIGRATE_TUNNELLED Tunnel migration data over the libvirt RPC channel
+ * VIR_MIGRATE_PERSIST_DEST If the migration is successful, persist the domain
+ * on the destination host.
+ * VIR_MIGRATE_UNDEFINE_SOURCE If the migration is successful, undefine the
+ * domain on the source host.
+ * VIR_MIGRATE_PAUSED Leave the domain suspended on the remote side.
+ * VIR_MIGRATE_NON_SHARED_DISK Migration with non-shared storage with full
+ * disk copy
+ * VIR_MIGRATE_NON_SHARED_INC Migration with non-shared storage with
+ * incremental disk copy
+ * VIR_MIGRATE_CHANGE_PROTECTION Protect against domain configuration
+ * changes during the migration process (set
+ * automatically when supported).
+ * VIR_MIGRATE_UNSAFE Force migration even if it is considered unsafe.
+ * VIR_MIGRATE_OFFLINE Migrate offline
+ *
+ * The operation of this API hinges on the VIR_MIGRATE_PEER2PEER flag.
+ * If the VIR_MIGRATE_PEER2PEER flag is NOT set, the duri parameter
+ * takes a hypervisor specific format. The uri_transports element of the
+ * hypervisor capabilities XML includes details of the supported URI
+ * schemes. Not all hypervisors will support this mode of migration, so
+ * if the VIR_MIGRATE_PEER2PEER flag is not set, then it may be necessary
+ * to use the alternative virDomainMigrate API providing and explicit
+ * virConnectPtr for the destination host.
+ *
+ * If the VIR_MIGRATE_PEER2PEER flag IS set, the duri parameter
+ * must be a valid libvirt connection URI, by which the source
+ * libvirt driver can connect to the destination libvirt.
+ *
+ * VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set.
+ *
+ * If you want to copy non-shared storage within migration you
+ * can use either VIR_MIGRATE_NON_SHARED_DISK or
+ * VIR_MIGRATE_NON_SHARED_INC as they are mutually exclusive.
+ *
+ * If a hypervisor supports renaming domains during migration,
+ * the dname parameter specifies the new name for the domain.
+ * Setting dname to NULL keeps the domain name the same. If domain
+ * renaming is not supported by the hypervisor, dname must be NULL or
+ * else an error will be returned.
+ *
+ * The maximum bandwidth (in MiB/s) that will be used to do migration
+ * can be specified with the bandwidth parameter. If set to 0,
+ * libvirt will choose a suitable default. Some hypervisors do
+ * not support this feature and will return an error if bandwidth
+ * is not 0.
+ *
+ * To see which features are supported by the current hypervisor,
+ * see virConnectGetCapabilities, /capabilities/host/migration_features.
+ *
+ * There are many limitations on migration imposed by the underlying
+ * technology - for example it may not be possible to migrate between
+ * different processors even with the same architecture, or between
+ * different types of hypervisor.
+ *
+ * Returns 0 if the migration succeeded, -1 upon error.
+ */
+int
+virDomainMigrateToURI(virDomainPtr domain,
+ const char *duri,
+ unsigned long flags,
+ const char *dname,
+ unsigned long bandwidth)
+{
+ VIR_DOMAIN_DEBUG(domain, "duri=%p, flags=%lx, dname=%s, bandwidth=%lu",
+ NULLSTR(duri), flags, NULLSTR(dname), bandwidth);
+
+ virResetLastError();
+
+ /* First checkout the source */
+ virCheckDomainReturn(domain, -1);
+ virCheckReadOnlyGoto(domain->conn->flags, error);
+
+ virCheckNonNullArgGoto(duri, error);
+
+ if (flags & VIR_MIGRATE_NON_SHARED_DISK &&
+ flags & VIR_MIGRATE_NON_SHARED_INC) {
+ virReportInvalidArg(flags,
+ _("flags 'shared disk' and 'shared
incremental' "
+ "in %s are mutually exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ if (flags & VIR_MIGRATE_OFFLINE &&
+ !VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("offline migration is not supported by "
+ "the source host"));
+ goto error;
+ }
+
+ if (flags & VIR_MIGRATE_PEER2PEER) {
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_P2P)) {
+ VIR_DEBUG("Using peer2peer migration");
+ if (virDomainMigratePeer2Peer(domain, NULL, flags,
+ dname, duri, NULL, bandwidth) < 0)
+ goto error;
+ } else {
+ /* No peer to peer migration supported */
+ virReportUnsupportedError();
+ goto error;
+ }
+ } else {
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_DIRECT)) {
+ VIR_DEBUG("Using direct migration");
+ if (virDomainMigrateDirect(domain, NULL, flags,
+ dname, duri, bandwidth) < 0)
+ goto error;
+ } else {
+ /* Cannot do a migration with only the perform step */
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("direct migration is not supported by the"
+ " connection driver"));
+ goto error;
+ }
+ }
+
+ return 0;
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainMigrateToURI2:
+ * @domain: a domain object
+ * @dconnuri: (optional) URI for target libvirtd if @flags includes
VIR_MIGRATE_PEER2PEER
+ * @miguri: (optional) URI for invoking the migration, not if @flags includs
VIR_MIGRATE_TUNNELLED
+ * @dxml: (optional) XML config for launching guest on target
+ * @flags: bitwise-OR of virDomainMigrateFlags
+ * @dname: (optional) rename domain to this at destination
+ * @bandwidth: (optional) specify migration bandwidth limit in MiB/s
+ *
+ * Migrate the domain object from its current host to the destination
+ * host given by duri.
+ *
+ * Flags may be one of more of the following:
+ * VIR_MIGRATE_LIVE Do not pause the VM during migration
+ * VIR_MIGRATE_PEER2PEER Direct connection between source & destination hosts
+ * VIR_MIGRATE_TUNNELLED Tunnel migration data over the libvirt RPC channel
+ * VIR_MIGRATE_PERSIST_DEST If the migration is successful, persist the domain
+ * on the destination host.
+ * VIR_MIGRATE_UNDEFINE_SOURCE If the migration is successful, undefine the
+ * domain on the source host.
+ * VIR_MIGRATE_PAUSED Leave the domain suspended on the remote side.
+ * VIR_MIGRATE_NON_SHARED_DISK Migration with non-shared storage with full
+ * disk copy
+ * VIR_MIGRATE_NON_SHARED_INC Migration with non-shared storage with
+ * incremental disk copy
+ * VIR_MIGRATE_CHANGE_PROTECTION Protect against domain configuration
+ * changes during the migration process (set
+ * automatically when supported).
+ * VIR_MIGRATE_UNSAFE Force migration even if it is considered unsafe.
+ * VIR_MIGRATE_OFFLINE Migrate offline
+ *
+ * The operation of this API hinges on the VIR_MIGRATE_PEER2PEER flag.
+ *
+ * If the VIR_MIGRATE_PEER2PEER flag is set, the @dconnuri parameter
+ * must be a valid libvirt connection URI, by which the source
+ * libvirt driver can connect to the destination libvirt. If the
+ * VIR_MIGRATE_PEER2PEER flag is NOT set, then @dconnuri must be
+ * NULL.
+ *
+ * If the VIR_MIGRATE_TUNNELLED flag is NOT set, then the @miguri
+ * parameter allows specification of a URI to use to initiate the
+ * VM migration. It takes a hypervisor specific format. The uri_transports
+ * element of the hypervisor capabilities XML includes details of the
+ * supported URI schemes.
+ *
+ * VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set.
+ *
+ * If you want to copy non-shared storage within migration you
+ * can use either VIR_MIGRATE_NON_SHARED_DISK or
+ * VIR_MIGRATE_NON_SHARED_INC as they are mutually exclusive.
+ *
+ * If a hypervisor supports changing the configuration of the guest
+ * during migration, the @dxml parameter specifies the new config
+ * for the guest. The configuration must include an identical set
+ * of virtual devices, to ensure a stable guest ABI across migration.
+ * Only parameters related to host side configuration can be
+ * changed in the XML. Hypervisors will validate this and refuse to
+ * allow migration if the provided XML would cause a change in the
+ * guest ABI,
+ *
+ * If a hypervisor supports renaming domains during migration,
+ * the dname parameter specifies the new name for the domain.
+ * Setting dname to NULL keeps the domain name the same. If domain
+ * renaming is not supported by the hypervisor, dname must be NULL or
+ * else an error will be returned.
+ *
+ * The maximum bandwidth (in MiB/s) that will be used to do migration
+ * can be specified with the bandwidth parameter. If set to 0,
+ * libvirt will choose a suitable default. Some hypervisors do
+ * not support this feature and will return an error if bandwidth
+ * is not 0.
+ *
+ * To see which features are supported by the current hypervisor,
+ * see virConnectGetCapabilities, /capabilities/host/migration_features.
+ *
+ * There are many limitations on migration imposed by the underlying
+ * technology - for example it may not be possible to migrate between
+ * different processors even with the same architecture, or between
+ * different types of hypervisor.
+ *
+ * Returns 0 if the migration succeeded, -1 upon error.
+ */
+int
+virDomainMigrateToURI2(virDomainPtr domain,
+ const char *dconnuri,
+ const char *miguri,
+ const char *dxml,
+ unsigned long flags,
+ const char *dname,
+ unsigned long bandwidth)
+{
+ VIR_DOMAIN_DEBUG(domain, "dconnuri=%s, miguri=%s, dxml=%s, "
+ "flags=%lx, dname=%s, bandwidth=%lu",
+ NULLSTR(dconnuri), NULLSTR(miguri), NULLSTR(dxml),
+ flags, NULLSTR(dname), bandwidth);
+
+ virResetLastError();
+
+ /* First checkout the source */
+ virCheckDomainReturn(domain, -1);
+ virCheckReadOnlyGoto(domain->conn->flags, error);
+
+ if (flags & VIR_MIGRATE_NON_SHARED_DISK &&
+ flags & VIR_MIGRATE_NON_SHARED_INC) {
+ virReportInvalidArg(flags,
+ _("flags 'shared disk' and 'shared
incremental' "
+ "in %s are mutually exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ if (flags & VIR_MIGRATE_PEER2PEER) {
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_P2P)) {
+ VIR_DEBUG("Using peer2peer migration");
+ if (virDomainMigratePeer2Peer(domain, dxml, flags,
+ dname, dconnuri, miguri, bandwidth) < 0)
+ goto error;
+ } else {
+ /* No peer to peer migration supported */
+ virReportUnsupportedError();
+ goto error;
+ }
+ } else {
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_DIRECT)) {
+ VIR_DEBUG("Using direct migration");
+ if (virDomainMigrateDirect(domain, dxml, flags,
+ dname, miguri, bandwidth) < 0)
+ goto error;
+ } else {
+ /* Cannot do a migration with only the perform step */
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("direct migration is not supported by the"
+ " connection driver"));
+ goto error;
+ }
+ }
+
+ return 0;
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainMigrateToURI3:
+ * @domain: a domain object
+ * @dconnuri: (optional) URI for target libvirtd if @flags includes
VIR_MIGRATE_PEER2PEER
+ * @params: (optional) migration parameters
+ * @nparams: (optional) number of migration parameters in @params
+ * @flags: bitwise-OR of virDomainMigrateFlags
+ *
+ * Migrate the domain object from its current host to the destination host
+ * given by URI.
+ *
+ * See virDomainMigrateFlags documentation for description of individual flags.
+ *
+ * The operation of this API hinges on the VIR_MIGRATE_PEER2PEER flag.
+ *
+ * If the VIR_MIGRATE_PEER2PEER flag is set, the @dconnuri parameter must be a
+ * valid libvirt connection URI, by which the source libvirt daemon can connect
+ * to the destination libvirt.
+ *
+ * If the VIR_MIGRATE_PEER2PEER flag is NOT set, then @dconnuri must be NULL
+ * and VIR_MIGRATE_PARAM_URI migration parameter must be filled in with
+ * hypervisor specific URI used to initiate the migration. This is called
+ * "direct" migration.
+ *
+ * VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set.
+ *
+ * If you want to copy non-shared storage within migration you
+ * can use either VIR_MIGRATE_NON_SHARED_DISK or
+ * VIR_MIGRATE_NON_SHARED_INC as they are mutually exclusive.
+ *
+ * There are many limitations on migration imposed by the underlying
+ * technology - for example it may not be possible to migrate between
+ * different processors even with the same architecture, or between
+ * different types of hypervisor.
+ *
+ * Returns 0 if the migration succeeded, -1 upon error.
+ */
+int
+virDomainMigrateToURI3(virDomainPtr domain,
+ const char *dconnuri,
+ virTypedParameterPtr params,
+ unsigned int nparams,
+ unsigned int flags)
+{
+ bool compat;
+ const char *compatParams[] = { VIR_MIGRATE_PARAM_URI,
+ VIR_MIGRATE_PARAM_DEST_NAME,
+ VIR_MIGRATE_PARAM_DEST_XML,
+ VIR_MIGRATE_PARAM_BANDWIDTH };
+ const char *uri = NULL;
+ const char *dname = NULL;
+ const char *dxml = NULL;
+ unsigned long long bandwidth = 0;
+
+ VIR_DOMAIN_DEBUG(domain, "dconnuri=%s, params=%p, nparms=%u flags=%x",
+ NULLSTR(dconnuri), params, nparams, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ /* First checkout the source */
+ virCheckDomainReturn(domain, -1);
+ virCheckReadOnlyGoto(domain->conn->flags, error);
+
+ if (flags & VIR_MIGRATE_NON_SHARED_DISK &&
+ flags & VIR_MIGRATE_NON_SHARED_INC) {
+ virReportInvalidArg(flags,
+ _("flags 'shared disk' and 'shared
incremental' "
+ "in %s are mutually exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ compat = virTypedParamsCheck(params, nparams, compatParams,
+ ARRAY_CARDINALITY(compatParams));
+
+ if (virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_URI, &uri) < 0 ||
+ virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_DEST_NAME, &dname) < 0 ||
+ virTypedParamsGetString(params, nparams,
+ VIR_MIGRATE_PARAM_DEST_XML, &dxml) < 0 ||
+ virTypedParamsGetULLong(params, nparams,
+ VIR_MIGRATE_PARAM_BANDWIDTH, &bandwidth) < 0) {
+ goto error;
+ }
+
+ if (flags & VIR_MIGRATE_PEER2PEER) {
+ if (!VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_P2P)) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("Peer-to-peer migration is not supported by "
+ "the connection driver"));
+ goto error;
+ }
+
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_PARAMS)) {
+ VIR_DEBUG("Using peer2peer migration with extensible parameters");
+ if (virDomainMigratePeer2PeerParams(domain, dconnuri, params,
+ nparams, flags) < 0)
+ goto error;
+ } else if (compat) {
+ VIR_DEBUG("Using peer2peer migration");
+ if (virDomainMigratePeer2Peer(domain, dxml, flags, dname,
+ dconnuri, uri, bandwidth) < 0)
+ goto error;
+ } else {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Peer-to-peer migration with extensible "
+ "parameters is not supported but extended "
+ "parameters were passed"));
+ goto error;
+ }
+ } else {
+ if (!VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_MIGRATION_DIRECT)) {
+ /* Cannot do a migration with only the perform step */
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("Direct migration is not supported by the"
+ " connection driver"));
+ goto error;
+ }
+
+ if (!compat) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Direct migration does not support extensible "
+ "parameters"));
+ goto error;
+ }
+
+ VIR_DEBUG("Using direct migration");
+ if (virDomainMigrateDirect(domain, dxml, flags,
+ dname, uri, bandwidth) < 0)
+ goto error;
+ }
+
+ return 0;
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+int
+virDomainMigratePrepare(virConnectPtr dconn,
+ char **cookie,
+ int *cookielen,
+ const char *uri_in,
+ char **uri_out,
+ unsigned long flags,
+ const char *dname,
+ unsigned long bandwidth)
+{
+ VIR_DEBUG("dconn=%p, cookie=%p, cookielen=%p, uri_in=%s, uri_out=%p, "
+ "flags=%lx, dname=%s, bandwidth=%lu", dconn, cookie, cookielen,
+ NULLSTR(uri_in), uri_out, flags, NULLSTR(dname), bandwidth);
+
+ virResetLastError();
+
+ virCheckConnectReturn(dconn, -1);
+ virCheckReadOnlyGoto(dconn->flags, error);
+
+ if (dconn->driver->domainMigratePrepare) {
+ int ret;
+ ret = dconn->driver->domainMigratePrepare(dconn, cookie, cookielen,
+ uri_in, uri_out,
+ flags, dname, bandwidth);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dconn);
+ return -1;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+int
+virDomainMigratePerform(virDomainPtr domain,
+ const char *cookie,
+ int cookielen,
+ const char *uri,
+ unsigned long flags,
+ const char *dname,
+ unsigned long bandwidth)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "cookie=%p, cookielen=%d, uri=%s, flags=%lx, "
+ "dname=%s, bandwidth=%lu", cookie, cookielen, uri, flags,
+ NULLSTR(dname), bandwidth);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainMigratePerform) {
+ int ret;
+ ret = conn->driver->domainMigratePerform(domain, cookie, cookielen,
+ uri,
+ flags, dname, bandwidth);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+virDomainPtr
+virDomainMigrateFinish(virConnectPtr dconn,
+ const char *dname,
+ const char *cookie,
+ int cookielen,
+ const char *uri,
+ unsigned long flags)
+{
+ VIR_DEBUG("dconn=%p, dname=%s, cookie=%p, cookielen=%d, uri=%s, "
+ "flags=%lx", dconn, NULLSTR(dname), cookie, cookielen,
+ uri, flags);
+
+ virResetLastError();
+
+ virCheckConnectReturn(dconn, NULL);
+ virCheckReadOnlyGoto(dconn->flags, error);
+
+ if (dconn->driver->domainMigrateFinish) {
+ virDomainPtr ret;
+ ret = dconn->driver->domainMigrateFinish(dconn, dname,
+ cookie, cookielen,
+ uri, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dconn);
+ return NULL;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+int
+virDomainMigratePrepare2(virConnectPtr dconn,
+ char **cookie,
+ int *cookielen,
+ const char *uri_in,
+ char **uri_out,
+ unsigned long flags,
+ const char *dname,
+ unsigned long bandwidth,
+ const char *dom_xml)
+{
+ VIR_DEBUG("dconn=%p, cookie=%p, cookielen=%p, uri_in=%s, uri_out=%p,"
+ "flags=%lx, dname=%s, bandwidth=%lu, dom_xml=%s", dconn,
+ cookie, cookielen, uri_in, uri_out, flags, NULLSTR(dname),
+ bandwidth, dom_xml);
+
+ virResetLastError();
+
+ virCheckConnectReturn(dconn, -1);
+ virCheckReadOnlyGoto(dconn->flags, error);
+
+ if (dconn->driver->domainMigratePrepare2) {
+ int ret;
+ ret = dconn->driver->domainMigratePrepare2(dconn, cookie, cookielen,
+ uri_in, uri_out,
+ flags, dname, bandwidth,
+ dom_xml);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dconn);
+ return -1;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+virDomainPtr
+virDomainMigrateFinish2(virConnectPtr dconn,
+ const char *dname,
+ const char *cookie,
+ int cookielen,
+ const char *uri,
+ unsigned long flags,
+ int retcode)
+{
+ VIR_DEBUG("dconn=%p, dname=%s, cookie=%p, cookielen=%d, uri=%s, "
+ "flags=%lx, retcode=%d", dconn, NULLSTR(dname), cookie,
+ cookielen, uri, flags, retcode);
+
+ virResetLastError();
+
+ virCheckConnectReturn(dconn, NULL);
+ virCheckReadOnlyGoto(dconn->flags, error);
+
+ if (dconn->driver->domainMigrateFinish2) {
+ virDomainPtr ret;
+ ret = dconn->driver->domainMigrateFinish2(dconn, dname,
+ cookie, cookielen,
+ uri, flags,
+ retcode);
+ if (!ret && !retcode)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dconn);
+ return NULL;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+int
+virDomainMigratePrepareTunnel(virConnectPtr conn,
+ virStreamPtr st,
+ unsigned long flags,
+ const char *dname,
+ unsigned long bandwidth,
+ const char *dom_xml)
+{
+ VIR_DEBUG("conn=%p, stream=%p, flags=%lx, dname=%s, "
+ "bandwidth=%lu, dom_xml=%s", conn, st, flags,
+ NULLSTR(dname), bandwidth, dom_xml);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn != st->conn) {
+ virReportInvalidArg(conn,
+ _("conn in %s must match stream connection"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainMigratePrepareTunnel) {
+ int rv = conn->driver->domainMigratePrepareTunnel(conn, st,
+ flags, dname,
+ bandwidth, dom_xml);
+ if (rv < 0)
+ goto error;
+ return rv;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+char *
+virDomainMigrateBegin3(virDomainPtr domain,
+ const char *xmlin,
+ char **cookieout,
+ int *cookieoutlen,
+ unsigned long flags,
+ const char *dname,
+ unsigned long bandwidth)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "xmlin=%s cookieout=%p, cookieoutlen=%p, "
+ "flags=%lx, dname=%s, bandwidth=%lu",
+ NULLSTR(xmlin), cookieout, cookieoutlen, flags,
+ NULLSTR(dname), bandwidth);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, NULL);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainMigrateBegin3) {
+ char *xml;
+ xml = conn->driver->domainMigrateBegin3(domain, xmlin,
+ cookieout, cookieoutlen,
+ flags, dname, bandwidth);
+ VIR_DEBUG("xml %s", NULLSTR(xml));
+ if (!xml)
+ goto error;
+ return xml;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return NULL;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+int
+virDomainMigratePrepare3(virConnectPtr dconn,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ const char *uri_in,
+ char **uri_out,
+ unsigned long flags,
+ const char *dname,
+ unsigned long bandwidth,
+ const char *dom_xml)
+{
+ VIR_DEBUG("dconn=%p, cookiein=%p, cookieinlen=%d, cookieout=%p, "
+ "cookieoutlen=%p, uri_in=%s, uri_out=%p, flags=%lx, dname=%s, "
+ "bandwidth=%lu, dom_xml=%s",
+ dconn, cookiein, cookieinlen, cookieout, cookieoutlen, uri_in,
+ uri_out, flags, NULLSTR(dname), bandwidth, dom_xml);
+
+ virResetLastError();
+
+ virCheckConnectReturn(dconn, -1);
+ virCheckReadOnlyGoto(dconn->flags, error);
+
+ if (dconn->driver->domainMigratePrepare3) {
+ int ret;
+ ret = dconn->driver->domainMigratePrepare3(dconn,
+ cookiein, cookieinlen,
+ cookieout, cookieoutlen,
+ uri_in, uri_out,
+ flags, dname, bandwidth,
+ dom_xml);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dconn);
+ return -1;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+int
+virDomainMigratePrepareTunnel3(virConnectPtr conn,
+ virStreamPtr st,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ unsigned long flags,
+ const char *dname,
+ unsigned long bandwidth,
+ const char *dom_xml)
+{
+ VIR_DEBUG("conn=%p, stream=%p, cookiein=%p, cookieinlen=%d, cookieout=%p,
"
+ "cookieoutlen=%p, flags=%lx, dname=%s, bandwidth=%lu, "
+ "dom_xml=%s",
+ conn, st, cookiein, cookieinlen, cookieout, cookieoutlen, flags,
+ NULLSTR(dname), bandwidth, dom_xml);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn != st->conn) {
+ virReportInvalidArg(conn,
+ _("conn in %s must match stream connection"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainMigratePrepareTunnel3) {
+ int rv = conn->driver->domainMigratePrepareTunnel3(conn, st,
+ cookiein, cookieinlen,
+ cookieout, cookieoutlen,
+ flags, dname,
+ bandwidth, dom_xml);
+ if (rv < 0)
+ goto error;
+ return rv;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+int
+virDomainMigratePerform3(virDomainPtr domain,
+ const char *xmlin,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ const char *dconnuri,
+ const char *uri,
+ unsigned long flags,
+ const char *dname,
+ unsigned long bandwidth)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "xmlin=%s cookiein=%p, cookieinlen=%d, "
+ "cookieout=%p, cookieoutlen=%p, dconnuri=%s, "
+ "uri=%s, flags=%lx, dname=%s, bandwidth=%lu",
+ NULLSTR(xmlin), cookiein, cookieinlen,
+ cookieout, cookieoutlen, NULLSTR(dconnuri),
+ NULLSTR(uri), flags, NULLSTR(dname), bandwidth);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainMigratePerform3) {
+ int ret;
+ ret = conn->driver->domainMigratePerform3(domain, xmlin,
+ cookiein, cookieinlen,
+ cookieout, cookieoutlen,
+ dconnuri, uri,
+ flags, dname, bandwidth);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+virDomainPtr
+virDomainMigrateFinish3(virConnectPtr dconn,
+ const char *dname,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ const char *dconnuri,
+ const char *uri,
+ unsigned long flags,
+ int cancelled)
+{
+ VIR_DEBUG("dconn=%p, dname=%s, cookiein=%p, cookieinlen=%d, cookieout=%p,"
+ "cookieoutlen=%p, dconnuri=%s, uri=%s, flags=%lx, retcode=%d",
+ dconn, NULLSTR(dname), cookiein, cookieinlen, cookieout,
+ cookieoutlen, NULLSTR(dconnuri), NULLSTR(uri), flags, cancelled);
+
+ virResetLastError();
+
+ virCheckConnectReturn(dconn, NULL);
+ virCheckReadOnlyGoto(dconn->flags, error);
+
+ if (dconn->driver->domainMigrateFinish3) {
+ virDomainPtr ret;
+ ret = dconn->driver->domainMigrateFinish3(dconn, dname,
+ cookiein, cookieinlen,
+ cookieout, cookieoutlen,
+ dconnuri, uri, flags,
+ cancelled);
+ if (!ret && !cancelled)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dconn);
+ return NULL;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+int
+virDomainMigrateConfirm3(virDomainPtr domain,
+ const char *cookiein,
+ int cookieinlen,
+ unsigned long flags,
+ int cancelled)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain,
+ "cookiein=%p, cookieinlen=%d, flags=%lx, cancelled=%d",
+ cookiein, cookieinlen, flags, cancelled);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainMigrateConfirm3) {
+ int ret;
+ ret = conn->driver->domainMigrateConfirm3(domain,
+ cookiein, cookieinlen,
+ flags, cancelled);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+char *
+virDomainMigrateBegin3Params(virDomainPtr domain,
+ virTypedParameterPtr params,
+ int nparams,
+ char **cookieout,
+ int *cookieoutlen,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, "
+ "cookieout=%p, cookieoutlen=%p, flags=%x",
+ params, nparams, cookieout, cookieoutlen, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, NULL);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainMigrateBegin3Params) {
+ char *xml;
+ xml = conn->driver->domainMigrateBegin3Params(domain, params, nparams,
+ cookieout, cookieoutlen,
+ flags);
+ VIR_DEBUG("xml %s", NULLSTR(xml));
+ if (!xml)
+ goto error;
+ return xml;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return NULL;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+int
+virDomainMigratePrepare3Params(virConnectPtr dconn,
+ virTypedParameterPtr params,
+ int nparams,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ char **uri_out,
+ unsigned int flags)
+{
+ VIR_DEBUG("dconn=%p, params=%p, nparams=%d, cookiein=%p, cookieinlen=%d, "
+ "cookieout=%p, cookieoutlen=%p, uri_out=%p, flags=%x",
+ dconn, params, nparams, cookiein, cookieinlen,
+ cookieout, cookieoutlen, uri_out, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ virCheckConnectReturn(dconn, -1);
+ virCheckReadOnlyGoto(dconn->flags, error);
+
+ if (dconn->driver->domainMigratePrepare3Params) {
+ int ret;
+ ret = dconn->driver->domainMigratePrepare3Params(dconn, params, nparams,
+ cookiein, cookieinlen,
+ cookieout, cookieoutlen,
+ uri_out, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dconn);
+ return -1;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+int
+virDomainMigratePrepareTunnel3Params(virConnectPtr conn,
+ virStreamPtr st,
+ virTypedParameterPtr params,
+ int nparams,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ unsigned int flags)
+{
+ VIR_DEBUG("conn=%p, stream=%p, params=%p, nparams=%d, cookiein=%p, "
+ "cookieinlen=%d, cookieout=%p, cookieoutlen=%p, flags=%x",
+ conn, st, params, nparams, cookiein, cookieinlen,
+ cookieout, cookieoutlen, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn != st->conn) {
+ virReportInvalidArg(conn,
+ _("conn in %s must match stream connection"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainMigratePrepareTunnel3Params) {
+ int rv;
+ rv = conn->driver->domainMigratePrepareTunnel3Params(
+ conn, st, params, nparams, cookiein, cookieinlen,
+ cookieout, cookieoutlen, flags);
+ if (rv < 0)
+ goto error;
+ return rv;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+int
+virDomainMigratePerform3Params(virDomainPtr domain,
+ const char *dconnuri,
+ virTypedParameterPtr params,
+ int nparams,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "dconnuri=%s, params=%p, nparams=%d, cookiein=%p,
"
+ "cookieinlen=%d, cookieout=%p, cookieoutlen=%p,
flags=%x",
+ NULLSTR(dconnuri), params, nparams, cookiein,
+ cookieinlen, cookieout, cookieoutlen, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainMigratePerform3Params) {
+ int ret;
+ ret = conn->driver->domainMigratePerform3Params(
+ domain, dconnuri, params, nparams, cookiein, cookieinlen,
+ cookieout, cookieoutlen, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+virDomainPtr
+virDomainMigrateFinish3Params(virConnectPtr dconn,
+ virTypedParameterPtr params,
+ int nparams,
+ const char *cookiein,
+ int cookieinlen,
+ char **cookieout,
+ int *cookieoutlen,
+ unsigned int flags,
+ int cancelled)
+{
+ VIR_DEBUG("dconn=%p, params=%p, nparams=%d, cookiein=%p, cookieinlen=%d, "
+ "cookieout=%p, cookieoutlen=%p, flags=%x, cancelled=%d",
+ dconn, params, nparams, cookiein, cookieinlen, cookieout,
+ cookieoutlen, flags, cancelled);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ virCheckConnectReturn(dconn, NULL);
+ virCheckReadOnlyGoto(dconn->flags, error);
+
+ if (dconn->driver->domainMigrateFinish3Params) {
+ virDomainPtr ret;
+ ret = dconn->driver->domainMigrateFinish3Params(
+ dconn, params, nparams, cookiein, cookieinlen,
+ cookieout, cookieoutlen, flags, cancelled);
+ if (!ret && !cancelled)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dconn);
+ return NULL;
+}
+
+
+/*
+ * Not for public use. This function is part of the internal
+ * implementation of migration in the remote case.
+ */
+int
+virDomainMigrateConfirm3Params(virDomainPtr domain,
+ virTypedParameterPtr params,
+ int nparams,
+ const char *cookiein,
+ int cookieinlen,
+ unsigned int flags,
+ int cancelled)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, cookiein=%p, "
+ "cookieinlen=%d, flags=%x, cancelled=%d",
+ params, nparams, cookiein, cookieinlen, flags, cancelled);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainMigrateConfirm3Params) {
+ int ret;
+ ret = conn->driver->domainMigrateConfirm3Params(
+ domain, params, nparams,
+ cookiein, cookieinlen, flags, cancelled);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetSchedulerType:
+ * @domain: pointer to domain object
+ * @nparams: pointer to number of scheduler parameters, can be NULL
+ * (return value)
+ *
+ * Get the scheduler type and the number of scheduler parameters.
+ *
+ * Returns NULL in case of error. The caller must free the returned string.
+ */
+char *
+virDomainGetSchedulerType(virDomainPtr domain, int *nparams)
+{
+ virConnectPtr conn;
+ char *schedtype;
+
+ VIR_DOMAIN_DEBUG(domain, "nparams=%p", nparams);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, NULL);
+ conn = domain->conn;
+
+ if (conn->driver->domainGetSchedulerType) {
+ schedtype = conn->driver->domainGetSchedulerType(domain, nparams);
+ if (!schedtype)
+ goto error;
+ return schedtype;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainGetSchedulerParameters:
+ * @domain: pointer to domain object
+ * @params: pointer to scheduler parameter objects
+ * (return value)
+ * @nparams: pointer to number of scheduler parameter objects
+ * (this value should generally be as large as the returned value
+ * nparams of virDomainGetSchedulerType()); input and output
+ *
+ * Get all scheduler parameters. On input, @nparams gives the size of the
+ * @params array; on output, @nparams gives how many slots were filled
+ * with parameter information, which might be less but will not exceed
+ * the input value. @nparams cannot be 0.
+ *
+ * It is hypervisor specific whether this returns the live or
+ * persistent state; for more control, use
+ * virDomainGetSchedulerParametersFlags().
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainGetSchedulerParameters(virDomainPtr domain,
+ virTypedParameterPtr params, int *nparams)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%p", params, nparams);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+
+ virCheckNonNullArgGoto(params, error);
+ virCheckNonNullArgGoto(nparams, error);
+ virCheckPositiveArgGoto(*nparams, error);
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetSchedulerParameters) {
+ int ret;
+ ret = conn->driver->domainGetSchedulerParameters(domain, params, nparams);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetSchedulerParametersFlags:
+ * @domain: pointer to domain object
+ * @params: pointer to scheduler parameter object
+ * (return value)
+ * @nparams: pointer to number of scheduler parameter
+ * (this value should be same than the returned value
+ * nparams of virDomainGetSchedulerType()); input and output
+ * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
+ *
+ * Get all scheduler parameters. On input, @nparams gives the size of the
+ * @params array; on output, @nparams gives how many slots were filled
+ * with parameter information, which might be less but will not exceed
+ * the input value. @nparams cannot be 0.
+ *
+ * The value of @flags can be exactly VIR_DOMAIN_AFFECT_CURRENT,
+ * VIR_DOMAIN_AFFECT_LIVE, or VIR_DOMAIN_AFFECT_CONFIG.
+ *
+ * Here is a sample code snippet:
+ *
+ * char *ret = virDomainGetSchedulerType(dom, &nparams);
+ * if (ret && nparams != 0) {
+ * if ((params = malloc(sizeof(*params) * nparams)) == NULL)
+ * goto error;
+ * memset(params, 0, sizeof(*params) * nparams);
+ * if (virDomainGetSchedulerParametersFlags(dom, params, &nparams, 0))
+ * goto error;
+ * }
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainGetSchedulerParametersFlags(virDomainPtr domain,
+ virTypedParameterPtr params, int *nparams,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%p, flags=%x",
+ params, nparams, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+
+ virCheckNonNullArgGoto(params, error);
+ virCheckNonNullArgGoto(nparams, error);
+ virCheckPositiveArgGoto(*nparams, error);
+
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_TYPED_PARAM_STRING))
+ flags |= VIR_TYPED_PARAM_STRING_OKAY;
+
+ /* At most one of these two flags should be set. */
+ if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
+ (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
+ virReportInvalidArg(flags,
+ _("flags 'affect live' and 'affect
config' in %s "
+ "are mutually exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+ conn = domain->conn;
+
+ if (conn->driver->domainGetSchedulerParametersFlags) {
+ int ret;
+ ret = conn->driver->domainGetSchedulerParametersFlags(domain, params,
+ nparams, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSetSchedulerParameters:
+ * @domain: pointer to domain object
+ * @params: pointer to scheduler parameter objects
+ * @nparams: number of scheduler parameter objects
+ * (this value can be the same or less than the returned value
+ * nparams of virDomainGetSchedulerType)
+ *
+ * Change all or a subset or the scheduler parameters. It is
+ * hypervisor-specific whether this sets live, persistent, or both
+ * settings; for more control, use
+ * virDomainSetSchedulerParametersFlags.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainSetSchedulerParameters(virDomainPtr domain,
+ virTypedParameterPtr params, int nparams)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d", params, nparams);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(params, error);
+ virCheckNonNegativeArgGoto(nparams, error);
+
+ if (virTypedParameterValidateSet(conn, params, nparams) < 0)
+ goto error;
+
+ if (conn->driver->domainSetSchedulerParameters) {
+ int ret;
+ ret = conn->driver->domainSetSchedulerParameters(domain, params, nparams);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSetSchedulerParametersFlags:
+ * @domain: pointer to domain object
+ * @params: pointer to scheduler parameter objects
+ * @nparams: number of scheduler parameter objects
+ * (this value can be the same or less than the returned value
+ * nparams of virDomainGetSchedulerType)
+ * @flags: bitwise-OR of virDomainModificationImpact
+ *
+ * Change a subset or all scheduler parameters. The value of @flags
+ * should be either VIR_DOMAIN_AFFECT_CURRENT, or a bitwise-or of
+ * values from VIR_DOMAIN_AFFECT_LIVE and
+ * VIR_DOMAIN_AFFECT_CURRENT, although hypervisors vary in which
+ * flags are supported.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainSetSchedulerParametersFlags(virDomainPtr domain,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
+ params, nparams, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(params, error);
+ virCheckNonNegativeArgGoto(nparams, error);
+
+ if (virTypedParameterValidateSet(conn, params, nparams) < 0)
+ goto error;
+
+ if (conn->driver->domainSetSchedulerParametersFlags) {
+ int ret;
+ ret = conn->driver->domainSetSchedulerParametersFlags(domain,
+ params,
+ nparams,
+ flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainBlockStats:
+ * @dom: pointer to the domain object
+ * @disk: path to the block device, or device shorthand
+ * @stats: block device stats (returned)
+ * @size: size of stats structure
+ *
+ * This function returns block device (disk) stats for block
+ * devices attached to the domain.
+ *
+ * The @disk parameter is either the device target shorthand (the
+ * <target dev='...'/> sub-element, such as "vda"), or (since
0.9.8)
+ * an unambiguous source name of the block device (the <source
+ * file='...'/> sub-element, such as "/path/to/image"). Valid
names
+ * can be found by calling virDomainGetXMLDesc() and inspecting
+ * elements within //domain/devices/disk. Some drivers might also
+ * accept the empty string for the @disk parameter, and then yield
+ * summary stats for the entire domain.
+ *
+ * Domains may have more than one block device. To get stats for
+ * each you should make multiple calls to this function.
+ *
+ * Individual fields within the stats structure may be returned
+ * as -1, which indicates that the hypervisor does not support
+ * that particular statistic.
+ *
+ * Returns: 0 in case of success or -1 in case of failure.
+ */
+int
+virDomainBlockStats(virDomainPtr dom, const char *disk,
+ virDomainBlockStatsPtr stats, size_t size)
+{
+ virConnectPtr conn;
+ virDomainBlockStatsStruct stats2 = { -1, -1, -1, -1, -1 };
+
+ VIR_DOMAIN_DEBUG(dom, "disk=%s, stats=%p, size=%zi", disk, stats, size);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ virCheckNonNullArgGoto(disk, error);
+ virCheckNonNullArgGoto(stats, error);
+ if (size > sizeof(stats2)) {
+ virReportInvalidArg(size,
+ _("size in %s must not exceed %zu"),
+ __FUNCTION__, sizeof(stats2));
+ goto error;
+ }
+ conn = dom->conn;
+
+ if (conn->driver->domainBlockStats) {
+ if (conn->driver->domainBlockStats(dom, disk, &stats2) == -1)
+ goto error;
+
+ memcpy(stats, &stats2, size);
+ return 0;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainBlockStatsFlags:
+ * @dom: pointer to domain object
+ * @disk: path to the block device, or device shorthand
+ * @params: pointer to block stats parameter object
+ * (return value, allocated by the caller)
+ * @nparams: pointer to number of block stats; input and output
+ * @flags: bitwise-OR of virTypedParameterFlags
+ *
+ * This function is to get block stats parameters for block
+ * devices attached to the domain.
+ *
+ * The @disk parameter is either the device target shorthand (the
+ * <target dev='...'/> sub-element, such as "vda"), or (since
0.9.8)
+ * an unambiguous source name of the block device (the <source
+ * file='...'/> sub-element, such as "/path/to/image"). Valid
names
+ * can be found by calling virDomainGetXMLDesc() and inspecting
+ * elements within //domain/devices/disk. Some drivers might also
+ * accept the empty string for the @disk parameter, and then yield
+ * summary stats for the entire domain.
+ *
+ * Domains may have more than one block device. To get stats for
+ * each you should make multiple calls to this function.
+ *
+ * On input, @nparams gives the size of the @params array; on output,
+ * @nparams gives how many slots were filled with parameter
+ * information, which might be less but will not exceed the input
+ * value.
+ *
+ * As a special case, calling with @params as NULL and @nparams as 0 on
+ * input will cause @nparams on output to contain the number of parameters
+ * supported by the hypervisor. (Note that block devices of different types
+ * might support different parameters, so it might be necessary to compute
+ * @nparams for each block device). The caller should then allocate @params
+ * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
+ * again. See virDomainGetMemoryParameters() for more details.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainBlockStatsFlags(virDomainPtr dom,
+ const char *disk,
+ virTypedParameterPtr params,
+ int *nparams,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "disk=%s, params=%p, nparams=%d, flags=%x",
+ disk, params, nparams ? *nparams : -1, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ virCheckNonNullArgGoto(disk, error);
+ virCheckNonNullArgGoto(nparams, error);
+ virCheckNonNegativeArgGoto(*nparams, error);
+ if (*nparams != 0)
+ virCheckNonNullArgGoto(params, error);
+
+ if (VIR_DRV_SUPPORTS_FEATURE(dom->conn->driver, dom->conn,
+ VIR_DRV_FEATURE_TYPED_PARAM_STRING))
+ flags |= VIR_TYPED_PARAM_STRING_OKAY;
+ conn = dom->conn;
+
+ if (conn->driver->domainBlockStatsFlags) {
+ int ret;
+ ret = conn->driver->domainBlockStatsFlags(dom, disk, params, nparams,
flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainInterfaceStats:
+ * @dom: pointer to the domain object
+ * @path: path to the interface
+ * @stats: network interface stats (returned)
+ * @size: size of stats structure
+ *
+ * This function returns network interface stats for interfaces
+ * attached to the domain.
+ *
+ * The path parameter is the name of the network interface.
+ *
+ * Domains may have more than one network interface. To get stats for
+ * each you should make multiple calls to this function.
+ *
+ * Individual fields within the stats structure may be returned
+ * as -1, which indicates that the hypervisor does not support
+ * that particular statistic.
+ *
+ * Returns: 0 in case of success or -1 in case of failure.
+ */
+int
+virDomainInterfaceStats(virDomainPtr dom, const char *path,
+ virDomainInterfaceStatsPtr stats, size_t size)
+{
+ virConnectPtr conn;
+ virDomainInterfaceStatsStruct stats2 = { -1, -1, -1, -1,
+ -1, -1, -1, -1 };
+
+ VIR_DOMAIN_DEBUG(dom, "path=%s, stats=%p, size=%zi",
+ path, stats, size);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ virCheckNonNullArgGoto(path, error);
+ virCheckNonNullArgGoto(stats, error);
+ if (size > sizeof(stats2)) {
+ virReportInvalidArg(size,
+ _("size in %s must not exceed %zu"),
+ __FUNCTION__, sizeof(stats2));
+ goto error;
+ }
+
+ conn = dom->conn;
+
+ if (conn->driver->domainInterfaceStats) {
+ if (conn->driver->domainInterfaceStats(dom, path, &stats2) == -1)
+ goto error;
+
+ memcpy(stats, &stats2, size);
+ return 0;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSetInterfaceParameters:
+ * @domain: pointer to domain object
+ * @device: the interface name or mac address
+ * @params: pointer to interface parameter objects
+ * @nparams: number of interface parameter (this value can be the same or
+ * less than the number of parameters supported)
+ * @flags: bitwise-OR of virDomainModificationImpact
+ *
+ * Change a subset or all parameters of interface; currently this
+ * includes bandwidth parameters. The value of @flags should be
+ * either VIR_DOMAIN_AFFECT_CURRENT, or a bitwise-or of values
+ * VIR_DOMAIN_AFFECT_LIVE and VIR_DOMAIN_AFFECT_CONFIG, although
+ * hypervisors vary in which flags are supported.
+ *
+ * This function may require privileged access to the hypervisor.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainSetInterfaceParameters(virDomainPtr domain,
+ const char *device,
+ virTypedParameterPtr params,
+ int nparams, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "device=%s, params=%p, nparams=%d, flags=%x",
+ device, params, nparams, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(params, error);
+ virCheckPositiveArgGoto(nparams, error);
+
+ if (virTypedParameterValidateSet(conn, params, nparams) < 0)
+ goto error;
+
+ if (conn->driver->domainSetInterfaceParameters) {
+ int ret;
+ ret = conn->driver->domainSetInterfaceParameters(domain, device,
+ params, nparams,
+ flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetInterfaceParameters:
+ * @domain: pointer to domain object
+ * @device: the interface name or mac address
+ * @params: pointer to interface parameter objects
+ * (return value, allocated by the caller)
+ * @nparams: pointer to number of interface parameter; input and output
+ * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
+ *
+ * Get all interface parameters. On input, @nparams gives the size of
+ * the @params array; on output, @nparams gives how many slots were
+ * filled with parameter information, which might be less but will not
+ * exceed the input value.
+ *
+ * As a special case, calling with @params as NULL and @nparams as 0 on
+ * input will cause @nparams on output to contain the number of parameters
+ * supported by the hypervisor. The caller should then allocate @params
+ * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the
+ * API again. See virDomainGetMemoryParameters() for an equivalent usage
+ * example.
+ *
+ * This function may require privileged access to the hypervisor. This function
+ * expects the caller to allocate the @params.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainGetInterfaceParameters(virDomainPtr domain,
+ const char *device,
+ virTypedParameterPtr params,
+ int *nparams, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "device=%s, params=%p, nparams=%d, flags=%x",
+ device, params, (nparams) ? *nparams : -1, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ virCheckNonNullArgGoto(nparams, error);
+ virCheckNonNegativeArgGoto(*nparams, error);
+ if (*nparams != 0)
+ virCheckNonNullArgGoto(params, error);
+
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_TYPED_PARAM_STRING))
+ flags |= VIR_TYPED_PARAM_STRING_OKAY;
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetInterfaceParameters) {
+ int ret;
+ ret = conn->driver->domainGetInterfaceParameters(domain, device,
+ params, nparams,
+ flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainMemoryStats:
+ * @dom: pointer to the domain object
+ * @stats: nr_stats-sized array of stat structures (returned)
+ * @nr_stats: number of memory statistics requested
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * This function provides memory statistics for the domain.
+ *
+ * Up to 'nr_stats' elements of 'stats' will be populated with memory
statistics
+ * from the domain. Only statistics supported by the domain, the driver, and
+ * this version of libvirt will be returned.
+ *
+ * Memory Statistics:
+ *
+ * VIR_DOMAIN_MEMORY_STAT_SWAP_IN:
+ * The total amount of data read from swap space (in kb).
+ * VIR_DOMAIN_MEMORY_STAT_SWAP_OUT:
+ * The total amount of memory written out to swap space (in kb).
+ * VIR_DOMAIN_MEMORY_STAT_MAJOR_FAULT:
+ * The number of page faults that required disk IO to service.
+ * VIR_DOMAIN_MEMORY_STAT_MINOR_FAULT:
+ * The number of page faults serviced without disk IO.
+ * VIR_DOMAIN_MEMORY_STAT_UNUSED:
+ * The amount of memory which is not being used for any purpose (in kb).
+ * VIR_DOMAIN_MEMORY_STAT_AVAILABLE:
+ * The total amount of memory available to the domain's OS (in kb).
+ * VIR_DOMAIN_MEMORY_STAT_ACTUAL_BALLOON:
+ * Current balloon value (in kb).
+ *
+ * Returns: The number of stats provided or -1 in case of failure.
+ */
+int
+virDomainMemoryStats(virDomainPtr dom, virDomainMemoryStatPtr stats,
+ unsigned int nr_stats, unsigned int flags)
+{
+ virConnectPtr conn;
+ unsigned long nr_stats_ret = 0;
+
+ VIR_DOMAIN_DEBUG(dom, "stats=%p, nr_stats=%u, flags=%x",
+ stats, nr_stats, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+
+ if (!stats || nr_stats == 0)
+ return 0;
+
+ if (nr_stats > VIR_DOMAIN_MEMORY_STAT_NR)
+ nr_stats = VIR_DOMAIN_MEMORY_STAT_NR;
+
+ conn = dom->conn;
+ if (conn->driver->domainMemoryStats) {
+ nr_stats_ret = conn->driver->domainMemoryStats(dom, stats, nr_stats,
+ flags);
+ if (nr_stats_ret == -1)
+ goto error;
+ return nr_stats_ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainBlockPeek:
+ * @dom: pointer to the domain object
+ * @disk: path to the block device, or device shorthand
+ * @offset: offset within block device
+ * @size: size to read
+ * @buffer: return buffer (must be at least size bytes)
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * This function allows you to read the contents of a domain's
+ * disk device.
+ *
+ * Typical uses for this are to determine if the domain has
+ * written a Master Boot Record (indicating that the domain
+ * has completed installation), or to try to work out the state
+ * of the domain's filesystems.
+ *
+ * (Note that in the local case you might try to open the
+ * block device or file directly, but that won't work in the
+ * remote case, nor if you don't have sufficient permission.
+ * Hence the need for this call).
+ *
+ * The @disk parameter is either an unambiguous source name of the
+ * block device (the <source file='...'/> sub-element, such as
+ * "/path/to/image"), or (since 0.9.5) the device target shorthand
+ * (the <target dev='...'/> sub-element, such as "vda"). Valid
names
+ * can be found by calling virDomainGetXMLDesc() and inspecting
+ * elements within //domain/devices/disk.
+ *
+ * 'offset' and 'size' represent an area which must lie entirely
+ * within the device or file. 'size' may be 0 to test if the
+ * call would succeed.
+ *
+ * 'buffer' is the return buffer and must be at least 'size' bytes.
+ *
+ * NB. The remote driver imposes a 64K byte limit on 'size'.
+ * For your program to be able to work reliably over a remote
+ * connection you should split large requests to <= 65536 bytes.
+ * However, with 0.9.13 this RPC limit has been raised to 1M byte.
+ * Starting with version 1.0.6 the RPC limit has been raised again.
+ * Now large requests up to 16M byte are supported.
+ *
+ * Returns: 0 in case of success or -1 in case of failure.
+ */
+int
+virDomainBlockPeek(virDomainPtr dom,
+ const char *disk,
+ unsigned long long offset /* really 64 bits */,
+ size_t size,
+ void *buffer,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "disk=%s, offset=%lld, size=%zi, buffer=%p,
flags=%x",
+ disk, offset, size, buffer, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(disk, error);
+
+ /* Allow size == 0 as an access test. */
+ if (size > 0)
+ virCheckNonNullArgGoto(buffer, error);
+
+ if (conn->driver->domainBlockPeek) {
+ int ret;
+ ret = conn->driver->domainBlockPeek(dom, disk, offset, size,
+ buffer, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainBlockResize:
+ * @dom: pointer to the domain object
+ * @disk: path to the block image, or shorthand
+ * @size: new size of the block image, see below for unit
+ * @flags: bitwise-OR of virDomainBlockResizeFlags
+ *
+ * Resize a block device of domain while the domain is running. If
+ * @flags is 0, then @size is in kibibytes (blocks of 1024 bytes);
+ * since 0.9.11, if @flags includes VIR_DOMAIN_BLOCK_RESIZE_BYTES,
+ * @size is in bytes instead. @size is taken directly as the new
+ * size. Depending on the file format, the hypervisor may round up
+ * to the next alignment boundary.
+ *
+ * The @disk parameter is either an unambiguous source name of the
+ * block device (the <source file='...'/> sub-element, such as
+ * "/path/to/image"), or (since 0.9.5) the device target shorthand
+ * (the <target dev='...'/> sub-element, such as "vda"). Valid
names
+ * can be found by calling virDomainGetXMLDesc() and inspecting
+ * elements within //domain/devices/disk.
+ *
+ * Note that this call may fail if the underlying virtualization hypervisor
+ * does not support it; this call requires privileged access to the
+ * hypervisor.
+ *
+ * Returns: 0 in case of success or -1 in case of failure.
+ */
+int
+virDomainBlockResize(virDomainPtr dom,
+ const char *disk,
+ unsigned long long size,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "disk=%s, size=%llu, flags=%x", disk, size, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(disk, error);
+
+ if (conn->driver->domainBlockResize) {
+ int ret;
+ ret = conn->driver->domainBlockResize(dom, disk, size, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainMemoryPeek:
+ * @dom: pointer to the domain object
+ * @start: start of memory to peek
+ * @size: size of memory to peek
+ * @buffer: return buffer (must be at least size bytes)
+ * @flags: bitwise-OR of virDomainMemoryFlags
+ *
+ * This function allows you to read the contents of a domain's
+ * memory.
+ *
+ * The memory which is read is controlled by the 'start', 'size'
+ * and 'flags' parameters.
+ *
+ * If 'flags' is VIR_MEMORY_VIRTUAL then the 'start' and 'size'
+ * parameters are interpreted as virtual memory addresses for
+ * whichever task happens to be running on the domain at the
+ * moment. Although this sounds haphazard it is in fact what
+ * you want in order to read Linux kernel state, because it
+ * ensures that pointers in the kernel image can be interpreted
+ * coherently.
+ *
+ * 'buffer' is the return buffer and must be at least 'size' bytes.
+ * 'size' may be 0 to test if the call would succeed.
+ *
+ * NB. The remote driver imposes a 64K byte limit on 'size'.
+ * For your program to be able to work reliably over a remote
+ * connection you should split large requests to <= 65536 bytes.
+ * However, with 0.9.13 this RPC limit has been raised to 1M byte.
+ * Starting with version 1.0.6 the RPC limit has been raised again.
+ * Now large requests up to 16M byte are supported.
+ *
+ * Returns: 0 in case of success or -1 in case of failure.
+ */
+int
+virDomainMemoryPeek(virDomainPtr dom,
+ unsigned long long start /* really 64 bits */,
+ size_t size,
+ void *buffer,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "start=%lld, size=%zi, buffer=%p, flags=%x",
+ start, size, buffer, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ /* Note on access to physical memory: A VIR_MEMORY_PHYSICAL flag is
+ * a possibility. However it isn't really useful unless the caller
+ * can also access registers, particularly CR3 on x86 in order to
+ * get the Page Table Directory. Since registers are different on
+ * every architecture, that would imply another call to get the
+ * machine registers.
+ *
+ * The QEMU driver handles VIR_MEMORY_VIRTUAL, mapping it
+ * to the qemu 'memsave' command which does the virtual to physical
+ * mapping inside qemu.
+ *
+ * The QEMU driver also handles VIR_MEMORY_PHYSICAL, mapping it
+ * to the qemu 'pmemsave' command.
+ *
+ * At time of writing there is no Xen driver. However the Xen
+ * hypervisor only lets you map physical pages from other domains,
+ * and so the Xen driver would have to do the virtual to physical
+ * mapping by chasing 2, 3 or 4-level page tables from the PTD.
+ * There is example code in libxc (xc_translate_foreign_address)
+ * which does this, although we cannot copy this code directly
+ * because of incompatible licensing.
+ */
+
+ /* Exactly one of these two flags must be set. */
+ if (!(flags & VIR_MEMORY_VIRTUAL) == !(flags & VIR_MEMORY_PHYSICAL)) {
+ virReportInvalidArg(flags,
+ _("flags in %s must include VIR_MEMORY_VIRTUAL or
"
+ "VIR_MEMORY_PHYSICAL"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ /* Allow size == 0 as an access test. */
+ if (size > 0)
+ virCheckNonNullArgGoto(buffer, error);
+
+ if (conn->driver->domainMemoryPeek) {
+ int ret;
+ ret = conn->driver->domainMemoryPeek(dom, start, size,
+ buffer, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetBlockInfo:
+ * @domain: a domain object
+ * @disk: path to the block device, or device shorthand
+ * @info: pointer to a virDomainBlockInfo structure allocated by the user
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Extract information about a domain's block device.
+ *
+ * The @disk parameter is either an unambiguous source name of the
+ * block device (the <source file='...'/> sub-element, such as
+ * "/path/to/image"), or (since 0.9.5) the device target shorthand
+ * (the <target dev='...'/> sub-element, such as "vda"). Valid
names
+ * can be found by calling virDomainGetXMLDesc() and inspecting
+ * elements within //domain/devices/disk.
+ *
+ * For QEMU domains, the allocation and physical virDomainBlockInfo
+ * values returned will generally be the same, except when using a
+ * non raw, block backing device, such as qcow2 for an active domain.
+ * When the persistent domain is not active, QEMU will return the
+ * default which is the same value for allocation and physical.
+ *
+ * Active QEMU domains can return an allocation value which is more
+ * representative of the currently used blocks by the device compared
+ * to the physical size of the device. Applications can use/monitor
+ * the allocation value with the understanding that if the domain
+ * becomes inactive during an attempt to get the value, the default
+ * values will be returned. Thus, the application should check
+ * after the call for the domain being inactive if the values are
+ * the same. Optionally, the application could be watching for a
+ * shutdown event and then ignore any values received afterwards.
+ * This can be an issue when a domain is being migrated and the
+ * exact timing of the domain being made inactive and check of
+ * the allocation value results the default being returned. For
+ * a transient domain in the similar situation, this call will return
+ * -1 and an error message indicating the "domain is not running".
+ *
+ * The following is some pseudo code illustrating the call sequence:
+ *
+ * ...
+ * virDomainPtr dom;
+ * virDomainBlockInfo info;
+ * char *device;
+ * ...
+ * // Either get a list of all domains or a specific domain
+ * // via a virDomainLookupBy*() call.
+ * //
+ * // It's also required to fill in the device pointer, but that's
+ * // specific to the implementation. For the purposes of this example
+ * // a qcow2 backed device name string would need to be provided.
+ * ...
+ * // If the following call is made on a persistent domain with a
+ * // qcow2 block backed block device, then it's possible the returned
+ * // allocation equals the physical value. In that case, the domain
+ * // that may have been active prior to calling has become inactive,
+ * // such as is the case during a domain migration. Thus once we
+ * // get data returned, check for active domain when the values are
+ * // the same.
+ * if (virDomainGetBlockInfo(dom, device, &info, 0) < 0)
+ * goto failure;
+ * if (info.allocation == info.physical) {
+ * // If the domain is no longer active,
+ * // then the defaults are being returned.
+ * if (!virDomainIsActive())
+ * goto ignore_return;
+ * }
+ * // Do something with the allocation and physical values
+ * ...
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainGetBlockInfo(virDomainPtr domain, const char *disk,
+ virDomainBlockInfoPtr info, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "info=%p, flags=%x", info, flags);
+
+ virResetLastError();
+
+ if (info)
+ memset(info, 0, sizeof(*info));
+
+ virCheckDomainReturn(domain, -1);
+ virCheckNonNullArgGoto(disk, error);
+ virCheckNonNullArgGoto(info, error);
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetBlockInfo) {
+ int ret;
+ ret = conn->driver->domainGetBlockInfo(domain, disk, info, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainDefineXML:
+ * @conn: pointer to the hypervisor connection
+ * @xml: the XML description for the domain, preferably in UTF-8
+ *
+ * Define 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
+virDomainDefineXML(virConnectPtr conn, const char *xml)
+{
+ VIR_DEBUG("conn=%p, xml=%s", conn, xml);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, NULL);
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(xml, error);
+
+ if (conn->driver->domainDefineXML) {
+ virDomainPtr ret;
+ ret = conn->driver->domainDefineXML(conn, xml);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainUndefine:
+ * @domain: pointer to a defined domain
+ *
+ * Undefine a domain. If the domain is running, it's converted to
+ * transient domain, without stopping it. If the domain is inactive,
+ * the domain configuration is removed.
+ *
+ * If the domain has a managed save image (see
+ * virDomainHasManagedSaveImage()), or if it is inactive and has any
+ * snapshot metadata (see virDomainSnapshotNum()), then the undefine will
+ * fail. See virDomainUndefineFlags() for more control.
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+virDomainUndefine(virDomainPtr domain)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainUndefine) {
+ int ret;
+ ret = conn->driver->domainUndefine(domain);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainUndefineFlags:
+ * @domain: pointer to a defined domain
+ * @flags: bitwise-OR of supported virDomainUndefineFlagsValues
+ *
+ * Undefine a domain. If the domain is running, it's converted to
+ * transient domain, without stopping it. If the domain is inactive,
+ * the domain configuration is removed.
+ *
+ * If the domain has a managed save image (see virDomainHasManagedSaveImage()),
+ * then including VIR_DOMAIN_UNDEFINE_MANAGED_SAVE in @flags will also remove
+ * that file, and omitting the flag will cause the undefine process to fail.
+ *
+ * If the domain is inactive and has any snapshot metadata (see
+ * virDomainSnapshotNum()), then including
+ * VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA in @flags will also remove
+ * that metadata. Omitting the flag will cause the undefine of an
+ * inactive domain to fail. Active snapshots will retain snapshot
+ * metadata until the (now-transient) domain halts, regardless of
+ * whether this flag is present. On hypervisors where snapshots do
+ * not use libvirt metadata, this flag has no effect.
+ *
+ * If the domain has any nvram specified, then including
+ * VIR_DOMAIN_UNDEFINE_NVRAM will also remove that file, and omitting the flag
+ * will cause the undefine process to fail.
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+virDomainUndefineFlags(virDomainPtr domain,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainUndefineFlags) {
+ int ret;
+ ret = conn->driver->domainUndefineFlags(domain, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virConnectNumOfDefinedDomains:
+ * @conn: pointer to the hypervisor connection
+ *
+ * Provides the number of defined but inactive domains.
+ *
+ * Returns the number of domain found or -1 in case of error
+ */
+int
+virConnectNumOfDefinedDomains(virConnectPtr conn)
+{
+ VIR_DEBUG("conn=%p", conn);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+
+ if (conn->driver->connectNumOfDefinedDomains) {
+ int ret;
+ ret = conn->driver->connectNumOfDefinedDomains(conn);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virConnectListDefinedDomains:
+ * @conn: pointer to the hypervisor connection
+ * @names: pointer to an array to store the names
+ * @maxnames: size of the array
+ *
+ * list the defined but inactive domains, stores the pointers to the names
+ * in @names
+ *
+ * For active domains, see virConnectListDomains(). For more control over
+ * the results, see virConnectListAllDomains().
+ *
+ * Returns the number of names provided in the array or -1 in case of error.
+ * Note that this command is inherently racy; a domain can be defined between
+ * a call to virConnectNumOfDefinedDomains() and this call; you are only
+ * guaranteed that all currently defined domains were listed if the return
+ * is less than @maxids. The client must call free() on each returned name.
+ */
+int
+virConnectListDefinedDomains(virConnectPtr conn, char **const names,
+ int maxnames)
+{
+ VIR_DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+ virCheckNonNullArgGoto(names, error);
+ virCheckNonNegativeArgGoto(maxnames, error);
+
+ if (conn->driver->connectListDefinedDomains) {
+ int ret;
+ ret = conn->driver->connectListDefinedDomains(conn, names, maxnames);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virConnectListAllDomains:
+ * @conn: Pointer to the hypervisor connection.
+ * @domains: Pointer to a variable to store the array containing domain objects
+ * or NULL if the list is not required (just returns number of guests).
+ * @flags: bitwise-OR of virConnectListAllDomainsFlags
+ *
+ * Collect a possibly-filtered list of all domains, and return an allocated
+ * array of information for each. This API solves the race inherent in
+ * virConnectListDomains() and virConnectListDefinedDomains().
+ *
+ * Normally, all domains are returned; however, @flags can be used to
+ * filter the results for a smaller list of targeted domains. The valid
+ * flags are divided into groups, where each group contains bits that
+ * describe mutually exclusive attributes of a domain, and where all bits
+ * within a group describe all possible domains. Some hypervisors might
+ * reject explicit bits from a group where the hypervisor cannot make a
+ * distinction (for example, not all hypervisors can tell whether domains
+ * have snapshots). For a group supported by a given hypervisor, the
+ * behavior when no bits of a group are set is identical to the behavior
+ * when all bits in that group are set. When setting bits from more than
+ * one group, it is possible to select an impossible combination (such
+ * as an inactive transient domain), in that case a hypervisor may return
+ * either 0 or an error.
+ *
+ * The first group of @flags is VIR_CONNECT_LIST_DOMAINS_ACTIVE (online
+ * domains) and VIR_CONNECT_LIST_DOMAINS_INACTIVE (offline domains).
+ *
+ * The next group of @flags is VIR_CONNECT_LIST_DOMAINS_PERSISTENT (defined
+ * domains) and VIR_CONNECT_LIST_DOMAINS_TRANSIENT (running but not defined).
+ *
+ * The next group of @flags covers various domain states:
+ * VIR_CONNECT_LIST_DOMAINS_RUNNING, VIR_CONNECT_LIST_DOMAINS_PAUSED,
+ * VIR_CONNECT_LIST_DOMAINS_SHUTOFF, and a catch-all for all other states
+ * (such as crashed, this catch-all covers the possibility of adding new
+ * states).
+ *
+ * The remaining groups cover boolean attributes commonly asked about
+ * domains; they include VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE and
+ * VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE, for filtering based on whether
+ * a managed save image exists; VIR_CONNECT_LIST_DOMAINS_AUTOSTART and
+ * VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART, for filtering based on autostart;
+ * VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT and
+ * VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT, for filtering based on whether
+ * a domain has snapshots.
+ *
+ * Example of usage:
+ *
+ * virDomainPtr *domains;
+ * size_t i;
+ * int ret;
+ * unsigned int flags = VIR_CONNECT_LIST_DOMAINS_RUNNING |
+ * VIR_CONNECT_LIST_DOMAINS_PERSISTENT;
+ * ret = virConnectListAllDomains(conn, &domains, flags);
+ * if (ret < 0)
+ * error();
+ * for (i = 0; i < ret; i++) {
+ * do_something_with_domain(domains[i]);
+ * //here or in a separate loop if needed
+ * virDomainFree(domains[i]);
+ * }
+ * free(domains);
+ *
+ * Returns the number of domains found or -1 and sets domains to NULL in case of
+ * error. On success, the array stored into @domains is guaranteed to have an
+ * extra allocated element set to NULL but not included in the return count, to
+ * make iteration easier. The caller is responsible for calling virDomainFree()
+ * on each array element, then calling free() on @domains.
+ */
+int
+virConnectListAllDomains(virConnectPtr conn,
+ virDomainPtr **domains,
+ unsigned int flags)
+{
+ VIR_DEBUG("conn=%p, domains=%p, flags=%x", conn, domains, flags);
+
+ virResetLastError();
+
+ if (domains)
+ *domains = NULL;
+
+ virCheckConnectReturn(conn, -1);
+
+ if (conn->driver->connectListAllDomains) {
+ int ret;
+ ret = conn->driver->connectListAllDomains(conn, domains, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainCreate:
+ * @domain: pointer to a defined domain
+ *
+ * Launch a defined domain. If the call succeeds the domain moves from the
+ * defined to the running domains pools. The domain will be paused only
+ * if restoring from managed state created from a paused domain. For more
+ * control, see virDomainCreateWithFlags().
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+virDomainCreate(virDomainPtr domain)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainCreate) {
+ int ret;
+ ret = conn->driver->domainCreate(domain);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainCreateWithFlags:
+ * @domain: pointer to a defined domain
+ * @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.
+ *
+ * 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
+virDomainCreateWithFlags(virDomainPtr domain, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainCreateWithFlags) {
+ int ret;
+ ret = conn->driver->domainCreateWithFlags(domain, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ 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();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainCreateWithFiles) {
+ int ret;
+ ret = conn->driver->domainCreateWithFiles(domain,
+ nfiles, files,
+ flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetAutostart:
+ * @domain: a domain object
+ * @autostart: the value returned
+ *
+ * Provides a boolean value indicating whether the domain
+ * configured to be automatically started when the host
+ * machine boots.
+ *
+ * Returns -1 in case of error, 0 in case of success
+ */
+int
+virDomainGetAutostart(virDomainPtr domain,
+ int *autostart)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "autostart=%p", autostart);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ virCheckNonNullArgGoto(autostart, error);
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetAutostart) {
+ int ret;
+ ret = conn->driver->domainGetAutostart(domain, autostart);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSetAutostart:
+ * @domain: a domain object
+ * @autostart: whether the domain should be automatically started 0 or 1
+ *
+ * Configure the domain to be automatically started
+ * when the host machine boots.
+ *
+ * Returns -1 in case of error, 0 in case of success
+ */
+int
+virDomainSetAutostart(virDomainPtr domain,
+ int autostart)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "autostart=%d", autostart);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainSetAutostart) {
+ int ret;
+ ret = conn->driver->domainSetAutostart(domain, autostart);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainInjectNMI:
+ * @domain: pointer to domain object, or NULL for Domain0
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Send NMI to the guest
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virDomainInjectNMI(virDomainPtr domain, unsigned int flags)
+{
+ virConnectPtr conn;
+ VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainInjectNMI) {
+ int ret;
+ ret = conn->driver->domainInjectNMI(domain, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSendKey:
+ * @domain: pointer to domain object, or NULL for Domain0
+ * @codeset: the code set of keycodes, from virKeycodeSet
+ * @holdtime: the duration (in milliseconds) that the keys will be held
+ * @keycodes: array of keycodes
+ * @nkeycodes: number of keycodes, up to VIR_DOMAIN_SEND_KEY_MAX_KEYS
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Send key(s) to the guest.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virDomainSendKey(virDomainPtr domain,
+ unsigned int codeset,
+ unsigned int holdtime,
+ unsigned int *keycodes,
+ int nkeycodes,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+ VIR_DOMAIN_DEBUG(domain, "codeset=%u, holdtime=%u, nkeycodes=%u,
flags=%x",
+ codeset, holdtime, nkeycodes, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(keycodes, error);
+ virCheckPositiveArgGoto(nkeycodes, error);
+
+ if (nkeycodes > VIR_DOMAIN_SEND_KEY_MAX_KEYS) {
+ virReportInvalidArg(nkeycodes,
+ _("nkeycodes in %s must be <= %d"),
+ __FUNCTION__, VIR_DOMAIN_SEND_KEY_MAX_KEYS);
+ goto error;
+ }
+
+ if (conn->driver->domainSendKey) {
+ int ret;
+ ret = conn->driver->domainSendKey(domain, codeset, holdtime,
+ keycodes, nkeycodes, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSendProcessSignal:
+ * @domain: pointer to domain object
+ * @pid_value: a positive integer process ID, or negative integer process group ID
+ * @signum: a signal from the virDomainProcessSignal enum
+ * @flags: one of the virDomainProcessSignalFlag values
+ *
+ * Send a signal to the designated process in the guest
+ *
+ * The signal numbers must be taken from the virDomainProcessSignal
+ * enum. These will be translated to the corresponding signal
+ * number for the guest OS, by the guest agent delivering the
+ * signal. If there is no mapping from virDomainProcessSignal to
+ * the native OS signals, this API will report an error.
+ *
+ * If @pid_value is an integer greater than zero, it is
+ * treated as a process ID. If @pid_value is an integer
+ * less than zero, it is treated as a process group ID.
+ * All the @pid_value numbers are from the container/guest
+ * namespace. The value zero is not valid.
+ *
+ * Not all hypervisors will support sending signals to
+ * arbitrary processes or process groups. If this API is
+ * implemented the minimum requirement is to be able to
+ * use @pid_value == 1 (i.e. kill init). No other value is
+ * required to be supported.
+ *
+ * If the @signum is VIR_DOMAIN_PROCESS_SIGNAL_NOP then this
+ * API will simply report whether the process is running in
+ * the container/guest.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virDomainSendProcessSignal(virDomainPtr domain,
+ long long pid_value,
+ unsigned int signum,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+ VIR_DOMAIN_DEBUG(domain, "pid=%lld, signum=%u flags=%x",
+ pid_value, signum, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckNonZeroArgGoto(pid_value, error);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainSendProcessSignal) {
+ int ret;
+ ret = conn->driver->domainSendProcessSignal(domain,
+ pid_value,
+ signum,
+ flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSetVcpus:
+ * @domain: pointer to domain object, or NULL for Domain0
+ * @nvcpus: the new number of virtual CPUs for this domain
+ *
+ * Dynamically change the number of virtual CPUs used by the domain.
+ * Note that this call may fail if the underlying virtualization hypervisor
+ * does not support it or if growing the number is arbitrarily limited.
+ * This function may require privileged access to the hypervisor.
+ *
+ * Note that if this call is executed before the guest has finished booting,
+ * the guest may fail to process the change.
+ *
+ * This command only changes the runtime configuration of the domain,
+ * so can only be called on an active domain. It is hypervisor-dependent
+ * whether it also affects persistent configuration; for more control,
+ * use virDomainSetVcpusFlags().
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "nvcpus=%u", nvcpus);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonZeroArgGoto(nvcpus, error);
+
+ if (conn->driver->domainSetVcpus) {
+ int ret;
+ ret = conn->driver->domainSetVcpus(domain, nvcpus);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSetVcpusFlags:
+ * @domain: pointer to domain object, or NULL for Domain0
+ * @nvcpus: the new number of virtual CPUs for this domain, must be at least 1
+ * @flags: bitwise-OR of virDomainVcpuFlags
+ *
+ * Dynamically change the number of virtual CPUs used by the domain.
+ * Note that this call may fail if the underlying virtualization hypervisor
+ * does not support it or if growing the number is arbitrarily limited.
+ * This function may require privileged access to the hypervisor.
+ *
+ * @flags may include VIR_DOMAIN_AFFECT_LIVE to affect a running
+ * domain (which may fail if domain is not active), or
+ * VIR_DOMAIN_AFFECT_CONFIG to affect the next boot via the XML
+ * description of the domain. Both flags may be set.
+ * If neither flag is specified (that is, @flags is VIR_DOMAIN_AFFECT_CURRENT),
+ * then an inactive domain modifies persistent setup, while an active domain
+ * is hypervisor-dependent on whether just live or both live and persistent
+ * state is changed.
+ *
+ * Note that if this call is executed before the guest has finished booting,
+ * the guest may fail to process the change.
+ *
+ * If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then
+ * VIR_DOMAIN_AFFECT_LIVE must be clear, and only the maximum virtual
+ * CPU limit is altered; generally, this value must be less than or
+ * equal to virConnectGetMaxVcpus(). Otherwise, this call affects the
+ * current virtual CPU limit, which must be less than or equal to the
+ * maximum limit.
+ *
+ * If @flags includes VIR_DOMAIN_VCPU_GUEST, then the state of processors is
+ * modified inside the guest instead of the hypervisor. This flag can only
+ * be used with live guests and is incompatible with VIR_DOMAIN_VCPU_MAXIMUM.
+ * The usage of this flag may require a guest agent configured.
+ *
+ * Not all hypervisors can support all flag combinations.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "nvcpus=%u, flags=%x", nvcpus, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ virCheckReadOnlyGoto(domain->conn->flags, error);
+
+ if (flags & VIR_DOMAIN_VCPU_GUEST &&
+ flags & VIR_DOMAIN_VCPU_MAXIMUM) {
+ virReportInvalidArg(flags,
+ _("flags 'VIR_DOMAIN_VCPU_MAXIMUM' and "
+ "'VIR_DOMAIN_VCPU_GUEST' in '%s' are
mutually "
+ "exclusive"), __FUNCTION__);
+ goto error;
+ }
+
+ virCheckNonZeroArgGoto(nvcpus, error);
+
+ if ((unsigned short) nvcpus != nvcpus) {
+ virReportError(VIR_ERR_OVERFLOW, _("input too large: %u"), nvcpus);
+ goto error;
+ }
+ conn = domain->conn;
+
+ if (conn->driver->domainSetVcpusFlags) {
+ int ret;
+ ret = conn->driver->domainSetVcpusFlags(domain, nvcpus, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetVcpusFlags:
+ * @domain: pointer to domain object, or NULL for Domain0
+ * @flags: bitwise-OR of virDomainVcpuFlags
+ *
+ * Query the number of virtual CPUs used by the domain. Note that
+ * this call may fail if the underlying virtualization hypervisor does
+ * not support it. This function may require privileged access to the
+ * hypervisor.
+ *
+ * If @flags includes VIR_DOMAIN_AFFECT_LIVE, this will query a
+ * running domain (which will fail if domain is not active); if
+ * it includes VIR_DOMAIN_AFFECT_CONFIG, this will query the XML
+ * description of the domain. It is an error to set both flags.
+ * If neither flag is set (that is, VIR_DOMAIN_AFFECT_CURRENT),
+ * then the configuration queried depends on whether the domain
+ * is currently running.
+ *
+ * If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then the maximum
+ * virtual CPU limit is queried. Otherwise, this call queries the
+ * current virtual CPU count.
+ *
+ * If @flags includes VIR_DOMAIN_VCPU_GUEST, then the state of the processors
+ * is queried in the guest instead of the hypervisor. This flag is only usable
+ * on live domains. Guest agent may be needed for this flag to be available.
+ *
+ * Returns the number of vCPUs in case of success, -1 in case of failure.
+ */
+int
+virDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ if (flags & VIR_DOMAIN_VCPU_GUEST)
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ /* At most one of these two flags should be set. */
+ if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
+ (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
+ virReportInvalidArg(flags,
+ _("flags 'affect live' and 'affect
config' in %s "
+ "are mutually exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainGetVcpusFlags) {
+ int ret;
+ ret = conn->driver->domainGetVcpusFlags(domain, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainPinVcpu:
+ * @domain: pointer to domain object, or NULL for Domain0
+ * @vcpu: virtual CPU number
+ * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN)
+ * Each bit set to 1 means that corresponding CPU is usable.
+ * Bytes are stored in little-endian order: CPU0-7, 8-15...
+ * In each byte, lowest CPU number is least significant bit.
+ * @maplen: number of bytes in cpumap, from 1 up to size of CPU map in
+ * underlying virtualization system (Xen...).
+ * If maplen < size, missing bytes are set to zero.
+ * If maplen > size, failure code is returned.
+ *
+ * Dynamically change the real CPUs which can be allocated to a virtual CPU.
+ * This function may require privileged access to the hypervisor.
+ *
+ * This command only changes the runtime configuration of the domain,
+ * so can only be called on an active domain.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
+ unsigned char *cpumap, int maplen)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "vcpu=%u, cpumap=%p, maplen=%d",
+ vcpu, cpumap, maplen);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(cpumap, error);
+ virCheckPositiveArgGoto(maplen, error);
+
+ if ((unsigned short) vcpu != vcpu) {
+ virReportError(VIR_ERR_OVERFLOW, _("input too large: %u"), vcpu);
+ goto error;
+ }
+
+ if (conn->driver->domainPinVcpu) {
+ int ret;
+ ret = conn->driver->domainPinVcpu(domain, vcpu, cpumap, maplen);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainPinVcpuFlags:
+ * @domain: pointer to domain object, or NULL for Domain0
+ * @vcpu: virtual CPU number
+ * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN)
+ * Each bit set to 1 means that corresponding CPU is usable.
+ * Bytes are stored in little-endian order: CPU0-7, 8-15...
+ * In each byte, lowest CPU number is least significant bit.
+ * @maplen: number of bytes in cpumap, from 1 up to size of CPU map in
+ * underlying virtualization system (Xen...).
+ * If maplen < size, missing bytes are set to zero.
+ * If maplen > size, failure code is returned.
+ * @flags: bitwise-OR of virDomainModificationImpact
+ *
+ * Dynamically change the real CPUs which can be allocated to a virtual CPU.
+ * This function may require privileged access to the hypervisor.
+ *
+ * @flags may include VIR_DOMAIN_AFFECT_LIVE or VIR_DOMAIN_AFFECT_CONFIG.
+ * Both flags may be set.
+ * If VIR_DOMAIN_AFFECT_LIVE is set, the change affects a running domain
+ * and may fail if domain is not alive.
+ * If VIR_DOMAIN_AFFECT_CONFIG is set, the change affects persistent state,
+ * and will fail for transient domains. If neither flag is specified (that is,
+ * @flags is VIR_DOMAIN_AFFECT_CURRENT), then an inactive domain modifies
+ * persistent setup, while an active domain is hypervisor-dependent on whether
+ * just live or both live and persistent state is changed.
+ * Not all hypervisors can support all flag combinations.
+ *
+ * See also virDomainGetVcpuPinInfo for querying this information.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ *
+ */
+int
+virDomainPinVcpuFlags(virDomainPtr domain, unsigned int vcpu,
+ unsigned char *cpumap, int maplen, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "vcpu=%u, cpumap=%p, maplen=%d, flags=%x",
+ vcpu, cpumap, maplen, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(cpumap, error);
+ virCheckPositiveArgGoto(maplen, error);
+
+ if ((unsigned short) vcpu != vcpu) {
+ virReportError(VIR_ERR_OVERFLOW, _("input too large: %u"), vcpu);
+ goto error;
+ }
+
+ if (conn->driver->domainPinVcpuFlags) {
+ int ret;
+ ret = conn->driver->domainPinVcpuFlags(domain, vcpu, cpumap, maplen,
flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetVcpuPinInfo:
+ * @domain: pointer to domain object, or NULL for Domain0
+ * @ncpumaps: the number of cpumap (listed first to match virDomainGetVcpus)
+ * @cpumaps: pointer to a bit map of real CPUs for all vcpus of this
+ * domain (in 8-bit bytes) (OUT)
+ * It's assumed there is <ncpumaps> cpumap in cpumaps array.
+ * The memory allocated to cpumaps must be (ncpumaps * maplen) bytes
+ * (ie: calloc(ncpumaps, maplen)).
+ * One cpumap inside cpumaps has the format described in
+ * virDomainPinVcpu() API.
+ * Must not be NULL.
+ * @maplen: the number of bytes in one cpumap, from 1 up to size of CPU map.
+ * Must be positive.
+ * @flags: bitwise-OR of virDomainModificationImpact
+ * Must not be VIR_DOMAIN_AFFECT_LIVE and
+ * VIR_DOMAIN_AFFECT_CONFIG concurrently.
+ *
+ * Query the CPU affinity setting of all virtual CPUs of domain, store it
+ * in cpumaps.
+ *
+ * Returns the number of virtual CPUs in case of success,
+ * -1 in case of failure.
+ */
+int
+virDomainGetVcpuPinInfo(virDomainPtr domain, int ncpumaps,
+ unsigned char *cpumaps, int maplen, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "ncpumaps=%d, cpumaps=%p, maplen=%d, flags=%x",
+ ncpumaps, cpumaps, maplen, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckNonNullArgGoto(cpumaps, error);
+ virCheckPositiveArgGoto(ncpumaps, error);
+ virCheckPositiveArgGoto(maplen, error);
+
+ if (INT_MULTIPLY_OVERFLOW(ncpumaps, maplen)) {
+ virReportError(VIR_ERR_OVERFLOW, _("input too large: %d * %d"),
+ ncpumaps, maplen);
+ goto error;
+ }
+
+ /* At most one of these two flags should be set. */
+ if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
+ (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
+ virReportInvalidArg(flags,
+ _("flags 'affect live' and 'affect
config' in %s "
+ "are mutually exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainGetVcpuPinInfo) {
+ int ret;
+ ret = conn->driver->domainGetVcpuPinInfo(domain, ncpumaps,
+ cpumaps, maplen, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainPinEmulator:
+ * @domain: pointer to domain object, or NULL for Domain0
+ * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN)
+ * Each bit set to 1 means that corresponding CPU is usable.
+ * Bytes are stored in little-endian order: CPU0-7, 8-15...
+ * In each byte, lowest CPU number is least significant bit.
+ * @maplen: number of bytes in cpumap, from 1 up to size of CPU map in
+ * underlying virtualization system (Xen...).
+ * If maplen < size, missing bytes are set to zero.
+ * If maplen > size, failure code is returned.
+ * @flags: bitwise-OR of virDomainModificationImpact
+ *
+ * Dynamically change the real CPUs which can be allocated to all emulator
+ * threads. This function may require privileged access to the hypervisor.
+ *
+ * @flags may include VIR_DOMAIN_AFFECT_LIVE or VIR_DOMAIN_AFFECT_CONFIG.
+ * Both flags may be set.
+ * If VIR_DOMAIN_AFFECT_LIVE is set, the change affects a running domain
+ * and may fail if domain is not alive.
+ * If VIR_DOMAIN_AFFECT_CONFIG is set, the change affects persistent state,
+ * and will fail for transient domains. If neither flag is specified (that is,
+ * @flags is VIR_DOMAIN_AFFECT_CURRENT), then an inactive domain modifies
+ * persistent setup, while an active domain is hypervisor-dependent on whether
+ * just live or both live and persistent state is changed.
+ * Not all hypervisors can support all flag combinations.
+ *
+ * See also virDomainGetEmulatorPinInfo for querying this information.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ *
+ */
+int
+virDomainPinEmulator(virDomainPtr domain, unsigned char *cpumap,
+ int maplen, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "cpumap=%p, maplen=%d, flags=%x",
+ cpumap, maplen, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ virCheckNonNullArgGoto(cpumap, error);
+ virCheckPositiveArgGoto(maplen, error);
+
+ if (conn->driver->domainPinEmulator) {
+ int ret;
+ ret = conn->driver->domainPinEmulator(domain, cpumap, maplen, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetEmulatorPinInfo:
+ * @domain: pointer to domain object, or NULL for Domain0
+ * @cpumap: pointer to a bit map of real CPUs for all emulator threads of
+ * this domain (in 8-bit bytes) (OUT)
+ * There is only one cpumap for all emulator threads.
+ * Must not be NULL.
+ * @maplen: the number of bytes in one cpumap, from 1 up to size of CPU map.
+ * Must be positive.
+ * @flags: bitwise-OR of virDomainModificationImpact
+ * Must not be VIR_DOMAIN_AFFECT_LIVE and
+ * VIR_DOMAIN_AFFECT_CONFIG concurrently.
+ *
+ * Query the CPU affinity setting of all emulator threads of domain, store
+ * it in cpumap.
+ *
+ * Returns 1 in case of success,
+ * 0 in case of no emulator threads are pined to pcpus,
+ * -1 in case of failure.
+ */
+int
+virDomainGetEmulatorPinInfo(virDomainPtr domain, unsigned char *cpumap,
+ int maplen, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "cpumap=%p, maplen=%d, flags=%x",
+ cpumap, maplen, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+
+ virCheckNonNullArgGoto(cpumap, error);
+ virCheckPositiveArgGoto(maplen, error);
+
+ /* At most one of these two flags should be set. */
+ if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
+ (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
+ virReportInvalidArg(flags,
+ _("flags 'affect live' and 'affect
config' in %s "
+ "are mutually exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+ conn = domain->conn;
+
+ if (conn->driver->domainGetEmulatorPinInfo) {
+ int ret;
+ ret = conn->driver->domainGetEmulatorPinInfo(domain, cpumap,
+ maplen, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetVcpus:
+ * @domain: pointer to domain object, or NULL for Domain0
+ * @info: pointer to an array of virVcpuInfo structures (OUT)
+ * @maxinfo: number of structures in info array
+ * @cpumaps: pointer to a bit map of real CPUs for all vcpus of this
+ * domain (in 8-bit bytes) (OUT)
+ * If cpumaps is NULL, then no cpumap information is returned by the API.
+ * It's assumed there is <maxinfo> cpumap in cpumaps array.
+ * The memory allocated to cpumaps must be (maxinfo * maplen) bytes
+ * (ie: calloc(maxinfo, maplen)).
+ * One cpumap inside cpumaps has the format described in
+ * virDomainPinVcpu() API.
+ * @maplen: number of bytes in one cpumap, from 1 up to size of CPU map in
+ * underlying virtualization system (Xen...).
+ * Must be zero when cpumaps is NULL and positive when it is non-NULL.
+ *
+ * Extract information about virtual CPUs of domain, store it in info array
+ * and also in cpumaps if this pointer isn't NULL. This call may fail
+ * on an inactive domain.
+ *
+ * See also virDomainGetVcpuPinInfo for querying just cpumaps, including on
+ * an inactive domain.
+ *
+ * Returns the number of info filled in case of success, -1 in case of failure.
+ */
+int
+virDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo,
+ unsigned char *cpumaps, int maplen)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "info=%p, maxinfo=%d, cpumaps=%p, maplen=%d",
+ info, maxinfo, cpumaps, maplen);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ virCheckNonNullArgGoto(info, error);
+ virCheckPositiveArgGoto(maxinfo, error);
+
+ /* Ensure that domainGetVcpus (aka remoteDomainGetVcpus) does not
+ try to memcpy anything into a NULL pointer. */
+ if (cpumaps)
+ virCheckPositiveArgGoto(maplen, error);
+ else
+ virCheckZeroArgGoto(maplen, error);
+
+ if (cpumaps && INT_MULTIPLY_OVERFLOW(maxinfo, maplen)) {
+ virReportError(VIR_ERR_OVERFLOW, _("input too large: %d * %d"),
+ maxinfo, maplen);
+ goto error;
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetVcpus) {
+ int ret;
+ ret = conn->driver->domainGetVcpus(domain, info, maxinfo,
+ cpumaps, maplen);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetMaxVcpus:
+ * @domain: pointer to domain object
+ *
+ * Provides the maximum number of virtual CPUs supported for
+ * the guest VM. If the guest is inactive, this is basically
+ * the same as virConnectGetMaxVcpus(). If the guest is running
+ * this will reflect the maximum number of virtual CPUs the
+ * guest was booted with. For more details, see virDomainGetVcpusFlags().
+ *
+ * Returns the maximum of virtual CPU or -1 in case of error.
+ */
+int
+virDomainGetMaxVcpus(virDomainPtr domain)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ if (conn->driver->domainGetMaxVcpus) {
+ int ret;
+ ret = conn->driver->domainGetMaxVcpus(domain);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetSecurityLabel:
+ * @domain: a domain object
+ * @seclabel: pointer to a virSecurityLabel structure
+ *
+ * Extract security label of an active domain. The 'label' field
+ * in the @seclabel argument will be initialized to the empty
+ * string if the domain is not running under a security model.
+ *
+ * Returns 0 in case of success, -1 in case of failure
+ */
+int
+virDomainGetSecurityLabel(virDomainPtr domain, virSecurityLabelPtr seclabel)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "seclabel=%p", seclabel);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckNonNullArgGoto(seclabel, error);
+
+ if (conn->driver->domainGetSecurityLabel) {
+ int ret;
+ ret = conn->driver->domainGetSecurityLabel(domain, seclabel);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetSecurityLabelList:
+ * @domain: a domain object
+ * @seclabels: will be auto-allocated and filled with domains' security labels.
+ * Caller must free memory on return.
+ *
+ * Extract the security labels of an active domain. The 'label' field
+ * in the @seclabels argument will be initialized to the empty
+ * string if the domain is not running under a security model.
+ *
+ * Returns number of elemnets in @seclabels on success, -1 in case of failure.
+ */
+int
+virDomainGetSecurityLabelList(virDomainPtr domain,
+ virSecurityLabelPtr* seclabels)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "seclabels=%p", seclabels);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+
+ virCheckNonNullArgGoto(seclabels, error);
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetSecurityLabelList) {
+ int ret;
+ ret = conn->driver->domainGetSecurityLabelList(domain, seclabels);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSetMetadata:
+ * @domain: a domain object
+ * @type: type of metadata, from virDomainMetadataType
+ * @metadata: new metadata text
+ * @key: XML namespace key, or NULL
+ * @uri: XML namespace URI, or NULL
+ * @flags: bitwise-OR of virDomainModificationImpact
+ *
+ * Sets the appropriate domain element given by @type to the
+ * value of @metadata. A @type of VIR_DOMAIN_METADATA_DESCRIPTION
+ * is free-form text; VIR_DOMAIN_METADATA_TITLE is free-form, but no
+ * newlines are permitted, and should be short (although the length is
+ * not enforced). For these two options @key and @uri are irrelevant and
+ * must be set to NULL.
+ *
+ * For type VIR_DOMAIN_METADATA_ELEMENT @metadata must be well-formed
+ * XML belonging to namespace defined by @uri with local name @key.
+ *
+ * Passing NULL for @metadata says to remove that element from the
+ * domain XML (passing the empty string leaves the element present).
+ *
+ * The resulting metadata will be present in virDomainGetXMLDesc(),
+ * as well as quick access through virDomainGetMetadata().
+ *
+ * @flags controls whether the live domain, persistent configuration,
+ * or both will be modified.
+ *
+ * Returns 0 on success, -1 in case of failure.
+ */
+int
+virDomainSetMetadata(virDomainPtr domain,
+ int type,
+ const char *metadata,
+ const char *key,
+ const char *uri,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain,
+ "type=%d, metadata='%s', key='%s',
uri='%s', flags=%x",
+ type, NULLSTR(metadata), NULLSTR(key), NULLSTR(uri),
+ flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ switch (type) {
+ case VIR_DOMAIN_METADATA_TITLE:
+ if (metadata && strchr(metadata, '\n')) {
+ virReportInvalidArg(metadata,
+ _("metadata title in %s can't contain "
+ "newlines"),
+ __FUNCTION__);
+ goto error;
+ }
+ /* fallthrough */
+ case VIR_DOMAIN_METADATA_DESCRIPTION:
+ virCheckNullArgGoto(uri, error);
+ virCheckNullArgGoto(key, error);
+ break;
+ case VIR_DOMAIN_METADATA_ELEMENT:
+ virCheckNonNullArgGoto(uri, error);
+ if (metadata)
+ virCheckNonNullArgGoto(key, error);
+ break;
+ default:
+ /* For future expansion */
+ break;
+ }
+
+ if (conn->driver->domainSetMetadata) {
+ int ret;
+ ret = conn->driver->domainSetMetadata(domain, type, metadata, key, uri,
+ flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetMetadata:
+ * @domain: a domain object
+ * @type: type of metadata, from virDomainMetadataType
+ * @uri: XML namespace identifier
+ * @flags: bitwise-OR of virDomainModificationImpact
+ *
+ * Retrieves the appropriate domain element given by @type.
+ * If VIR_DOMAIN_METADATA_ELEMENT is requested parameter @uri
+ * must be set to the name of the namespace the requested elements
+ * belong to, otherwise must be NULL.
+ *
+ * If an element of the domain XML is not present, the resulting
+ * error will be VIR_ERR_NO_DOMAIN_METADATA. This method forms
+ * a shortcut for seeing information from virDomainSetMetadata()
+ * without having to go through virDomainGetXMLDesc().
+ *
+ * @flags controls whether the live domain or persistent
+ * configuration will be queried.
+ *
+ * Returns the metadata string on success (caller must free),
+ * or NULL in case of failure.
+ */
+char *
+virDomainGetMetadata(virDomainPtr domain,
+ int type,
+ const char *uri,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "type=%d, uri='%s', flags=%x",
+ type, NULLSTR(uri), flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, NULL);
+
+ if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
+ (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
+ virReportInvalidArg(flags,
+ _("flags 'affect live' and 'affect
config' in %s "
+ "are mutually exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ switch (type) {
+ case VIR_DOMAIN_METADATA_TITLE:
+ case VIR_DOMAIN_METADATA_DESCRIPTION:
+ virCheckNullArgGoto(uri, error);
+ break;
+ case VIR_DOMAIN_METADATA_ELEMENT:
+ virCheckNonNullArgGoto(uri, error);
+ break;
+ default:
+ /* For future expansion */
+ break;
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetMetadata) {
+ char *ret;
+ if (!(ret = conn->driver->domainGetMetadata(domain, type, uri, flags)))
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainAttachDevice:
+ * @domain: pointer to domain object
+ * @xml: pointer to XML description of one device
+ *
+ * Create a virtual device attachment to backend. This function,
+ * having hotplug semantics, is only allowed on an active domain.
+ *
+ * For compatibility, this method can also be used to change the media
+ * in an existing CDROM/Floppy device, however, applications are
+ * recommended to use the virDomainUpdateDeviceFlag method instead.
+ *
+ * Be aware that hotplug changes might not persist across a domain going
+ * into S4 state (also known as hibernation) unless you also modify the
+ * persistent domain definition.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virDomainAttachDevice(virDomainPtr domain, const char *xml)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "xml=%s", xml);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckNonNullArgGoto(xml, error);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainAttachDevice) {
+ int ret;
+ ret = conn->driver->domainAttachDevice(domain, xml);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainAttachDeviceFlags:
+ * @domain: pointer to domain object
+ * @xml: pointer to XML description of one device
+ * @flags: bitwise-OR of virDomainDeviceModifyFlags
+ *
+ * Attach a virtual device to a domain, using the flags parameter
+ * to control how the device is attached. VIR_DOMAIN_AFFECT_CURRENT
+ * specifies that the device allocation is made based on current domain
+ * state. VIR_DOMAIN_AFFECT_LIVE specifies that the device shall be
+ * allocated to the active domain instance only and is not added to the
+ * persisted domain configuration. VIR_DOMAIN_AFFECT_CONFIG
+ * specifies that the device shall be allocated to the persisted domain
+ * configuration only. Note that the target hypervisor must return an
+ * error if unable to satisfy flags. E.g. the hypervisor driver will
+ * return failure if LIVE is specified but it only supports modifying the
+ * persisted device allocation.
+ *
+ * For compatibility, this method can also be used to change the media
+ * in an existing CDROM/Floppy device, however, applications are
+ * recommended to use the virDomainUpdateDeviceFlag method instead.
+ *
+ * Be aware that hotplug changes might not persist across a domain going
+ * into S4 state (also known as hibernation) unless you also modify the
+ * persistent domain definition.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virDomainAttachDeviceFlags(virDomainPtr domain,
+ const char *xml, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "xml=%s, flags=%x", xml, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckNonNullArgGoto(xml, error);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainAttachDeviceFlags) {
+ int ret;
+ ret = conn->driver->domainAttachDeviceFlags(domain, xml, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainDetachDevice:
+ * @domain: pointer to domain object
+ * @xml: pointer to XML description of one device
+ *
+ * Destroy a virtual device attachment to backend. This function,
+ * having hot-unplug semantics, is only allowed on an active domain.
+ *
+ * Be aware that hotplug changes might not persist across a domain going
+ * into S4 state (also known as hibernation) unless you also modify the
+ * persistent domain definition.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virDomainDetachDevice(virDomainPtr domain, const char *xml)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "xml=%s", xml);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckNonNullArgGoto(xml, error);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainDetachDevice) {
+ int ret;
+ ret = conn->driver->domainDetachDevice(domain, xml);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainDetachDeviceFlags:
+ * @domain: pointer to domain object
+ * @xml: pointer to XML description of one device
+ * @flags: bitwise-OR of virDomainDeviceModifyFlags
+ *
+ * Detach a virtual device from a domain, using the flags parameter
+ * to control how the device is detached. VIR_DOMAIN_AFFECT_CURRENT
+ * specifies that the device allocation is removed based on current domain
+ * state. VIR_DOMAIN_AFFECT_LIVE specifies that the device shall be
+ * deallocated from the active domain instance only and is not from the
+ * persisted domain configuration. VIR_DOMAIN_AFFECT_CONFIG
+ * specifies that the device shall be deallocated from the persisted domain
+ * configuration only. Note that the target hypervisor must return an
+ * error if unable to satisfy flags. E.g. the hypervisor driver will
+ * return failure if LIVE is specified but it only supports removing the
+ * persisted device allocation.
+ *
+ * Some hypervisors may prevent this operation if there is a current
+ * block copy operation on the device being detached; in that case,
+ * use virDomainBlockJobAbort() to stop the block copy first.
+ *
+ * Beware that depending on the hypervisor and device type, detaching a device
+ * from a running domain may be asynchronous. That is, calling
+ * virDomainDetachDeviceFlags may just request device removal while the device
+ * is actually removed later (in cooperation with a guest OS). Previously,
+ * this fact was ignored and the device could have been removed from domain
+ * configuration before it was actually removed by the hypervisor causing
+ * various failures on subsequent operations. To check whether the device was
+ * successfully removed, either recheck domain configuration using
+ * virDomainGetXMLDesc() or add handler for VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED
+ * event. In case the device is already gone when virDomainDetachDeviceFlags
+ * returns, the event is delivered before this API call ends. To help existing
+ * clients work better in most cases, this API will try to transform an
+ * asynchronous device removal that finishes shortly after the request into
+ * a synchronous removal. In other words, this API may wait a bit for the
+ * removal to complete in case it was not synchronous.
+ *
+ * Be aware that hotplug changes might not persist across a domain going
+ * into S4 state (also known as hibernation) unless you also modify the
+ * persistent domain definition.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virDomainDetachDeviceFlags(virDomainPtr domain,
+ const char *xml, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "xml=%s, flags=%x", xml, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckNonNullArgGoto(xml, error);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainDetachDeviceFlags) {
+ int ret;
+ ret = conn->driver->domainDetachDeviceFlags(domain, xml, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainUpdateDeviceFlags:
+ * @domain: pointer to domain object
+ * @xml: pointer to XML description of one device
+ * @flags: bitwise-OR of virDomainDeviceModifyFlags
+ *
+ * Change a virtual device on a domain, using the flags parameter
+ * to control how the device is changed. VIR_DOMAIN_AFFECT_CURRENT
+ * specifies that the device change is made based on current domain
+ * state. VIR_DOMAIN_AFFECT_LIVE specifies that the device shall be
+ * changed on the active domain instance only and is not added to the
+ * persisted domain configuration. VIR_DOMAIN_AFFECT_CONFIG
+ * specifies that the device shall be changed on the persisted domain
+ * configuration only. Note that the target hypervisor must return an
+ * error if unable to satisfy flags. E.g. the hypervisor driver will
+ * return failure if LIVE is specified but it only supports modifying the
+ * persisted device allocation.
+ *
+ * This method is used for actions such changing CDROM/Floppy device
+ * media, altering the graphics configuration such as password,
+ * reconfiguring the NIC device backend connectivity, etc.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virDomainUpdateDeviceFlags(virDomainPtr domain,
+ const char *xml, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "xml=%s, flags=%x", xml, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckNonNullArgGoto(xml, error);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainUpdateDeviceFlags) {
+ int ret;
+ ret = conn->driver->domainUpdateDeviceFlags(domain, xml, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virConnectDomainEventRegister:
+ * @conn: pointer to the connection
+ * @cb: callback to the function handling domain events
+ * @opaque: opaque data to pass on to the callback
+ * @freecb: optional function to deallocate opaque when not used anymore
+ *
+ * Adds a callback to receive notifications of domain lifecycle events
+ * occurring on a connection. This function requires that an event loop
+ * has been previously registered with virEventRegisterImpl() or
+ * virEventRegisterDefaultImpl().
+ *
+ * Use of this method is no longer recommended. Instead applications
+ * should try virConnectDomainEventRegisterAny() which has a more flexible
+ * API contract.
+ *
+ * The virDomainPtr object handle passed into the callback upon delivery
+ * of an event is only valid for the duration of execution of the callback.
+ * If the callback wishes to keep the domain object after the callback returns,
+ * it shall take a reference to it, by calling virDomainRef.
+ * The reference can be released once the object is no longer required
+ * by calling virDomainFree.
+ *
+ * Returns 0 on success, -1 on failure. Older versions of some hypervisors
+ * sometimes returned a positive number on success, but without any reliable
+ * semantics on what that number represents.
+ */
+int
+virConnectDomainEventRegister(virConnectPtr conn,
+ virConnectDomainEventCallback cb,
+ void *opaque,
+ virFreeCallback freecb)
+{
+ VIR_DEBUG("conn=%p, cb=%p, opaque=%p, freecb=%p", conn, cb, opaque,
freecb);
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+ virCheckNonNullArgGoto(cb, error);
+
+ if (conn->driver && conn->driver->connectDomainEventRegister) {
+ int ret;
+ ret = conn->driver->connectDomainEventRegister(conn, cb, opaque, freecb);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virConnectDomainEventDeregister:
+ * @conn: pointer to the connection
+ * @cb: callback to the function handling domain events
+ *
+ * Removes a callback previously registered with the
+ * virConnectDomainEventRegister() function.
+ *
+ * Use of this method is no longer recommended. Instead applications
+ * should try virConnectDomainEventDeregisterAny() which has a more flexible
+ * API contract
+ *
+ * Returns 0 on success, -1 on failure. Older versions of some hypervisors
+ * sometimes returned a positive number on success, but without any reliable
+ * semantics on what that number represents.
+ */
+int
+virConnectDomainEventDeregister(virConnectPtr conn,
+ virConnectDomainEventCallback cb)
+{
+ VIR_DEBUG("conn=%p, cb=%p", conn, cb);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+ virCheckNonNullArgGoto(cb, error);
+
+ if (conn->driver && conn->driver->connectDomainEventDeregister) {
+ int ret;
+ ret = conn->driver->connectDomainEventDeregister(conn, cb);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainIsActive:
+ * @dom: pointer to the domain object
+ *
+ * Determine if the domain is currently running
+ *
+ * Returns 1 if running, 0 if inactive, -1 on error
+ */
+int
+virDomainIsActive(virDomainPtr dom)
+{
+ VIR_DEBUG("dom=%p", dom);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+
+ if (dom->conn->driver->domainIsActive) {
+ int ret;
+ ret = dom->conn->driver->domainIsActive(dom);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainIsPersistent:
+ * @dom: pointer to the domain object
+ *
+ * Determine if the domain has a persistent configuration
+ * which means it will still exist after shutting down
+ *
+ * Returns 1 if persistent, 0 if transient, -1 on error
+ */
+int
+virDomainIsPersistent(virDomainPtr dom)
+{
+ VIR_DOMAIN_DEBUG(dom);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+
+ if (dom->conn->driver->domainIsPersistent) {
+ int ret;
+ ret = dom->conn->driver->domainIsPersistent(dom);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainIsUpdated:
+ * @dom: pointer to the domain object
+ *
+ * Determine if the domain has been updated.
+ *
+ * Returns 1 if updated, 0 if not, -1 on error
+ */
+int
+virDomainIsUpdated(virDomainPtr dom)
+{
+ VIR_DOMAIN_DEBUG(dom);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+
+ if (dom->conn->driver->domainIsUpdated) {
+ int ret;
+ ret = dom->conn->driver->domainIsUpdated(dom);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetJobInfo:
+ * @domain: a domain object
+ * @info: pointer to a virDomainJobInfo structure allocated by the user
+ *
+ * Extract information about progress of a background job on a domain.
+ * Will return an error if the domain is not active.
+ *
+ * This function returns a limited amount of information in comparison
+ * to virDomainGetJobStats().
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainGetJobInfo(virDomainPtr domain, virDomainJobInfoPtr info)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "info=%p", info);
+
+ virResetLastError();
+
+ if (info)
+ memset(info, 0, sizeof(*info));
+
+ virCheckDomainReturn(domain, -1);
+ virCheckNonNullArgGoto(info, error);
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetJobInfo) {
+ int ret;
+ ret = conn->driver->domainGetJobInfo(domain, info);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetJobStats:
+ * @domain: a domain object
+ * @type: where to store the job type (one of virDomainJobType)
+ * @params: where to store job statistics
+ * @nparams: number of items in @params
+ * @flags: bitwise-OR of virDomainGetJobStatsFlags
+ *
+ * Extract information about progress of a background job on a domain.
+ * Will return an error if the domain is not active. The function returns
+ * a superset of progress information provided by virDomainGetJobInfo.
+ * Possible fields returned in @params are defined by VIR_DOMAIN_JOB_*
+ * macros and new fields will likely be introduced in the future so callers
+ * may receive fields that they do not understand in case they talk to a
+ * newer server.
+ *
+ * When @flags contains VIR_DOMAIN_JOB_STATS_COMPLETED, the function will
+ * return statistics about a recently completed job. Specifically, this
+ * flag may be used to query statistics of a completed incoming migration.
+ * Statistics of a completed job are automatically destroyed once read or
+ * when libvirtd is restarted. Note that time information returned for
+ * completed migrations may be completely irrelevant unless both source and
+ * destination hosts have synchronized time (i.e., NTP daemon is running on
+ * both of them).
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainGetJobStats(virDomainPtr domain,
+ int *type,
+ virTypedParameterPtr *params,
+ int *nparams,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "type=%p, params=%p, nparams=%p, flags=%x",
+ type, params, nparams, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ virCheckNonNullArgGoto(type, error);
+ virCheckNonNullArgGoto(params, error);
+ virCheckNonNullArgGoto(nparams, error);
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetJobStats) {
+ int ret;
+ ret = conn->driver->domainGetJobStats(domain, type, params,
+ nparams, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainAbortJob:
+ * @domain: a domain object
+ *
+ * Requests that the current background job be aborted at the
+ * soonest opportunity.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainAbortJob(virDomainPtr domain)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainAbortJob) {
+ int ret;
+ ret = conn->driver->domainAbortJob(domain);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainMigrateSetMaxDowntime:
+ * @domain: a domain object
+ * @downtime: maximum tolerable downtime for live migration, in milliseconds
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Sets maximum tolerable time for which the domain is allowed to be paused
+ * at the end of live migration. It's supposed to be called while the domain is
+ * being live-migrated as a reaction to migration progress.
+ *
+ * Returns 0 in case of success, -1 otherwise.
+ */
+int
+virDomainMigrateSetMaxDowntime(virDomainPtr domain,
+ unsigned long long downtime,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "downtime=%llu, flags=%x", downtime, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainMigrateSetMaxDowntime) {
+ if (conn->driver->domainMigrateSetMaxDowntime(domain, downtime, flags) <
0)
+ goto error;
+ return 0;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainMigrateGetCompressionCache:
+ * @domain: a domain object
+ * @cacheSize: return value of current size of the cache (in bytes)
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Gets current size of the cache (in bytes) used for compressing repeatedly
+ * transferred memory pages during live migration.
+ *
+ * Returns 0 in case of success, -1 otherwise.
+ */
+int
+virDomainMigrateGetCompressionCache(virDomainPtr domain,
+ unsigned long long *cacheSize,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "cacheSize=%p, flags=%x", cacheSize, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckNonNullArgGoto(cacheSize, error);
+
+ if (conn->driver->domainMigrateGetCompressionCache) {
+ if (conn->driver->domainMigrateGetCompressionCache(domain, cacheSize,
+ flags) < 0)
+ goto error;
+ return 0;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainMigrateSetCompressionCache:
+ * @domain: a domain object
+ * @cacheSize: size of the cache (in bytes) used for compression
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Sets size of the cache (in bytes) used for compressing repeatedly
+ * transferred memory pages during live migration. It's supposed to be called
+ * while the domain is being live-migrated as a reaction to migration progress
+ * and increasing number of compression cache misses obtained from
+ * virDomainGetJobStats.
+ *
+ * Returns 0 in case of success, -1 otherwise.
+ */
+int
+virDomainMigrateSetCompressionCache(virDomainPtr domain,
+ unsigned long long cacheSize,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "cacheSize=%llu, flags=%x", cacheSize, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainMigrateSetCompressionCache) {
+ if (conn->driver->domainMigrateSetCompressionCache(domain, cacheSize,
+ flags) < 0)
+ goto error;
+ return 0;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainMigrateSetMaxSpeed:
+ * @domain: a domain object
+ * @bandwidth: migration bandwidth limit in MiB/s
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * The maximum bandwidth (in MiB/s) that will be used to do migration
+ * can be specified with the bandwidth parameter. Not all hypervisors
+ * will support a bandwidth cap
+ *
+ * Returns 0 in case of success, -1 otherwise.
+ */
+int
+virDomainMigrateSetMaxSpeed(virDomainPtr domain,
+ unsigned long bandwidth,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "bandwidth=%lu, flags=%x", bandwidth, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainMigrateSetMaxSpeed) {
+ if (conn->driver->domainMigrateSetMaxSpeed(domain, bandwidth, flags) <
0)
+ goto error;
+ return 0;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainMigrateGetMaxSpeed:
+ * @domain: a domain object
+ * @bandwidth: return value of current migration bandwidth limit in MiB/s
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Get the current maximum bandwidth (in MiB/s) that will be used if the
+ * domain is migrated. Not all hypervisors will support a bandwidth limit.
+ *
+ * Returns 0 in case of success, -1 otherwise.
+ */
+int
+virDomainMigrateGetMaxSpeed(virDomainPtr domain,
+ unsigned long *bandwidth,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "bandwidth = %p, flags=%x", bandwidth, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckNonNullArgGoto(bandwidth, error);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainMigrateGetMaxSpeed) {
+ if (conn->driver->domainMigrateGetMaxSpeed(domain, bandwidth, flags) <
0)
+ goto error;
+ return 0;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virConnectDomainEventRegisterAny:
+ * @conn: pointer to the connection
+ * @dom: pointer to the domain
+ * @eventID: the event type to receive
+ * @cb: callback to the function handling domain events
+ * @opaque: opaque data to pass on to the callback
+ * @freecb: optional function to deallocate opaque when not used anymore
+ *
+ * Adds a callback to receive notifications of arbitrary domain events
+ * occurring on a domain. This function requires that an event loop
+ * has been previously registered with virEventRegisterImpl() or
+ * virEventRegisterDefaultImpl().
+ *
+ * If @dom is NULL, then events will be monitored for any domain. If @dom
+ * is non-NULL, then only the specific domain will be monitored.
+ *
+ * Most types of event have a callback providing a custom set of parameters
+ * for the event. When registering an event, it is thus necessary to use
+ * the VIR_DOMAIN_EVENT_CALLBACK() macro to cast the supplied function pointer
+ * to match the signature of this method.
+ *
+ * The virDomainPtr object handle passed into the callback upon delivery
+ * of an event is only valid for the duration of execution of the callback.
+ * If the callback wishes to keep the domain object after the callback returns,
+ * it shall take a reference to it, by calling virDomainRef().
+ * The reference can be released once the object is no longer required
+ * by calling virDomainFree().
+ *
+ * The return value from this method is a positive integer identifier
+ * for the callback. To unregister a callback, this callback ID should
+ * be passed to the virConnectDomainEventDeregisterAny() method.
+ *
+ * Returns a callback identifier on success, -1 on failure.
+ */
+int
+virConnectDomainEventRegisterAny(virConnectPtr conn,
+ virDomainPtr dom,
+ int eventID,
+ virConnectDomainEventGenericCallback cb,
+ void *opaque,
+ virFreeCallback freecb)
+{
+ VIR_DOMAIN_DEBUG(dom, "conn=%p, eventID=%d, cb=%p, opaque=%p, freecb=%p",
+ conn, eventID, cb, opaque, freecb);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+ if (dom) {
+ virCheckDomainGoto(dom, error);
+ if (dom->conn != conn) {
+ virReportInvalidArg(dom,
+ _("domain '%s' in %s must match
connection"),
+ dom->name, __FUNCTION__);
+ goto error;
+ }
+ }
+ virCheckNonNullArgGoto(cb, error);
+ virCheckNonNegativeArgGoto(eventID, error);
+ if (eventID >= VIR_DOMAIN_EVENT_ID_LAST) {
+ virReportInvalidArg(eventID,
+ _("eventID in %s must be less than %d"),
+ __FUNCTION__, VIR_DOMAIN_EVENT_ID_LAST);
+ goto error;
+ }
+
+ if (conn->driver && conn->driver->connectDomainEventRegisterAny) {
+ int ret;
+ ret = conn->driver->connectDomainEventRegisterAny(conn, dom, eventID, cb,
opaque, freecb);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virConnectDomainEventDeregisterAny:
+ * @conn: pointer to the connection
+ * @callbackID: the callback identifier
+ *
+ * Removes an event callback. The callbackID parameter should be the
+ * value obtained from a previous virConnectDomainEventRegisterAny() method.
+ *
+ * Returns 0 on success, -1 on failure. Older versions of some hypervisors
+ * sometimes returned a positive number on success, but without any reliable
+ * semantics on what that number represents. */
+int
+virConnectDomainEventDeregisterAny(virConnectPtr conn,
+ int callbackID)
+{
+ VIR_DEBUG("conn=%p, callbackID=%d", conn, callbackID);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+ virCheckNonNegativeArgGoto(callbackID, error);
+
+ if (conn->driver && conn->driver->connectDomainEventDeregisterAny)
{
+ int ret;
+ ret = conn->driver->connectDomainEventDeregisterAny(conn, callbackID);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainManagedSave:
+ * @dom: pointer to the domain
+ * @flags: bitwise-OR of virDomainSaveRestoreFlags
+ *
+ * This method will suspend a domain and save its memory contents to
+ * a file on disk. After the call, if successful, the domain is not
+ * listed as running anymore.
+ * The difference from virDomainSave() is that libvirt is keeping track of
+ * the saved state itself, and will reuse it once the domain is being
+ * restarted (automatically or via an explicit libvirt call).
+ * As a result any running domain is sure to not have a managed saved image.
+ * This also implies that managed save only works on persistent domains,
+ * since the domain must still exist in order to use virDomainCreate() to
+ * restart it.
+ *
+ * If @flags includes VIR_DOMAIN_SAVE_BYPASS_CACHE, then libvirt will
+ * attempt to bypass the file system cache while creating 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 saves to NFS.
+ *
+ * Normally, the managed saved state will remember whether the domain
+ * was running or paused, and start will resume to the same state.
+ * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in
+ * @flags will override the default saved into the file. These two
+ * flags are mutually exclusive.
+ *
+ * Returns 0 in case of success or -1 in case of failure
+ */
+int
+virDomainManagedSave(virDomainPtr dom, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if ((flags & VIR_DOMAIN_SAVE_RUNNING) && (flags &
VIR_DOMAIN_SAVE_PAUSED)) {
+ virReportInvalidArg(flags,
+ _("running and paused flags in %s are mutually "
+ "exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainManagedSave) {
+ int ret;
+
+ ret = conn->driver->domainManagedSave(dom, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainHasManagedSaveImage:
+ * @dom: pointer to the domain
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Check if a domain has a managed save image as created by
+ * virDomainManagedSave(). Note that any running domain should not have
+ * such an image, as it should have been removed on restart.
+ *
+ * Returns 0 if no image is present, 1 if an image is present, and
+ * -1 in case of error
+ */
+int
+virDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ if (conn->driver->domainHasManagedSaveImage) {
+ int ret;
+
+ ret = conn->driver->domainHasManagedSaveImage(dom, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainManagedSaveRemove:
+ * @dom: pointer to the domain
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Remove any managed save image for this domain.
+ *
+ * Returns 0 in case of success, and -1 in case of error
+ */
+int
+virDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainManagedSaveRemove) {
+ int ret;
+
+ ret = conn->driver->domainManagedSaveRemove(dom, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+
+/**
+ * virDomainOpenConsole:
+ * @dom: a domain object
+ * @dev_name: the console, serial or parallel port device alias, or NULL
+ * @st: a stream to associate with the console
+ * @flags: bitwise-OR of virDomainConsoleFlags
+ *
+ * This opens the backend associated with a console, serial or
+ * parallel port device on a guest, if the backend is supported.
+ * If the @dev_name is omitted, then the first console or serial
+ * device is opened. The console is associated with the passed
+ * in @st stream, which should have been opened in non-blocking
+ * mode for bi-directional I/O.
+ *
+ * By default, when @flags is 0, the open will fail if libvirt
+ * detects that the console is already in use by another client;
+ * passing VIR_DOMAIN_CONSOLE_FORCE will cause libvirt to forcefully
+ * remove the other client prior to opening this console.
+ *
+ * If flag VIR_DOMAIN_CONSOLE_SAFE the console is opened only in the
+ * case where the hypervisor driver supports safe (mutually exclusive)
+ * console handling.
+ *
+ * Older servers did not support either flag, and also did not forbid
+ * simultaneous clients on a console, with potentially confusing results.
+ * When passing @flags of 0 in order to support a wider range of server
+ * versions, it is up to the client to ensure mutual exclusion.
+ *
+ * Returns 0 if the console was opened, -1 on error
+ */
+int
+virDomainOpenConsole(virDomainPtr dom,
+ const char *dev_name,
+ virStreamPtr st,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "dev_name=%s, st=%p, flags=%x",
+ NULLSTR(dev_name), st, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckStreamGoto(st, error);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn != st->conn) {
+ virReportInvalidArg(st,
+ _("stream in %s must match connection of domain
'%s'"),
+ __FUNCTION__, dom->name);
+ goto error;
+ }
+
+ if (conn->driver->domainOpenConsole) {
+ int ret;
+ ret = conn->driver->domainOpenConsole(dom, dev_name, st, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainOpenChannel:
+ * @dom: a domain object
+ * @name: the channel name, or NULL
+ * @st: a stream to associate with the channel
+ * @flags: bitwise-OR of virDomainChannelFlags
+ *
+ * This opens the host interface associated with a channel device on a
+ * guest, if the host interface is supported. If @name is given, it
+ * can match either the device alias (e.g. "channel0"), or the virtio
+ * target name (e.g. "org.qemu.guest_agent.0"). If @name is omitted,
+ * then the first channel is opened. The channel is associated with
+ * the passed in @st stream, which should have been opened in
+ * non-blocking mode for bi-directional I/O.
+ *
+ * By default, when @flags is 0, the open will fail if libvirt detects
+ * that the channel is already in use by another client; passing
+ * VIR_DOMAIN_CHANNEL_FORCE will cause libvirt to forcefully remove the
+ * other client prior to opening this channel.
+ *
+ * Returns 0 if the channel was opened, -1 on error
+ */
+int
+virDomainOpenChannel(virDomainPtr dom,
+ const char *name,
+ virStreamPtr st,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "name=%s, st=%p, flags=%x",
+ NULLSTR(name), st, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckStreamGoto(st, error);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn != st->conn) {
+ virReportInvalidArg(st,
+ _("stream in %s must match connection of domain
'%s'"),
+ __FUNCTION__, dom->name);
+ goto error;
+ }
+
+ if (conn->driver->domainOpenChannel) {
+ int ret;
+ ret = conn->driver->domainOpenChannel(dom, name, st, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainBlockJobAbort:
+ * @dom: pointer to domain object
+ * @disk: path to the block device, or device shorthand
+ * @flags: bitwise-OR of virDomainBlockJobAbortFlags
+ *
+ * Cancel the active block job on the given disk.
+ *
+ * The @disk parameter is either an unambiguous source name of the
+ * block device (the <source file='...'/> sub-element, such as
+ * "/path/to/image"), or (since 0.9.5) the device target shorthand
+ * (the <target dev='...'/> sub-element, such as "vda"). Valid
names
+ * can be found by calling virDomainGetXMLDesc() and inspecting
+ * elements within //domain/devices/disk.
+ *
+ * If the current block job for @disk is VIR_DOMAIN_BLOCK_JOB_TYPE_PULL, then
+ * by default, this function performs a synchronous operation and the caller
+ * may assume that the operation has completed when 0 is returned. However,
+ * BlockJob operations may take a long time to cancel, and during this time
+ * further domain interactions may be unresponsive. To avoid this problem,
+ * pass VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC in the @flags argument to enable
+ * asynchronous behavior, returning as soon as possible. When the job has
+ * been canceled, a BlockJob event will be emitted, with status
+ * VIR_DOMAIN_BLOCK_JOB_CANCELED (even if the ABORT_ASYNC flag was not
+ * used); it is also possible to poll virDomainBlockJobInfo() to see if
+ * the job cancellation is still pending. This type of job can be restarted
+ * to pick up from where it left off.
+ *
+ * If the current block job for @disk is VIR_DOMAIN_BLOCK_JOB_TYPE_COPY, then
+ * the default is to abort the mirroring and revert to the source disk;
+ * likewise, if the current job is VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT,
+ * the default is to abort without changing the active layer of @disk.
+ * Adding @flags of VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT causes this call to
+ * fail with VIR_ERR_BLOCK_COPY_ACTIVE if the copy or commit is not yet
+ * ready; otherwise it will swap the disk over to the new active image
+ * to end the mirroring or active commit. An event will be issued when the
+ * job is ended, and it is possible to use VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC
+ * to control whether this command waits for the completion of the job.
+ * Restarting a copy or active commit job requires starting over from the
+ * beginning of the first phase.
+ *
+ * Returns -1 in case of failure, 0 when successful.
+ */
+int
+virDomainBlockJobAbort(virDomainPtr dom, const char *disk,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "disk=%s, flags=%x", disk, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(disk, error);
+
+ if (conn->driver->domainBlockJobAbort) {
+ int ret;
+ ret = conn->driver->domainBlockJobAbort(dom, disk, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetBlockJobInfo:
+ * @dom: pointer to domain object
+ * @disk: path to the block device, or device shorthand
+ * @info: pointer to a virDomainBlockJobInfo structure
+ * @flags: bitwise-OR of virDomainBlockJobInfoFlags
+ *
+ * Request block job information for the given disk. If an operation is active
+ * @info will be updated with the current progress. The units used for the
+ * bandwidth field of @info depends on @flags. If @flags includes
+ * VIR_DOMAIN_BLOCK_JOB_INFO_BANDWIDTH_BYTES, bandwidth is in bytes/second
+ * (although this mode can risk failure due to overflow, depending on both
+ * client and server word size); otherwise, the value is rounded up to MiB/s.
+ *
+ * The @disk parameter is either an unambiguous source name of the
+ * block device (the <source file='...'/> sub-element, such as
+ * "/path/to/image"), or (since 0.9.5) the device target shorthand
+ * (the <target dev='...'/> sub-element, such as "vda"). Valid
names
+ * can be found by calling virDomainGetXMLDesc() and inspecting
+ * elements within //domain/devices/disk.
+ *
+ * Returns -1 in case of failure, 0 when nothing found, 1 when info was found.
+ */
+int
+virDomainGetBlockJobInfo(virDomainPtr dom, const char *disk,
+ virDomainBlockJobInfoPtr info, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "disk=%s, info=%p, flags=%x", disk, info, flags);
+
+ virResetLastError();
+
+ if (info)
+ memset(info, 0, sizeof(*info));
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckNonNullArgGoto(disk, error);
+ virCheckNonNullArgGoto(info, error);
+
+ if (conn->driver->domainGetBlockJobInfo) {
+ int ret;
+ ret = conn->driver->domainGetBlockJobInfo(dom, disk, info, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainBlockJobSetSpeed:
+ * @dom: pointer to domain object
+ * @disk: path to the block device, or device shorthand
+ * @bandwidth: specify bandwidth limit; flags determine the unit
+ * @flags: bitwise-OR of virDomainBlockJobSetSpeedFlags
+ *
+ * Set the maximimum allowable bandwidth that a block job may consume. If
+ * bandwidth is 0, the limit will revert to the hypervisor default of
+ * unlimited.
+ *
+ * If @flags contains VIR_DOMAIN_BLOCK_JOB_SPEED_BANDWIDTH_BYTES, @bandwidth
+ * is in bytes/second; otherwise, it is in MiB/second. Values larger than
+ * 2^52 bytes/sec may be rejected due to overflow considerations based on
+ * the word size of both client and server, and values larger than 2^31
+ * bytes/sec may cause overflow problems if later queried by
+ * virDomainGetBlockJobInfo() without scaling. Hypervisors may further
+ * restrict the range of valid bandwidth values.
+ *
+ * The @disk parameter is either an unambiguous source name of the
+ * block device (the <source file='...'/> sub-element, such as
+ * "/path/to/image"), or (since 0.9.5) the device target shorthand
+ * (the <target dev='...'/> sub-element, such as "vda"). Valid
names
+ * can be found by calling virDomainGetXMLDesc() and inspecting
+ * elements within //domain/devices/disk.
+ *
+ * Returns -1 in case of failure, 0 when successful.
+ */
+int
+virDomainBlockJobSetSpeed(virDomainPtr dom, const char *disk,
+ unsigned long bandwidth, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "disk=%s, bandwidth=%lu, flags=%x",
+ disk, bandwidth, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(disk, error);
+
+ if (conn->driver->domainBlockJobSetSpeed) {
+ int ret;
+ ret = conn->driver->domainBlockJobSetSpeed(dom, disk, bandwidth, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainBlockPull:
+ * @dom: pointer to domain object
+ * @disk: path to the block device, or device shorthand
+ * @bandwidth: (optional) specify bandwidth limit; flags determine the unit
+ * @flags: bitwise-OR of virDomainBlockPullFlags
+ *
+ * Populate a disk image with data from its backing image. Once all data from
+ * its backing image has been pulled, the disk no longer depends on a backing
+ * image. This function pulls data for the entire device in the background.
+ * Progress of the operation can be checked with virDomainGetBlockJobInfo() and
+ * the operation can be aborted with virDomainBlockJobAbort(). When finished,
+ * an asynchronous event is raised to indicate the final status. To move
+ * data in the opposite direction, see virDomainBlockCommit().
+ *
+ * The @disk parameter is either an unambiguous source name of the
+ * block device (the <source file='...'/> sub-element, such as
+ * "/path/to/image"), or (since 0.9.5) the device target shorthand
+ * (the <target dev='...'/> sub-element, such as "vda"). Valid
names
+ * can be found by calling virDomainGetXMLDesc() and inspecting
+ * elements within //domain/devices/disk.
+ *
+ * The maximum bandwidth that will be used to do the copy can be
+ * specified with the @bandwidth parameter. If set to 0, there is no
+ * limit. If @flags includes VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES,
+ * @bandwidth is in bytes/second; otherwise, it is in MiB/second.
+ * Values larger than 2^52 bytes/sec may be rejected due to overflow
+ * considerations based on the word size of both client and server,
+ * and values larger than 2^31 bytes/sec may cause overflow problems
+ * if later queried by virDomainGetBlockJobInfo() without scaling.
+ * Hypervisors may further restrict the range of valid bandwidth
+ * values. Some hypervisors do not support this feature and will
+ * return an error if bandwidth is not 0; in this case, it might still
+ * be possible for a later call to virDomainBlockJobSetSpeed() to
+ * succeed. The actual speed can be determined with
+ * virDomainGetBlockJobInfo().
+ *
+ * This is shorthand for virDomainBlockRebase() with a NULL base.
+ *
+ * Returns 0 if the operation has started, -1 on failure.
+ */
+int
+virDomainBlockPull(virDomainPtr dom, const char *disk,
+ unsigned long bandwidth, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "disk=%s, bandwidth=%lu, flags=%x",
+ disk, bandwidth, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(disk, error);
+
+ if (conn->driver->domainBlockPull) {
+ int ret;
+ ret = conn->driver->domainBlockPull(dom, disk, bandwidth, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainBlockRebase:
+ * @dom: pointer to domain object
+ * @disk: path to the block device, or device shorthand
+ * @base: path to backing file to keep, or device shorthand,
+ * or NULL for no backing file
+ * @bandwidth: (optional) specify bandwidth limit; flags determine the unit
+ * @flags: bitwise-OR of virDomainBlockRebaseFlags
+ *
+ * Populate a disk image with data from its backing image chain, and
+ * setting the backing image to @base, or alternatively copy an entire
+ * backing chain to a new file @base.
+ *
+ * When @flags is 0, this starts a pull, where @base must be the absolute
+ * path of one of the backing images further up the chain, or NULL to
+ * convert the disk image so that it has no backing image. Once all
+ * data from its backing image chain has been pulled, the disk no
+ * longer depends on those intermediate backing images. This function
+ * pulls data for the entire device in the background. Progress of
+ * the operation can be checked with virDomainGetBlockJobInfo() with a
+ * job type of VIR_DOMAIN_BLOCK_JOB_TYPE_PULL, and the operation can be
+ * aborted with virDomainBlockJobAbort(). When finished, an asynchronous
+ * event is raised to indicate the final status, and the job no longer
+ * exists. If the job is aborted, a new one can be started later to
+ * resume from the same point.
+ *
+ * If @flags contains VIR_DOMAIN_BLOCK_REBASE_RELATIVE, the name recorded
+ * into the active disk as the location for @base will be kept relative.
+ * The operation will fail if libvirt can't infer the name.
+ *
+ * When @flags includes VIR_DOMAIN_BLOCK_REBASE_COPY, this starts a copy,
+ * where @base must be the name of a new file to copy the chain to. By
+ * default, the copy will pull the entire source chain into the destination
+ * file, but if @flags also contains VIR_DOMAIN_BLOCK_REBASE_SHALLOW, then
+ * only the top of the source chain will be copied (the source and
+ * destination have a common backing file). By default, @base will be
+ * created with the same file format as the source, but this can be altered
+ * by adding VIR_DOMAIN_BLOCK_REBASE_COPY_RAW to force the copy to be raw
+ * (does not make sense with the shallow flag unless the source is also raw),
+ * or by using VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT to reuse an existing file
+ * which was pre-created with the correct format and metadata and sufficient
+ * size to hold the copy. In case the VIR_DOMAIN_BLOCK_REBASE_SHALLOW flag
+ * is used the pre-created file has to exhibit the same guest visible contents
+ * as the backing file of the original image. This allows a management app to
+ * pre-create files with relative backing file names, rather than the default
+ * of absolute backing file names; as a security precaution, you should
+ * generally only use reuse_ext with the shallow flag and a non-raw
+ * destination file. By default, the copy destination will be treated as
+ * type='file', but using VIR_DOMAIN_BLOCK_REBASE_COPY_DEV treats the
+ * destination as type='block' (affecting how virDomainGetBlockInfo() will
+ * report allocation after pivoting).
+ *
+ * A copy job has two parts; in the first phase, the @bandwidth parameter
+ * affects how fast the source is pulled into the destination, and the job
+ * can only be canceled by reverting to the source file; progress in this
+ * phase can be tracked via the virDomainBlockJobInfo() command, with a
+ * job type of VIR_DOMAIN_BLOCK_JOB_TYPE_COPY. The job transitions to the
+ * second phase when the job info states cur == end, and remains alive to
+ * mirror all further changes to both source and destination. The user
+ * must call virDomainBlockJobAbort() to end the mirroring while choosing
+ * whether to revert to source or pivot to the destination. An event is
+ * issued when the job ends, and depending on the hypervisor, an event may
+ * also be issued when the job transitions from pulling to mirroring. If
+ * the job is aborted, a new job will have to start over from the beginning
+ * of the first phase.
+ *
+ * Some hypervisors will restrict certain actions, such as virDomainSave()
+ * or virDomainDetachDevice(), while a copy job is active; they may
+ * also restrict a copy job to transient domains.
+ *
+ * The @disk parameter is either an unambiguous source name of the
+ * block device (the <source file='...'/> sub-element, such as
+ * "/path/to/image"), or the device target shorthand (the
+ * <target dev='...'/> sub-element, such as "vda"). Valid names
+ * can be found by calling virDomainGetXMLDesc() and inspecting
+ * elements within //domain/devices/disk.
+ *
+ * The @base parameter can be either a path to a file within the backing
+ * chain, or the device target shorthand (the <target dev='...'/>
+ * sub-element, such as "vda") followed by an index to the backing chain
+ * enclosed in square brackets. Backing chain indexes can be found by
+ * inspecting //disk//backingStore/@index in the domain XML. Thus, for
+ * example, "vda[3]" refers to the backing store with index equal to
"3"
+ * in the chain of disk "vda".
+ *
+ * The maximum bandwidth that will be used to do the copy can be
+ * specified with the @bandwidth parameter. If set to 0, there is no
+ * limit. If @flags includes VIR_DOMAIN_BLOCK_REBASE_BANDWIDTH_BYTES,
+ * @bandwidth is in bytes/second; otherwise, it is in MiB/second.
+ * Values larger than 2^52 bytes/sec may be rejected due to overflow
+ * considerations based on the word size of both client and server,
+ * and values larger than 2^31 bytes/sec may cause overflow problems
+ * if later queried by virDomainGetBlockJobInfo() without scaling.
+ * Hypervisors may further restrict the range of valid bandwidth
+ * values. Some hypervisors do not support this feature and will
+ * return an error if bandwidth is not 0; in this case, it might still
+ * be possible for a later call to virDomainBlockJobSetSpeed() to
+ * succeed. The actual speed can be determined with
+ * virDomainGetBlockJobInfo().
+ *
+ * When @base is NULL and @flags is 0, this is identical to
+ * virDomainBlockPull(). When @flags contains VIR_DOMAIN_BLOCK_REBASE_COPY,
+ * this command is shorthand for virDomainBlockCopy() where the destination
+ * XML encodes @base as a <disk type='file'>, @bandwidth is properly
scaled
+ * and passed as a typed parameter, the shallow and reuse external flags
+ * are preserved, and remaining flags control whether the XML encodes a
+ * destination format of raw instead of leaving the destination identical
+ * to the source format or probed from the reused file.
+ *
+ * Returns 0 if the operation has started, -1 on failure.
+ */
+int
+virDomainBlockRebase(virDomainPtr dom, const char *disk,
+ const char *base, unsigned long bandwidth,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "disk=%s, base=%s, bandwidth=%lu, flags=%x",
+ disk, NULLSTR(base), bandwidth, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(disk, error);
+
+ if (flags & VIR_DOMAIN_BLOCK_REBASE_COPY) {
+ virCheckNonNullArgGoto(base, error);
+ } else if (flags & (VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
+ VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT |
+ VIR_DOMAIN_BLOCK_REBASE_COPY_RAW |
+ VIR_DOMAIN_BLOCK_REBASE_COPY_DEV)) {
+ virReportInvalidArg(flags,
+ _("use of flags in %s requires a copy job"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainBlockRebase) {
+ int ret;
+ ret = conn->driver->domainBlockRebase(dom, disk, base, bandwidth,
+ flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainBlockCopy:
+ * @dom: pointer to domain object
+ * @disk: path to the block device, or device shorthand
+ * @destxml: XML description of the copy destination
+ * @params: Pointer to block copy parameter objects, or NULL
+ * @nparams: Number of block copy parameters (this value can be the same or
+ * less than the number of parameters supported)
+ * @flags: bitwise-OR of virDomainBlockCopyFlags
+ *
+ * Copy the guest-visible contents of a disk image to a new file described
+ * by @destxml. The destination XML has a top-level element of <disk>, and
+ * resembles what is used when hot-plugging a disk via virDomainAttachDevice(),
+ * except that only sub-elements related to describing the new host resource
+ * are necessary (sub-elements related to the guest view, such as <target>,
+ * are ignored). It is strongly recommended to include a <driver
type='...'/>
+ * format designation for the destination, to avoid the potential of any
+ * security problem that might be caused by probing a file for its format.
+ *
+ * This command starts a long-running copy. By default, the copy will pull
+ * the entire source chain into the destination file, but if @flags also
+ * contains VIR_DOMAIN_BLOCK_COPY_SHALLOW, then only the top of the source
+ * chain will be copied (the source and destination have a common backing
+ * file). The format of the destination file is controlled by the <driver>
+ * sub-element of the XML. The destination will be created unless the
+ * VIR_DOMAIN_BLOCK_COPY_REUSE_EXT flag is present stating that the file
+ * was pre-created with the correct format and metadata and sufficient
+ * size to hold the copy. In case the VIR_DOMAIN_BLOCK_COPY_SHALLOW flag
+ * is used the pre-created file has to exhibit the same guest visible contents
+ * as the backing file of the original image. This allows a management app to
+ * pre-create files with relative backing file names, rather than the default
+ * of absolute backing file names.
+ *
+ * A copy job has two parts; in the first phase, the source is copied into
+ * the destination, and the job can only be canceled by reverting to the
+ * source file; progress in this phase can be tracked via the
+ * virDomainBlockJobInfo() command, with a job type of
+ * VIR_DOMAIN_BLOCK_JOB_TYPE_COPY. The job transitions to the second
+ * phase when the job info states cur == end, and remains alive to mirror
+ * all further changes to both source and destination. The user must
+ * call virDomainBlockJobAbort() to end the mirroring while choosing
+ * whether to revert to source or pivot to the destination. An event is
+ * issued when the job ends, and depending on the hypervisor, an event may
+ * also be issued when the job transitions from pulling to mirroring. If
+ * the job is aborted, a new job will have to start over from the beginning
+ * of the first phase.
+ *
+ * Some hypervisors will restrict certain actions, such as virDomainSave()
+ * or virDomainDetachDevice(), while a copy job is active; they may
+ * also restrict a copy job to transient domains.
+ *
+ * The @disk parameter is either an unambiguous source name of the
+ * block device (the <source file='...'/> sub-element, such as
+ * "/path/to/image"), or the device target shorthand (the
+ * <target dev='...'/> sub-element, such as "vda"). Valid names
+ * can be found by calling virDomainGetXMLDesc() and inspecting
+ * elements within //domain/devices/disk.
+ *
+ * The @params and @nparams arguments can be used to set hypervisor-specific
+ * tuning parameters, such as maximum bandwidth or granularity. For a
+ * parameter that the hypervisor understands, explicitly specifying 0
+ * behaves the same as omitting the parameter, to use the hypervisor
+ * default; however, omitting a parameter is less likely to fail.
+ *
+ * This command is a superset of the older virDomainBlockRebase() when used
+ * with the VIR_DOMAIN_BLOCK_REBASE_COPY flag, and offers better control
+ * over the destination format, the ability to copy to a destination that
+ * is not a local file, and the possibility of additional tuning parameters.
+ *
+ * Returns 0 if the operation has started, -1 on failure.
+ */
+int
+virDomainBlockCopy(virDomainPtr dom, const char *disk,
+ const char *destxml,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom,
+ "disk=%s, destxml=%s, params=%p, nparams=%d, flags=%x",
+ disk, destxml, params, nparams, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(disk, error);
+ virCheckNonNullArgGoto(destxml, error);
+ virCheckNonNegativeArgGoto(nparams, error);
+ if (nparams)
+ virCheckNonNullArgGoto(params, error);
+
+ if (conn->driver->domainBlockCopy) {
+ int ret;
+ ret = conn->driver->domainBlockCopy(dom, disk, destxml,
+ params, nparams, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainBlockCommit:
+ * @dom: pointer to domain object
+ * @disk: path to the block device, or device shorthand
+ * @base: path to backing file to merge into, or device shorthand,
+ * or NULL for default
+ * @top: path to file within backing chain that contains data to be merged,
+ * or device shorthand, or NULL to merge all possible data
+ * @bandwidth: (optional) specify bandwidth limit; flags determine the unit
+ * @flags: bitwise-OR of virDomainBlockCommitFlags
+ *
+ * Commit changes that were made to temporary top-level files within a disk
+ * image backing file chain into a lower-level base file. In other words,
+ * take all the difference between @base and @top, and update @base to contain
+ * that difference; after the commit, any portion of the chain that previously
+ * depended on @top will now depend on @base, and all files after @base up
+ * to and including @top will now be invalidated. A typical use of this
+ * command is to reduce the length of a backing file chain after taking an
+ * external disk snapshot. To move data in the opposite direction, see
+ * virDomainBlockPull().
+ *
+ * This command starts a long-running commit block job, whose status may
+ * be tracked by virDomainBlockJobInfo() with a job type of
+ * VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT, and the operation can be aborted with
+ * virDomainBlockJobAbort(). When finished, an asynchronous event is
+ * raised to indicate the final status, and the job no longer exists. If
+ * the job is aborted, it is up to the hypervisor whether starting a new
+ * job will resume from the same point, or start over.
+ *
+ * As a special case, if @top is the active image (or NULL), and @flags
+ * includes VIR_DOMAIN_BLOCK_COMMIT_ACTIVE, the block job will have a type
+ * of VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT, and operates in two phases.
+ * In the first phase, the contents are being committed into @base, and the
+ * job can only be canceled. The job transitions to the second phase when
+ * the job info states cur == end, and remains alive to keep all further
+ * changes to @top synchronized into @base; an event with status
+ * VIR_DOMAIN_BLOCK_JOB_READY is also issued to mark the job transition.
+ * Once in the second phase, the user must choose whether to cancel the job
+ * (keeping @top as the active image, but now containing only the changes
+ * since the time the job ended) or to pivot the job (adjusting to @base as
+ * the active image, and invalidating @top).
+ *
+ * Be aware that this command may invalidate files even if it is aborted;
+ * the user is cautioned against relying on the contents of invalidated
+ * intermediate files such as @top (when @top is not the active image)
+ * without manually rebasing those files to use a backing file of a
+ * read-only copy of @base prior to the point where the commit operation
+ * was started (and such a rebase cannot be safely done until the commit
+ * has successfully completed). However, the domain itself will not have
+ * any issues; the active layer remains valid throughout the entire commit
+ * operation.
+ *
+ * Some hypervisors may support a shortcut where if @flags contains
+ * VIR_DOMAIN_BLOCK_COMMIT_DELETE, then this command will unlink all files
+ * that were invalidated, after the commit successfully completes.
+ *
+ * If @flags contains VIR_DOMAIN_BLOCK_COMMIT_RELATIVE, the name recorded
+ * into the overlay of the @top image (if there is such image) as the
+ * path to the new backing file will be kept relative to other images.
+ * The operation will fail if libvirt can't infer the name.
+ *
+ * By default, if @base is NULL, the commit target will be the bottom of
+ * the backing chain; if @flags contains VIR_DOMAIN_BLOCK_COMMIT_SHALLOW,
+ * then the immediate backing file of @top will be used instead. If @top
+ * is NULL, the active image at the top of the chain will be used. Some
+ * hypervisors place restrictions on how much can be committed, and might
+ * fail if @base is not the immediate backing file of @top, or if @top is
+ * the active layer in use by a running domain but @flags did not include
+ * VIR_DOMAIN_BLOCK_COMMIT_ACTIVE, or if @top is not the top-most file;
+ * restrictions may differ for online vs. offline domains.
+ *
+ * The @disk parameter is either an unambiguous source name of the
+ * block device (the <source file='...'/> sub-element, such as
+ * "/path/to/image"), or the device target shorthand (the
+ * <target dev='...'/> sub-element, such as "vda"). Valid names
+ * can be found by calling virDomainGetXMLDesc() and inspecting
+ * elements within //domain/devices/disk.
+ *
+ * The @base and @top parameters can be either paths to files within the
+ * backing chain, or the device target shorthand (the <target dev='...'/>
+ * sub-element, such as "vda") followed by an index to the backing chain
+ * enclosed in square brackets. Backing chain indexes can be found by
+ * inspecting //disk//backingStore/@index in the domain XML. Thus, for
+ * example, "vda[3]" refers to the backing store with index equal to
"3"
+ * in the chain of disk "vda".
+ *
+ * The maximum bandwidth that will be used to do the commit can be
+ * specified with the @bandwidth parameter. If set to 0, there is no
+ * limit. If @flags includes VIR_DOMAIN_BLOCK_COMMIT_BANDWIDTH_BYTES,
+ * @bandwidth is in bytes/second; otherwise, it is in MiB/second.
+ * Values larger than 2^52 bytes/sec may be rejected due to overflow
+ * considerations based on the word size of both client and server,
+ * and values larger than 2^31 bytes/sec may cause overflow problems
+ * if later queried by virDomainGetBlockJobInfo() without scaling.
+ * Hypervisors may further restrict the range of valid bandwidth
+ * values. Some hypervisors do not support this feature and will
+ * return an error if bandwidth is not 0; in this case, it might still
+ * be possible for a later call to virDomainBlockJobSetSpeed() to
+ * succeed. The actual speed can be determined with
+ * virDomainGetBlockJobInfo().
+ *
+ * Returns 0 if the operation has started, -1 on failure.
+ */
+int
+virDomainBlockCommit(virDomainPtr dom, const char *disk,
+ const char *base, const char *top,
+ unsigned long bandwidth, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "disk=%s, base=%s, top=%s, bandwidth=%lu, flags=%x",
+ disk, NULLSTR(base), NULLSTR(top), bandwidth, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(disk, error);
+
+ if (conn->driver->domainBlockCommit) {
+ int ret;
+ ret = conn->driver->domainBlockCommit(dom, disk, base, top, bandwidth,
+ flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainOpenGraphics:
+ * @dom: pointer to domain object
+ * @idx: index of graphics config to open
+ * @fd: file descriptor to attach graphics to
+ * @flags: bitwise-OR of virDomainOpenGraphicsFlags
+ *
+ * This will attempt to connect the file descriptor @fd, to
+ * the graphics backend of @dom. If @dom has multiple graphics
+ * backends configured, then @idx will determine which one is
+ * opened, starting from @idx 0.
+ *
+ * To disable any authentication, pass the VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH
+ * constant for @flags.
+ *
+ * The caller should use an anonymous socketpair to open
+ * @fd before invocation.
+ *
+ * This method can only be used when connected to a local
+ * libvirt hypervisor, over a UNIX domain socket. Attempts
+ * to use this method over a TCP connection will always fail
+ *
+ * Returns 0 on success, -1 on failure
+ */
+int
+virDomainOpenGraphics(virDomainPtr dom,
+ unsigned int idx,
+ int fd,
+ unsigned int flags)
+{
+ struct stat sb;
+ VIR_DOMAIN_DEBUG(dom, "idx=%u, fd=%d, flags=%x",
+ idx, fd, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ virCheckNonNegativeArgGoto(fd, error);
+
+ if (fstat(fd, &sb) < 0) {
+ virReportSystemError(errno,
+ _("Unable to access file descriptor %d"), fd);
+ goto error;
+ }
+
+ if (!S_ISSOCK(sb.st_mode)) {
+ virReportInvalidArg(fd,
+ _("fd %d in %s must be a socket"),
+ fd, __FUNCTION__);
+ goto error;
+ }
+
+ virCheckReadOnlyGoto(dom->conn->flags, error);
+
+ if (!VIR_DRV_SUPPORTS_FEATURE(dom->conn->driver, dom->conn,
+ VIR_DRV_FEATURE_FD_PASSING)) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("fd passing is not supported by this connection"));
+ goto error;
+ }
+
+ if (dom->conn->driver->domainOpenGraphics) {
+ int ret;
+ ret = dom->conn->driver->domainOpenGraphics(dom, idx, fd, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainOpenGraphicsFD:
+ * @dom: pointer to domain object
+ * @idx: index of graphics config to open
+ * @flags: bitwise-OR of virDomainOpenGraphicsFlags
+ *
+ * This will create a socket pair connected to the graphics backend of @dom.
+ * One end of the socket will be returned on success, and the other end is
+ * handed to the hypervisor.
+ * If @dom has multiple graphics backends configured, then @idx will determine
+ * which one is opened, starting from @idx 0.
+ *
+ * To disable any authentication, pass the VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH
+ * constant for @flags.
+ *
+ * This method can only be used when connected to a local
+ * libvirt hypervisor, over a UNIX domain socket. Attempts
+ * to use this method over a TCP connection will always fail.
+ *
+ * Returns an fd on success, -1 on failure
+ */
+int
+virDomainOpenGraphicsFD(virDomainPtr dom,
+ unsigned int idx,
+ unsigned int flags)
+{
+ VIR_DOMAIN_DEBUG(dom, "idx=%u, flags=%x", idx, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+
+ virCheckReadOnlyGoto(dom->conn->flags, error);
+
+ if (!VIR_DRV_SUPPORTS_FEATURE(dom->conn->driver, dom->conn,
+ VIR_DRV_FEATURE_FD_PASSING)) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("fd passing is not supported by this connection"));
+ goto error;
+ }
+
+ if (dom->conn->driver->domainOpenGraphicsFD) {
+ int ret;
+ ret = dom->conn->driver->domainOpenGraphicsFD(dom, idx, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSetBlockIoTune:
+ * @dom: pointer to domain object
+ * @disk: path to the block device, or device shorthand
+ * @params: Pointer to blkio parameter objects
+ * @nparams: Number of blkio parameters (this value can be the same or
+ * less than the number of parameters supported)
+ * @flags: bitwise-OR of virDomainModificationImpact
+ *
+ * Change all or a subset of the per-device block IO tunables.
+ *
+ * The @disk parameter is either an unambiguous source name of the
+ * block device (the <source file='...'/> sub-element, such as
+ * "/path/to/image"), or the device target shorthand (the <target
+ * dev='...'/> sub-element, such as "xvda"). Valid names can be
found
+ * by calling virDomainGetXMLDesc() and inspecting elements
+ * within //domain/devices/disk.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainSetBlockIoTune(virDomainPtr dom,
+ const char *disk,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "disk=%s, params=%p, nparams=%d, flags=%x",
+ disk, params, nparams, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ conn = dom->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(disk, error);
+ virCheckPositiveArgGoto(nparams, error);
+ virCheckNonNullArgGoto(params, error);
+
+ if (virTypedParameterValidateSet(dom->conn, params, nparams) < 0)
+ goto error;
+
+ if (conn->driver->domainSetBlockIoTune) {
+ int ret;
+ ret = conn->driver->domainSetBlockIoTune(dom, disk, params, nparams,
flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetBlockIoTune:
+ * @dom: pointer to domain object
+ * @disk: path to the block device, or device shorthand
+ * @params: Pointer to blkio parameter object
+ * (return value, allocated by the caller)
+ * @nparams: Pointer to number of blkio parameters
+ * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
+ *
+ * Get all block IO tunable parameters for a given device. On input,
+ * @nparams gives the size of the @params array; on output, @nparams
+ * gives how many slots were filled with parameter information, which
+ * might be less but will not exceed the input value.
+ *
+ * As a special case, calling with @params as NULL and @nparams as 0
+ * on input will cause @nparams on output to contain the number of
+ * parameters supported by the hypervisor, either for the given @disk
+ * (note that block devices of different types might support different
+ * parameters), or if @disk is NULL, for all possible disks. The
+ * caller should then allocate @params array,
+ * i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
+ * again. See virDomainGetMemoryParameters() for more details.
+ *
+ * The @disk parameter is either an unambiguous source name of the
+ * block device (the <source file='...'/> sub-element, such as
+ * "/path/to/image"), or the device target shorthand (the <target
+ * dev='...'/> sub-element, such as "xvda"). Valid names can be
found
+ * by calling virDomainGetXMLDesc() and inspecting elements
+ * within //domain/devices/disk. This parameter cannot be NULL
+ * unless @nparams is 0 on input.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainGetBlockIoTune(virDomainPtr dom,
+ const char *disk,
+ virTypedParameterPtr params,
+ int *nparams,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "disk=%s, params=%p, nparams=%d, flags=%x",
+ NULLSTR(disk), params, (nparams) ? *nparams : -1, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+
+ virCheckNonNullArgGoto(nparams, error);
+ virCheckNonNegativeArgGoto(*nparams, error);
+ if (*nparams != 0) {
+ virCheckNonNullArgGoto(params, error);
+ virCheckNonNullArgGoto(disk, error);
+ }
+
+ if (VIR_DRV_SUPPORTS_FEATURE(dom->conn->driver, dom->conn,
+ VIR_DRV_FEATURE_TYPED_PARAM_STRING))
+ flags |= VIR_TYPED_PARAM_STRING_OKAY;
+
+ /* At most one of these two flags should be set. */
+ if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
+ (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
+ virReportInvalidArg(flags,
+ _("flags 'affect live' and 'affect
config' in %s "
+ "are mutually exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+ conn = dom->conn;
+
+ if (conn->driver->domainGetBlockIoTune) {
+ int ret;
+ ret = conn->driver->domainGetBlockIoTune(dom, disk, params, nparams,
flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetCPUStats:
+ * @domain: domain to query
+ * @params: array to populate on output
+ * @nparams: number of parameters per cpu
+ * @start_cpu: which cpu to start with, or -1 for summary
+ * @ncpus: how many cpus to query
+ * @flags: bitwise-OR of virTypedParameterFlags
+ *
+ * Get statistics relating to CPU usage attributable to a single
+ * domain (in contrast to the statistics returned by
+ * virNodeGetCPUStats() for all processes on the host). @dom
+ * must be running (an inactive domain has no attributable cpu
+ * usage). On input, @params must contain at least @nparams * @ncpus
+ * entries, allocated by the caller.
+ *
+ * If @start_cpu is -1, then @ncpus must be 1, and the returned
+ * results reflect the statistics attributable to the entire
+ * domain (such as user and system time for the process as a
+ * whole). Otherwise, @start_cpu represents which cpu to start
+ * with, and @ncpus represents how many consecutive processors to
+ * query, with statistics attributable per processor (such as
+ * per-cpu usage). If @ncpus is larger than the number of cpus
+ * available to query, then the trailing part of the array will
+ * be unpopulated.
+ *
+ * The remote driver imposes a limit of 128 @ncpus and 16 @nparams;
+ * the number of parameters per cpu should not exceed 16, but if you
+ * have a host with more than 128 CPUs, your program should split
+ * the request into multiple calls.
+ *
+ * As special cases, if @params is NULL and @nparams is 0 and
+ * @ncpus is 1, and the return value will be how many
+ * statistics are available for the given @start_cpu. This number
+ * may be different for @start_cpu of -1 than for any non-negative
+ * value, but will be the same for all non-negative @start_cpu.
+ * Likewise, if @params is NULL and @nparams is 0 and @ncpus is 0,
+ * the number of cpus available to query is returned. From the
+ * host perspective, this would typically match the cpus member
+ * of virNodeGetInfo(), but might be less due to host cpu hotplug.
+ *
+ * For now, @flags is unused, and the statistics all relate to the
+ * usage from the host perspective. It is possible that a future
+ * version will support a flag that queries the cpu usage from the
+ * guest's perspective, where the maximum cpu to query would be
+ * related to virDomainGetVcpusFlags() rather than virNodeGetInfo().
+ * An individual guest vcpu cannot be reliably mapped back to a
+ * specific host cpu unless a single-processor vcpu pinning was used,
+ * but when @start_cpu is -1, any difference in usage between a host
+ * and guest perspective would serve as a measure of hypervisor overhead.
+ *
+ * Typical use sequence is below.
+ *
+ * getting total stats: set start_cpu as -1, ncpus 1
+ * virDomainGetCPUStats(dom, NULL, 0, -1, 1, 0) => nparams
+ * params = calloc(nparams, sizeof(virTypedParameter))
+ * virDomainGetCPUStats(dom, params, nparams, -1, 1, 0) => total stats.
+ *
+ * getting per-cpu stats:
+ * virDomainGetCPUStats(dom, NULL, 0, 0, 0, 0) => ncpus
+ * virDomainGetCPUStats(dom, NULL, 0, 0, 1, 0) => nparams
+ * params = calloc(ncpus * nparams, sizeof(virTypedParameter))
+ * virDomainGetCPUStats(dom, params, nparams, 0, ncpus, 0) => per-cpu stats
+ *
+ * Returns -1 on failure, or the number of statistics that were
+ * populated per cpu on success (this will be less than the total
+ * number of populated @params, unless @ncpus was 1; and may be
+ * less than @nparams). The populated parameters start at each
+ * stride of @nparams, which means the results may be discontiguous;
+ * any unpopulated parameters will be zeroed on success (this includes
+ * skipped elements if @nparams is too large, and tail elements if
+ * @ncpus is too large). The caller is responsible for freeing any
+ * returned string parameters.
+ */
+int
+virDomainGetCPUStats(virDomainPtr domain,
+ virTypedParameterPtr params,
+ unsigned int nparams,
+ int start_cpu,
+ unsigned int ncpus,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain,
+ "params=%p, nparams=%d, start_cpu=%d, ncpus=%u,
flags=%x",
+ params, nparams, start_cpu, ncpus, flags);
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ /* Special cases:
+ * start_cpu must be non-negative, or else -1
+ * if start_cpu is -1, ncpus must be 1
+ * params == NULL must match nparams == 0
+ * ncpus must be non-zero unless params == NULL
+ * nparams * ncpus must not overflow (RPC may restrict it even more)
+ */
+ if (start_cpu == -1) {
+ if (ncpus != 1) {
+ virReportInvalidArg(start_cpu,
+ _("ncpus in %s must be 1 when start_cpu is
-1"),
+ __FUNCTION__);
+ goto error;
+ }
+ } else {
+ virCheckNonNegativeArgGoto(start_cpu, error);
+ }
+ if (nparams)
+ virCheckNonNullArgGoto(params, error);
+ else
+ virCheckNullArgGoto(params, error);
+ if (ncpus == 0)
+ virCheckNullArgGoto(params, error);
+
+ if (nparams && ncpus > UINT_MAX / nparams) {
+ virReportError(VIR_ERR_OVERFLOW, _("input too large: %u * %u"),
+ nparams, ncpus);
+ goto error;
+ }
+ if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_TYPED_PARAM_STRING))
+ flags |= VIR_TYPED_PARAM_STRING_OKAY;
+
+ if (conn->driver->domainGetCPUStats) {
+ int ret;
+
+ ret = conn->driver->domainGetCPUStats(domain, params, nparams,
+ start_cpu, ncpus, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetDiskErrors:
+ * @dom: a domain object
+ * @errors: array to populate on output
+ * @maxerrors: size of @errors array
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * The function populates @errors array with all disks that encountered an
+ * I/O error. Disks with no error will not be returned in the @errors array.
+ * Each disk is identified by its target (the dev attribute of target
+ * subelement in domain XML), such as "vda", and accompanied with the error
+ * that was seen on it. The caller is also responsible for calling free()
+ * on each disk name returned.
+ *
+ * In a special case when @errors is NULL and @maxerrors is 0, the function
+ * returns preferred size of @errors that the caller should use to get all
+ * disk errors.
+ *
+ * Since calling virDomainGetDiskErrors(dom, NULL, 0, 0) to get preferred size
+ * of @errors array and getting the errors are two separate operations, new
+ * disks may be hotplugged to the domain and new errors may be encountered
+ * between the two calls. Thus, this function may not return all disk errors
+ * because the supplied array is not large enough. Such errors may, however,
+ * be detected by listening to domain events.
+ *
+ * Returns number of disks with errors filled in the @errors array or -1 on
+ * error.
+ */
+int
+virDomainGetDiskErrors(virDomainPtr dom,
+ virDomainDiskErrorPtr errors,
+ unsigned int maxerrors,
+ unsigned int flags)
+{
+ VIR_DOMAIN_DEBUG(dom, "errors=%p, maxerrors=%u, flags=%x",
+ errors, maxerrors, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+
+ if (maxerrors)
+ virCheckNonNullArgGoto(errors, error);
+ else
+ virCheckNullArgGoto(errors, error);
+
+ if (dom->conn->driver->domainGetDiskErrors) {
+ int ret = dom->conn->driver->domainGetDiskErrors(dom, errors,
+ maxerrors, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+/**
+ * virDomainGetHostname:
+ * @domain: a domain object
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Get the hostname for that domain.
+ *
+ * Dependent on hypervisor used, this may require a guest agent to be
+ * available.
+ *
+ * Returns the hostname which must be freed by the caller, or
+ * NULL if there was an error.
+ */
+char *
+virDomainGetHostname(virDomainPtr domain, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, NULL);
+ conn = domain->conn;
+
+ if (conn->driver->domainGetHostname) {
+ char *ret;
+ ret = conn->driver->domainGetHostname(domain, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainFSTrim:
+ * @dom: a domain object
+ * @mountPoint: which mount point to trim
+ * @minimum: Minimum contiguous free range to discard in bytes
+ * @flags: extra flags, not used yet, so callers should always pass 0
+ *
+ * Calls FITRIM within the guest (hence guest agent may be
+ * required depending on hypervisor used). Either call it on each
+ * mounted filesystem (@mountPoint is NULL) or just on specified
+ * @mountPoint. @minimum hints that free ranges smaller than this
+ * may be ignored (this is a hint and the guest may not respect
+ * it). By increasing this value, the fstrim operation will
+ * complete more quickly for filesystems with badly fragmented
+ * free space, although not all blocks will be discarded.
+ * If @minimum is not zero, the command may fail.
+ *
+ * Returns 0 on success, -1 otherwise.
+ */
+int
+virDomainFSTrim(virDomainPtr dom,
+ const char *mountPoint,
+ unsigned long long minimum,
+ unsigned int flags)
+{
+ VIR_DOMAIN_DEBUG(dom, "mountPoint=%s, minimum=%llu, flags=%x",
+ mountPoint, minimum, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ virCheckReadOnlyGoto(dom->conn->flags, error);
+
+ if (dom->conn->driver->domainFSTrim) {
+ int ret = dom->conn->driver->domainFSTrim(dom, mountPoint,
+ minimum, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+/**
+ * virDomainFSFreeze:
+ * @dom: a domain object
+ * @mountpoints: list of mount points to be frozen
+ * @nmountpoints: the number of mount points specified in @mountpoints
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Freeze specified filesystems within the guest (hence guest agent
+ * may be required depending on hypervisor used). If @mountpoints is NULL and
+ * @nmountpoints is 0, every mounted filesystem on the guest is frozen.
+ * In some environments (e.g. QEMU guest with guest agent which doesn't
+ * support mountpoints argument), @mountpoints may need to be NULL.
+ *
+ * Returns the number of frozen filesystems on success, -1 otherwise.
+ */
+int
+virDomainFSFreeze(virDomainPtr dom,
+ const char **mountpoints,
+ unsigned int nmountpoints,
+ unsigned int flags)
+{
+ VIR_DOMAIN_DEBUG(dom, "mountpoints=%p, nmountpoints=%d, flags=%x",
+ mountpoints, nmountpoints, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ virCheckReadOnlyGoto(dom->conn->flags, error);
+ if (nmountpoints)
+ virCheckNonNullArgGoto(mountpoints, error);
+ else
+ virCheckNullArgGoto(mountpoints, error);
+
+ if (dom->conn->driver->domainFSFreeze) {
+ int ret = dom->conn->driver->domainFSFreeze(
+ dom, mountpoints, nmountpoints, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+/**
+ * virDomainFSThaw:
+ * @dom: a domain object
+ * @mountpoints: list of mount points to be thawed
+ * @nmountpoints: the number of mount points specified in @mountpoints
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Thaw specified filesystems within the guest. If @mountpoints is NULL and
+ * @nmountpoints is 0, every mounted filesystem on the guest is thawed.
+ * In some drivers (e.g. QEMU driver), @mountpoints may need to be NULL.
+ *
+ * Returns the number of thawed filesystems on success, -1 otherwise.
+ */
+int
+virDomainFSThaw(virDomainPtr dom,
+ const char **mountpoints,
+ unsigned int nmountpoints,
+ unsigned int flags)
+{
+ VIR_DOMAIN_DEBUG(dom, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ virCheckReadOnlyGoto(dom->conn->flags, error);
+ if (nmountpoints)
+ virCheckNonNullArgGoto(mountpoints, error);
+ else
+ virCheckNullArgGoto(mountpoints, error);
+
+ if (dom->conn->driver->domainFSThaw) {
+ int ret = dom->conn->driver->domainFSThaw(
+ dom, mountpoints, nmountpoints, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+/**
+ * virDomainGetTime:
+ * @dom: a domain object
+ * @seconds: domain's time in seconds
+ * @nseconds: the nanoscond part of @seconds
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Extract information about guest time and store it into
+ * @seconds and @nseconds. The @seconds represents the number of
+ * seconds since the UNIX Epoch of 1970-01-01 00:00:00 in UTC.
+ *
+ * Please note that some hypervisors may require guest agent to
+ * be configured and running in order to run this API.
+ *
+ * Returns 0 on success, -1 otherwise.
+ */
+int
+virDomainGetTime(virDomainPtr dom,
+ long long *seconds,
+ unsigned int *nseconds,
+ unsigned int flags)
+{
+ VIR_DOMAIN_DEBUG(dom, "seconds=%p, nseconds=%p, flags=%x",
+ seconds, nseconds, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+
+ if (dom->conn->driver->domainGetTime) {
+ int ret = dom->conn->driver->domainGetTime(dom, seconds,
+ nseconds, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+/**
+ * virDomainSetTime:
+ * @dom: a domain object
+ * @seconds: time to set
+ * @nseconds: the nanosecond part of @seconds
+ * @flags: bitwise-OR of virDomainSetTimeFlags
+ *
+ * When a domain is suspended or restored from a file the
+ * domain's OS has no idea that there was a big gap in the time.
+ * Depending on how long the gap was, NTP might not be able to
+ * resynchronize the guest.
+ *
+ * This API tries to set guest time to the given value. The time
+ * to set (@seconds and @nseconds) should be in seconds relative
+ * to the Epoch of 1970-01-01 00:00:00 in UTC.
+ *
+ * Please note that some hypervisors may require guest agent to
+ * be configured and running in order to be able to run this API.
+ *
+ * Returns 0 on success, -1 otherwise.
+ */
+int
+virDomainSetTime(virDomainPtr dom,
+ long long seconds,
+ unsigned int nseconds,
+ unsigned int flags)
+{
+ VIR_DOMAIN_DEBUG(dom, "seconds=%lld, nseconds=%u, flags=%x",
+ seconds, nseconds, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(dom, -1);
+ virCheckReadOnlyGoto(dom->conn->flags, error);
+
+ if (dom->conn->driver->domainSetTime) {
+ int ret = dom->conn->driver->domainSetTime(dom, seconds,
+ nseconds, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(dom->conn);
+ return -1;
+}
+
+
+
+/**
+ * virConnectGetDomainCapabilities:
+ * @conn: pointer to the hypervisor connection
+ * @emulatorbin: path to emulator
+ * @arch: domain architecture
+ * @machine: machine type
+ * @virttype: virtualization type
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Prior creating a domain (for instance via virDomainCreateXML
+ * or virDomainDefineXML) it may be suitable to know what the
+ * underlying emulator and/or libvirt is capable of. For
+ * instance, if host, libvirt and qemu is capable of VFIO
+ * passthrough and so on.
+ *
+ * Returns NULL in case of error or an XML string
+ * defining the capabilities.
+ */
+char *
+virConnectGetDomainCapabilities(virConnectPtr conn,
+ const char *emulatorbin,
+ const char *arch,
+ const char *machine,
+ const char *virttype,
+ unsigned int flags)
+{
+ VIR_DEBUG("conn=%p, emulatorbin=%s, arch=%s, "
+ "machine=%s, virttype=%s, flags=%x",
+ conn, NULLSTR(emulatorbin), NULLSTR(arch),
+ NULLSTR(machine), NULLSTR(virttype), flags);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, NULL);
+
+ if (conn->driver->connectGetDomainCapabilities) {
+ char *ret;
+ ret = conn->driver->connectGetDomainCapabilities(conn, emulatorbin,
+ arch, machine,
+ virttype, flags);
+ if (!ret)
+ goto error;
+ VIR_DEBUG("conn=%p, ret=%s", conn, ret);
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/**
+ * virConnectGetAllDomainStats:
+ * @conn: pointer to the hypervisor connection
+ * @stats: stats to return, binary-OR of virDomainStatsTypes
+ * @retStats: Pointer that will be filled with the array of returned stats
+ * @flags: extra flags; binary-OR of virConnectGetAllDomainStatsFlags
+ *
+ * Query statistics for all domains on a given connection.
+ *
+ * Report statistics of various parameters for a running VM according to @stats
+ * field. The statistics are returned as an array of structures for each queried
+ * domain. The structure contains an array of typed parameters containing the
+ * individual statistics. The typed parameter name for each statistic field
+ * consists of a dot-separated string containing name of the requested group
+ * followed by a group specific description of the statistic value.
+ *
+ * The statistic groups are enabled using the @stats parameter which is a
+ * binary-OR of enum virDomainStatsTypes. The following groups are available
+ * (although not necessarily implemented for each hypervisor):
+ *
+ * VIR_DOMAIN_STATS_STATE: Return domain state and reason for entering that
+ * state. The typed parameter keys are in this format:
+ * "state.state" - state of the VM, returned as int from virDomainState enum
+ * "state.reason" - reason for entering given state, returned as int from
+ * virDomain*Reason enum corresponding to given state.
+ *
+ * VIR_DOMAIN_STATS_CPU_TOTAL: Return CPU statistics and usage information.
+ * The typed parameter keys are in this format:
+ * "cpu.time" - total cpu time spent for this domain in nanoseconds
+ * as unsigned long long.
+ * "cpu.user" - user cpu time spent in nanoseconds as unsigned long long.
+ * "cpu.system" - system cpu time spent in nanoseconds as unsigned long long.
+ *
+ * VIR_DOMAIN_STATS_BALLOON: Return memory balloon device information.
+ * The typed parameter keys are in this format:
+ * "balloon.current" - the memory in kiB currently used
+ * as unsigned long long.
+ * "balloon.maximum" - the maximum memory in kiB allowed
+ * as unsigned long long.
+ *
+ * VIR_DOMAIN_STATS_VCPU: Return virtual CPU statistics.
+ * Due to VCPU hotplug, the vcpu.<num>.* array could be sparse.
+ * The actual size of the array corresponds to "vcpu.current".
+ * The array size will never exceed "vcpu.maximum".
+ * The typed parameter keys are in this format:
+ * "vcpu.current" - current number of online virtual CPUs as unsigned int.
+ * "vcpu.maximum" - maximum number of online virtual CPUs as unsigned int.
+ * "vcpu.<num>.state" - state of the virtual CPU <num>, as int
+ * from virVcpuState enum.
+ * "vcpu.<num>.time" - virtual cpu time spent by virtual CPU <num>
+ * as unsigned long long.
+ *
+ * VIR_DOMAIN_STATS_INTERFACE: Return network interface statistics.
+ * The typed parameter keys are in this format:
+ * "net.count" - number of network interfaces on this domain
+ * as unsigned int.
+ * "net.<num>.name" - name of the interface <num> as string.
+ * "net.<num>.rx.bytes" - bytes received as unsigned long long.
+ * "net.<num>.rx.pkts" - packets received as unsigned long long.
+ * "net.<num>.rx.errs" - receive errors as unsigned long long.
+ * "net.<num>.rx.drop" - receive packets dropped as unsigned long long.
+ * "net.<num>.tx.bytes" - bytes transmitted as unsigned long long.
+ * "net.<num>.tx.pkts" - packets transmitted as unsigned long long.
+ * "net.<num>.tx.errs" - transmission errors as unsigned long long.
+ * "net.<num>.tx.drop" - transmit packets dropped as unsigned long long.
+ *
+ * VIR_DOMAIN_STATS_BLOCK: Return block devices statistics.
+ * The typed parameter keys are in this format:
+ * "block.count" - number of block devices on this domain
+ * as unsigned int.
+ * "block.<num>.name" - name of the block device <num> as string.
+ * matches the target name (vda/sda/hda) of the
+ * block device.
+ * "block.<num>.rd.reqs" - number of read requests as unsigned long
long.
+ * "block.<num>.rd.bytes" - number of read bytes as unsigned long long.
+ * "block.<num>.rd.times" - total time (ns) spent on reads as
+ * unsigned long long.
+ * "block.<num>.wr.reqs" - number of write requests as unsigned long
long.
+ * "block.<num>.wr.bytes" - number of written bytes as unsigned long
long.
+ * "block.<num>.wr.times" - total time (ns) spent on writes as
+ * unsigned long long.
+ * "block.<num>.fl.reqs" - total flush requests as unsigned long long.
+ * "block.<num>.fl.times" - total time (ns) spent on cache flushing as
+ * unsigned long long.
+ * "block.<num>.errors" - Xen only: the 'oo_req' value as
+ * unsigned long long.
+ * "block.<num>.allocation" - offset of the highest written sector
+ * as unsigned long long.
+ * "block.<num>.capacity" - logical size in bytes of the block device
backing
+ * image as unsigned long long.
+ * "block.<num>.physical" - physical size in bytes of the container of
the
+ * backing image as unsigned long long.
+ *
+ * Note that entire stats groups or individual stat fields may be missing from
+ * the output in case they are not supported by the given hypervisor, are not
+ * applicable for the current state of the guest domain, or their retrieval
+ * was not successful.
+ *
+ * Using 0 for @stats returns all stats groups supported by the given
+ * hypervisor.
+ *
+ * Specifying VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS as @flags makes
+ * the function return error in case some of the stat types in @stats were
+ * not recognized by the daemon.
+ *
+ * Similarly to virConnectListAllDomains, @flags can contain various flags to
+ * filter the list of domains to provide stats for.
+ *
+ * VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE selects online domains while
+ * VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE selects offline ones.
+ *
+ * VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT and
+ * VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT allow to filter the list
+ * according to their persistence.
+ *
+ * To filter the list of VMs by domain state @flags can contain
+ * VIR_CONNECT_GET_ALL_DOMAINS_STATS_RUNNING,
+ * VIR_CONNECT_GET_ALL_DOMAINS_STATS_PAUSED,
+ * VIR_CONNECT_GET_ALL_DOMAINS_STATS_SHUTOFF and/or
+ * VIR_CONNECT_GET_ALL_DOMAINS_STATS_OTHER for all other states.
+ *
+ * Returns the count of returned statistics structures on success, -1 on error.
+ * The requested data are returned in the @retStats parameter. The returned
+ * array should be freed by the caller. See virDomainStatsRecordListFree.
+ */
+int
+virConnectGetAllDomainStats(virConnectPtr conn,
+ unsigned int stats,
+ virDomainStatsRecordPtr **retStats,
+ unsigned int flags)
+{
+ int ret = -1;
+
+ VIR_DEBUG("conn=%p, stats=0x%x, retStats=%p, flags=0x%x",
+ conn, stats, retStats, flags);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+ virCheckNonNullArgGoto(retStats, cleanup);
+
+ if (!conn->driver->connectGetAllDomainStats) {
+ virReportUnsupportedError();
+ goto cleanup;
+ }
+
+ ret = conn->driver->connectGetAllDomainStats(conn, NULL, 0, stats,
+ retStats, flags);
+
+ cleanup:
+ if (ret < 0)
+ virDispatchError(conn);
+
+ return ret;
+}
+
+
+/**
+ * virDomainListGetStats:
+ * @doms: NULL terminated array of domains
+ * @stats: stats to return, binary-OR of virDomainStatsTypes
+ * @retStats: Pointer that will be filled with the array of returned stats
+ * @flags: extra flags; binary-OR of virConnectGetAllDomainStatsFlags
+ *
+ * Query statistics for domains provided by @doms. Note that all domains in
+ * @doms must share the same connection.
+ *
+ * Report statistics of various parameters for a running VM according to @stats
+ * field. The statistics are returned as an array of structures for each queried
+ * domain. The structure contains an array of typed parameters containing the
+ * individual statistics. The typed parameter name for each statistic field
+ * consists of a dot-separated string containing name of the requested group
+ * followed by a group specific description of the statistic value.
+ *
+ * The statistic groups are enabled using the @stats parameter which is a
+ * binary-OR of enum virDomainStatsTypes. The stats groups are documented
+ * in virConnectGetAllDomainStats.
+ *
+ * Using 0 for @stats returns all stats groups supported by the given
+ * hypervisor.
+ *
+ * Specifying VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS as @flags makes
+ * the function return error in case some of the stat types in @stats were
+ * not recognized by the daemon.
+ *
+ * Note that any of the domain list filtering flags in @flags will be rejected
+ * by this function.
+ *
+ * Returns the count of returned statistics structures on success, -1 on error.
+ * The requested data are returned in the @retStats parameter. The returned
+ * array should be freed by the caller. See virDomainStatsRecordListFree.
+ * Note that the count of returned stats may be less than the domain count
+ * provided via @doms.
+ */
+int
+virDomainListGetStats(virDomainPtr *doms,
+ unsigned int stats,
+ virDomainStatsRecordPtr **retStats,
+ unsigned int flags)
+{
+ virConnectPtr conn = NULL;
+ virDomainPtr *nextdom = doms;
+ unsigned int ndoms = 0;
+ int ret = -1;
+
+ VIR_DEBUG("doms=%p, stats=0x%x, retStats=%p, flags=0x%x",
+ doms, stats, retStats, flags);
+
+ virResetLastError();
+
+ virCheckNonNullArgGoto(doms, cleanup);
+ virCheckNonNullArgGoto(retStats, cleanup);
+
+ if (!*doms) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("doms array in %s must contain at least one domain"),
+ __FUNCTION__);
+ goto cleanup;
+ }
+
+ conn = doms[0]->conn;
+ virCheckConnectReturn(conn, -1);
+
+ if (!conn->driver->connectGetAllDomainStats) {
+ virReportUnsupportedError();
+ goto cleanup;
+ }
+
+ while (*nextdom) {
+ virDomainPtr dom = *nextdom;
+
+ virCheckDomainGoto(dom, cleanup);
+
+ if (dom->conn != conn) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("domains in 'doms' array must belong to a
"
+ "single connection in %s"), __FUNCTION__);
+ goto cleanup;
+ }
+
+ ndoms++;
+ nextdom++;
+ }
+
+ ret = conn->driver->connectGetAllDomainStats(conn, doms, ndoms,
+ stats, retStats, flags);
+
+ cleanup:
+ if (ret < 0)
+ virDispatchError(conn);
+ return ret;
+}
+
+
+/**
+ * virDomainStatsRecordListFree:
+ * @stats: NULL terminated array of virDomainStatsRecords to free
+ *
+ * Convenience function to free a list of domain stats returned by
+ * virDomainListGetStats and virConnectGetAllDomainStats.
+ */
+void
+virDomainStatsRecordListFree(virDomainStatsRecordPtr *stats)
+{
+ virDomainStatsRecordPtr *next;
+
+ if (!stats)
+ return;
+
+ for (next = stats; *next; next++) {
+ virTypedParamsFree((*next)->params, (*next)->nparams);
+ virDomainFree((*next)->dom);
+ VIR_FREE(*next);
+ }
+
+ VIR_FREE(stats);
+}
diff --git a/src/libvirt.c b/src/libvirt.c
index 6fa360b..ceee342 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -52,7 +52,6 @@
#include "viruuid.h"
#include "viralloc.h"
#include "configmake.h"
-#include "intprops.h"
#include "virconf.h"
#if WITH_GNUTLS
# if WITH_GNUTLS_GCRYPT
@@ -1500,6 +1499,48 @@ virConnectSupportsFeature(virConnectPtr conn, int feature)
}
+/* Helper function called to validate incoming client array on any
+ * interface that sets typed parameters in the hypervisor. */
+int
+virTypedParameterValidateSet(virConnectPtr conn,
+ virTypedParameterPtr params,
+ int nparams)
+{
+ bool string_okay;
+ size_t i;
+
+ string_okay = VIR_DRV_SUPPORTS_FEATURE(conn->driver,
+ conn,
+ VIR_DRV_FEATURE_TYPED_PARAM_STRING);
+ for (i = 0; i < nparams; i++) {
+ if (strnlen(params[i].field, VIR_TYPED_PARAM_FIELD_LENGTH) ==
+ VIR_TYPED_PARAM_FIELD_LENGTH) {
+ virReportInvalidArg(params,
+ _("string parameter name '%.*s' too
long"),
+ VIR_TYPED_PARAM_FIELD_LENGTH,
+ params[i].field);
+ return -1;
+ }
+ if (params[i].type == VIR_TYPED_PARAM_STRING) {
+ if (string_okay) {
+ if (!params[i].value.s) {
+ virReportInvalidArg(params,
+ _("NULL string parameter
'%s'"),
+ params[i].field);
+ return -1;
+ }
+ } else {
+ virReportInvalidArg(params,
+ _("string parameter '%s'
unsupported"),
+ params[i].field);
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+
/**
* virConnectGetType:
* @conn: pointer to the hypervisor connection
@@ -1755,41 +1796,34 @@ virConnectGetMaxVcpus(virConnectPtr conn,
/**
- * virConnectListDomains:
+ * virNodeGetInfo:
* @conn: pointer to the hypervisor connection
- * @ids: array to collect the list of IDs of active domains
- * @maxids: size of @ids
- *
- * Collect the list of active domains, and store their IDs in array @ids
+ * @info: pointer to a virNodeInfo structure allocated by the user
*
- * For inactive domains, see virConnectListDefinedDomains(). For more
- * control over the results, see virConnectListAllDomains().
+ * Extract hardware information about the node.
*
- * Returns the number of domains found or -1 in case of error. Note that
- * this command is inherently racy; a domain can be started between a
- * call to virConnectNumOfDomains() and this call; you are only guaranteed
- * that all currently active domains were listed if the return is less
- * than @maxids.
+ * Returns 0 in case of success and -1 in case of failure.
*/
int
-virConnectListDomains(virConnectPtr conn, int *ids, int maxids)
+virNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
{
- VIR_DEBUG("conn=%p, ids=%p, maxids=%d", conn, ids, maxids);
+ VIR_DEBUG("conn=%p, info=%p", conn, info);
virResetLastError();
virCheckConnectReturn(conn, -1);
- virCheckNonNullArgGoto(ids, error);
- virCheckNonNegativeArgGoto(maxids, error);
+ virCheckNonNullArgGoto(info, error);
- if (conn->driver->connectListDomains) {
- int ret = conn->driver->connectListDomains(conn, ids, maxids);
+ if (conn->driver->nodeGetInfo) {
+ int ret;
+ ret = conn->driver->nodeGetInfo(conn, info);
if (ret < 0)
goto error;
return ret;
}
virReportUnsupportedError();
+
error:
virDispatchError(conn);
return -1;
@@ -1797,238 +1831,294 @@ virConnectListDomains(virConnectPtr conn, int *ids, int maxids)
/**
- * virConnectNumOfDomains:
+ * virConnectGetCapabilities:
* @conn: pointer to the hypervisor connection
*
- * Provides the number of active domains.
+ * Provides capabilities of the hypervisor / driver.
*
- * Returns the number of domain found or -1 in case of error
+ * Returns NULL in case of error, or an XML string
+ * defining the capabilities.
+ * The client must free the returned string after use.
*/
-int
-virConnectNumOfDomains(virConnectPtr conn)
+char *
+virConnectGetCapabilities(virConnectPtr conn)
{
VIR_DEBUG("conn=%p", conn);
virResetLastError();
- virCheckConnectReturn(conn, -1);
+ virCheckConnectReturn(conn, NULL);
- if (conn->driver->connectNumOfDomains) {
- int ret = conn->driver->connectNumOfDomains(conn);
- if (ret < 0)
+ if (conn->driver->connectGetCapabilities) {
+ char *ret;
+ ret = conn->driver->connectGetCapabilities(conn);
+ if (!ret)
goto error;
+ VIR_DEBUG("conn=%p ret=%s", conn, ret);
return ret;
}
virReportUnsupportedError();
+
error:
virDispatchError(conn);
- return -1;
+ return NULL;
}
/**
- * virDomainGetConnect:
- * @dom: pointer to a domain
+ * virNodeGetCPUStats:
+ * @conn: pointer to the hypervisor connection.
+ * @cpuNum: number of node cpu. (VIR_NODE_CPU_STATS_ALL_CPUS means total cpu
+ * statistics)
+ * @params: pointer to node cpu time parameter objects
+ * @nparams: number of node cpu time parameter (this value should be same or
+ * less than the number of parameters supported)
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * This function provides individual cpu statistics of the node.
+ * If you want to get total cpu statistics of the node, you must specify
+ * VIR_NODE_CPU_STATS_ALL_CPUS to @cpuNum.
+ * The @params array will be filled with the values equal to the number of
+ * parameters suggested by @nparams
+ *
+ * As the value of @nparams is dynamic, call the API setting @nparams to 0 and
+ * @params as NULL, the API returns the number of parameters supported by the
+ * HV by updating @nparams on SUCCESS. The caller should then allocate @params
+ * array, i.e. (sizeof(@virNodeCPUStats) * @nparams) bytes and call
+ * the API again.
+ *
+ * Here is a sample code snippet:
+ *
+ * if (virNodeGetCPUStats(conn, cpuNum, NULL, &nparams, 0) == 0 &&
+ * nparams != 0) {
+ * if ((params = malloc(sizeof(virNodeCPUStats) * nparams)) == NULL)
+ * goto error;
+ * memset(params, 0, sizeof(virNodeCPUStats) * nparams);
+ * if (virNodeGetCPUStats(conn, cpuNum, params, &nparams, 0))
+ * goto error;
+ * }
*
- * Provides the connection pointer associated with a domain. The
- * reference counter on the connection is not increased by this
- * call.
+ * This function doesn't require privileged access to the hypervisor.
+ * This function expects the caller to allocate the @params.
+ *
+ * CPU time Statistics:
*
- * WARNING: When writing libvirt bindings in other languages, do
- * not use this function. Instead, store the connection and
- * the domain object together.
+ * VIR_NODE_CPU_STATS_KERNEL:
+ * The cumulative CPU time which spends by kernel,
+ * when the node booting up.(nanoseconds)
+ * VIR_NODE_CPU_STATS_USER:
+ * The cumulative CPU time which spends by user processes,
+ * when the node booting up.(nanoseconds)
+ * VIR_NODE_CPU_STATS_IDLE:
+ * The cumulative idle CPU time, when the node booting up.(nanoseconds)
+ * VIR_NODE_CPU_STATS_IOWAIT:
+ * The cumulative I/O wait CPU time, when the node booting up.(nanoseconds)
+ * VIR_NODE_CPU_STATS_UTILIZATION:
+ * The CPU utilization. The usage value is in percent and 100%
+ * represents all CPUs on the server.
*
- * Returns the virConnectPtr or NULL in case of failure.
+ * Returns -1 in case of error, 0 in case of success.
*/
-virConnectPtr
-virDomainGetConnect(virDomainPtr dom)
+int
+virNodeGetCPUStats(virConnectPtr conn,
+ int cpuNum,
+ virNodeCPUStatsPtr params,
+ int *nparams, unsigned int flags)
{
- VIR_DOMAIN_DEBUG(dom);
+ VIR_DEBUG("conn=%p, cpuNum=%d, params=%p, nparams=%d, flags=%x",
+ conn, cpuNum, params, nparams ? *nparams : -1, flags);
virResetLastError();
- virCheckDomainReturn(dom, NULL);
+ virCheckConnectReturn(conn, -1);
+ virCheckNonNullArgGoto(nparams, error);
+ virCheckNonNegativeArgGoto(*nparams, error);
+ if (cpuNum < 0 && cpuNum != VIR_NODE_CPU_STATS_ALL_CPUS) {
+ virReportInvalidArg(cpuNum,
+ _("cpuNum in %s only accepts %d as a negative "
+ "value"),
+ __FUNCTION__, VIR_NODE_CPU_STATS_ALL_CPUS);
+ goto error;
+ }
+
+ if (conn->driver->nodeGetCPUStats) {
+ int ret;
+ ret = conn->driver->nodeGetCPUStats(conn, cpuNum, params, nparams, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+ virReportUnsupportedError();
- return dom->conn;
+ error:
+ virDispatchError(conn);
+ return -1;
}
/**
- * virDomainCreateXML:
- * @conn: pointer to the hypervisor connection
- * @xmlDesc: string containing an XML description of the domain
- * @flags: bitwise-OR of supported virDomainCreateFlags
+ * virNodeGetMemoryStats:
+ * @conn: pointer to the hypervisor connection.
+ * @cellNum: number of node cell. (VIR_NODE_MEMORY_STATS_ALL_CELLS means total
+ * cell statistics)
+ * @params: pointer to node memory stats objects
+ * @nparams: number of node memory stats (this value should be same or
+ * less than the number of stats supported)
+ * @flags: extra flags; not used yet, so callers should always pass 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).
+ * This function provides memory stats of the node.
+ * If you want to get total memory statistics of the node, you must specify
+ * VIR_NODE_MEMORY_STATS_ALL_CELLS to @cellNum.
+ * The @params array will be filled with the values equal to the number of
+ * stats suggested by @nparams
+ *
+ * As the value of @nparams is dynamic, call the API setting @nparams to 0 and
+ * @params as NULL, the API returns the number of parameters supported by the
+ * HV by updating @nparams on SUCCESS. The caller should then allocate @params
+ * array, i.e. (sizeof(@virNodeMemoryStats) * @nparams) bytes and call
+ * the API again.
+ *
+ * Here is the sample code snippet:
+ *
+ * if (virNodeGetMemoryStats(conn, cellNum, NULL, &nparams, 0) == 0 &&
+ * nparams != 0) {
+ * if ((params = malloc(sizeof(virNodeMemoryStats) * nparams)) == NULL)
+ * goto error;
+ * memset(params, cellNum, 0, sizeof(virNodeMemoryStats) * nparams);
+ * if (virNodeGetMemoryStats(conn, params, &nparams, 0))
+ * goto error;
+ * }
*
- * 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.
+ * This function doesn't require privileged access to the hypervisor.
+ * This function expects the caller to allocate the @params.
*
- * 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.
+ * Memory Stats:
*
- * virDomainFree should be used to free the resources after the
- * domain object is no longer needed.
+ * VIR_NODE_MEMORY_STATS_TOTAL:
+ * The total memory usage.(KB)
+ * VIR_NODE_MEMORY_STATS_FREE:
+ * The free memory usage.(KB)
+ * On linux, this usage includes buffers and cached.
+ * VIR_NODE_MEMORY_STATS_BUFFERS:
+ * The buffers memory usage.(KB)
+ * VIR_NODE_MEMORY_STATS_CACHED:
+ * The cached memory usage.(KB)
*
- * Returns a new domain object or NULL in case of failure
+ * Returns -1 in case of error, 0 in case of success.
*/
-virDomainPtr
-virDomainCreateXML(virConnectPtr conn, const char *xmlDesc,
- unsigned int flags)
+int
+virNodeGetMemoryStats(virConnectPtr conn,
+ int cellNum,
+ virNodeMemoryStatsPtr params,
+ int *nparams, unsigned int flags)
{
- VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, xmlDesc, flags);
+ VIR_DEBUG("conn=%p, cellNum=%d, params=%p, nparams=%d, flags=%x",
+ conn, cellNum, params, nparams ? *nparams : -1, flags);
virResetLastError();
- virCheckConnectReturn(conn, NULL);
- virCheckNonNullArgGoto(xmlDesc, error);
- virCheckReadOnlyGoto(conn->flags, error);
+ virCheckConnectReturn(conn, -1);
+ virCheckNonNullArgGoto(nparams, error);
+ virCheckNonNegativeArgGoto(*nparams, error);
+ if (cellNum < 0 && cellNum != VIR_NODE_MEMORY_STATS_ALL_CELLS) {
+ virReportInvalidArg(cpuNum,
+ _("cellNum in %s only accepts %d as a negative "
+ "value"),
+ __FUNCTION__, VIR_NODE_MEMORY_STATS_ALL_CELLS);
+ goto error;
+ }
- if (conn->driver->domainCreateXML) {
- virDomainPtr ret;
- ret = conn->driver->domainCreateXML(conn, xmlDesc, flags);
- if (!ret)
+ if (conn->driver->nodeGetMemoryStats) {
+ int ret;
+ ret = conn->driver->nodeGetMemoryStats(conn, cellNum, params, nparams,
flags);
+ if (ret < 0)
goto error;
return ret;
}
-
virReportUnsupportedError();
+
error:
virDispatchError(conn);
- return NULL;
+ return -1;
}
/**
- * virDomainCreateXMLWithFiles:
+ * virNodeGetFreeMemory:
* @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.
- *
- * virDomainFree should be used to free the resources after the
- * domain object is no longer needed.
- *
- * Returns a new domain object or NULL in case of failure
+ * provides the free memory available on the Node
+ * Note: most libvirt APIs provide memory sizes in kibibytes, but in this
+ * function the returned value is in bytes. Divide by 1024 as necessary.
+ *
+ * Returns the available free memory in bytes or 0 in case of error
*/
-virDomainPtr
-virDomainCreateXMLWithFiles(virConnectPtr conn, const char *xmlDesc,
- unsigned int nfiles,
- int *files,
- unsigned int flags)
+unsigned long long
+virNodeGetFreeMemory(virConnectPtr conn)
{
- VIR_DEBUG("conn=%p, xmlDesc=%s, nfiles=%u, files=%p, flags=%x",
- conn, xmlDesc, nfiles, files, flags);
+ VIR_DEBUG("conn=%p", conn);
virResetLastError();
- virCheckConnectReturn(conn, NULL);
- virCheckNonNullArgGoto(xmlDesc, error);
- virCheckReadOnlyGoto(conn->flags, error);
+ virCheckConnectReturn(conn, 0);
- if (conn->driver->domainCreateXMLWithFiles) {
- virDomainPtr ret;
- ret = conn->driver->domainCreateXMLWithFiles(conn, xmlDesc,
- nfiles, files,
- flags);
- if (!ret)
+ if (conn->driver->nodeGetFreeMemory) {
+ unsigned long long ret;
+ ret = conn->driver->nodeGetFreeMemory(conn);
+ if (ret == 0)
goto error;
return ret;
}
virReportUnsupportedError();
+
error:
virDispatchError(conn);
- return NULL;
+ return 0;
}
/**
- * virDomainCreateLinux:
+ * virNodeSuspendForDuration:
* @conn: pointer to the hypervisor connection
- * @xmlDesc: string containing an XML description of the domain
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Deprecated after 0.4.6.
- * Renamed to virDomainCreateXML() providing identical functionality.
- * This existing name will left indefinitely for API compatibility.
- *
- * Returns a new domain object or NULL in case of failure
- */
-virDomainPtr
-virDomainCreateLinux(virConnectPtr conn, const char *xmlDesc,
- unsigned int flags)
-{
- return virDomainCreateXML(conn, xmlDesc, flags);
-}
-
-
-/**
- * virDomainLookupByID:
- * @conn: pointer to the hypervisor connection
- * @id: the domain ID number
- *
- * Try to find a domain based on the hypervisor ID number
- * Note that this won't work for inactive domains which have an ID of -1,
- * in that case a lookup based on the Name or UUId need to be done instead.
+ * @target: the state to which the host must be suspended to,
+ * such as: VIR_NODE_SUSPEND_TARGET_MEM (Suspend-to-RAM)
+ * VIR_NODE_SUSPEND_TARGET_DISK (Suspend-to-Disk)
+ * VIR_NODE_SUSPEND_TARGET_HYBRID (Hybrid-Suspend,
+ * which is a combination of the former modes).
+ * @duration: the time duration in seconds for which the host
+ * has to be suspended
+ * @flags: extra flags; not used yet, so callers should always pass 0
*
- * virDomainFree should be used to free the resources after the
- * domain object is no longer needed.
+ * Attempt to suspend the node (host machine) for the given duration of
+ * time in the specified state (Suspend-to-RAM, Suspend-to-Disk or
+ * Hybrid-Suspend). Schedule the node's Real-Time-Clock interrupt to
+ * resume the node after the duration is complete.
*
- * Returns a new domain object or NULL in case of failure. If the
- * domain cannot be found, then VIR_ERR_NO_DOMAIN error is raised.
+ * Returns 0 on success (i.e., the node will be suspended after a short
+ * delay), -1 on failure (the operation is not supported, or an attempted
+ * suspend is already underway).
*/
-virDomainPtr
-virDomainLookupByID(virConnectPtr conn, int id)
+int
+virNodeSuspendForDuration(virConnectPtr conn,
+ unsigned int target,
+ unsigned long long duration,
+ unsigned int flags)
{
- VIR_DEBUG("conn=%p, id=%d", conn, id);
+ VIR_DEBUG("conn=%p, target=%d, duration=%lld, flags=%x",
+ conn, target, duration, flags);
virResetLastError();
- virCheckConnectReturn(conn, NULL);
- virCheckNonNegativeArgGoto(id, error);
+ virCheckConnectReturn(conn, -1);
+ virCheckReadOnlyGoto(conn->flags, error);
- if (conn->driver->domainLookupByID) {
- virDomainPtr ret;
- ret = conn->driver->domainLookupByID(conn, id);
- if (!ret)
+ if (conn->driver->nodeSuspendForDuration) {
+ int ret;
+ ret = conn->driver->nodeSuspendForDuration(conn, target,
+ duration, flags);
+ if (ret < 0)
goto error;
return ret;
}
@@ -2037,37 +2127,58 @@ virDomainLookupByID(virConnectPtr conn, int id)
error:
virDispatchError(conn);
- return NULL;
+ return -1;
}
-/**
- * virDomainLookupByUUID:
+/*
+ * virNodeGetMemoryParameters:
* @conn: pointer to the hypervisor connection
- * @uuid: the raw UUID for the domain
+ * @params: pointer to memory parameter object
+ * (return value, allocated by the caller)
+ * @nparams: pointer to number of memory parameters; input and output
+ * @flags: extra flags; not used yet, so callers should always pass 0
*
- * Try to lookup a domain on the given hypervisor based on its UUID.
+ * Get all node memory parameters (parameters unsupported by OS will be
+ * omitted). On input, @nparams gives the size of the @params array;
+ * on output, @nparams gives how many slots were filled with parameter
+ * information, which might be less but will not exceed the input value.
*
- * virDomainFree should be used to free the resources after the
- * domain object is no longer needed.
+ * As a special case, calling with @params as NULL and @nparams as 0 on
+ * input will cause @nparams on output to contain the number of parameters
+ * supported by the hypervisor. The caller should then allocate @params
+ * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
+ * again. See virDomainGetMemoryParameters() for an equivalent usage
+ * example.
*
- * Returns a new domain object or NULL in case of failure. If the
- * domain cannot be found, then VIR_ERR_NO_DOMAIN error is raised.
+ * Returns 0 in case of success, and -1 in case of failure.
*/
-virDomainPtr
-virDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
+int
+virNodeGetMemoryParameters(virConnectPtr conn,
+ virTypedParameterPtr params,
+ int *nparams,
+ unsigned int flags)
{
- VIR_UUID_DEBUG(conn, uuid);
+ VIR_DEBUG("conn=%p, params=%p, nparams=%p, flags=%x",
+ conn, params, nparams, flags);
virResetLastError();
- virCheckConnectReturn(conn, NULL);
- virCheckNonNullArgGoto(uuid, error);
+ virCheckConnectReturn(conn, -1);
+ virCheckNonNullArgGoto(nparams, error);
+ virCheckNonNegativeArgGoto(*nparams, error);
+ if (*nparams != 0)
+ virCheckNonNullArgGoto(params, error);
- if (conn->driver->domainLookupByUUID) {
- virDomainPtr ret;
- ret = conn->driver->domainLookupByUUID(conn, uuid);
- if (!ret)
+ if (VIR_DRV_SUPPORTS_FEATURE(conn->driver, conn,
+ VIR_DRV_FEATURE_TYPED_PARAM_STRING))
+ flags |= VIR_TYPED_PARAM_STRING_OKAY;
+
+ if (conn->driver->nodeGetMemoryParameters) {
+ int ret;
+ ret = conn->driver->nodeGetMemoryParameters(conn, params,
+ nparams, flags);
+ if (ret < 0)
goto error;
return ret;
}
@@ -2076,129 +2187,139 @@ virDomainLookupByUUID(virConnectPtr conn, const unsigned char
*uuid)
error:
virDispatchError(conn);
- return NULL;
+ return -1;
}
-/**
- * virDomainLookupByUUIDString:
+/*
+ * virNodeSetMemoryParameters:
* @conn: pointer to the hypervisor connection
- * @uuidstr: the string UUID for the domain
+ * @params: pointer to scheduler parameter objects
+ * @nparams: number of scheduler parameter objects
+ * (this value can be the same or less than the returned
+ * value nparams of virDomainGetSchedulerType)
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Change all or a subset of the node memory tunables. The function
+ * fails if not all of the tunables are supported.
*
- * Try to lookup a domain on the given hypervisor based on its UUID.
+ * Note that it's not recommended to use this function while the
+ * outside tuning program is running (such as ksmtuned under Linux),
+ * as they could change the tunables in parallel, which could cause
+ * conflicts.
*
- * virDomainFree should be used to free the resources after the
- * domain object is no longer needed.
+ * This function may require privileged access to the hypervisor.
*
- * Returns a new domain object or NULL in case of failure. If the
- * domain cannot be found, then VIR_ERR_NO_DOMAIN error is raised.
+ * Returns 0 in case of success, -1 in case of failure.
*/
-virDomainPtr
-virDomainLookupByUUIDString(virConnectPtr conn, const char *uuidstr)
+int
+virNodeSetMemoryParameters(virConnectPtr conn,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags)
{
- unsigned char uuid[VIR_UUID_BUFLEN];
- VIR_DEBUG("conn=%p, uuidstr=%s", conn, NULLSTR(uuidstr));
+ VIR_DEBUG("conn=%p, params=%p, nparams=%d, flags=%x",
+ conn, params, nparams, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, nparams);
virResetLastError();
- virCheckConnectReturn(conn, NULL);
- virCheckNonNullArgGoto(uuidstr, error);
+ virCheckConnectReturn(conn, -1);
+ virCheckReadOnlyGoto(conn->flags, error);
+ virCheckNonNullArgGoto(params, error);
+ virCheckNonNegativeArgGoto(nparams, error);
- if (virUUIDParse(uuidstr, uuid) < 0) {
- virReportInvalidArg(uuidstr,
- _("uuidstr in %s must be a valid UUID"),
- __FUNCTION__);
+ if (virTypedParameterValidateSet(conn, params, nparams) < 0)
goto error;
+
+ if (conn->driver->nodeSetMemoryParameters) {
+ int ret;
+ ret = conn->driver->nodeSetMemoryParameters(conn, params,
+ nparams, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
}
- return virDomainLookupByUUID(conn, &uuid[0]);
+ virReportUnsupportedError();
error:
virDispatchError(conn);
- return NULL;
+ return -1;
}
/**
- * virDomainLookupByName:
- * @conn: pointer to the hypervisor connection
- * @name: name for the domain
- *
- * Try to lookup a domain on the given hypervisor based on its name.
+ * virNodeGetSecurityModel:
+ * @conn: a connection object
+ * @secmodel: pointer to a virSecurityModel structure
*
- * virDomainFree should be used to free the resources after the
- * domain object is no longer needed.
+ * Extract the security model of a hypervisor. The 'model' field
+ * in the @secmodel argument may be initialized to the empty
+ * string if the driver has not activated a security model.
*
- * Returns a new domain object or NULL in case of failure. If the
- * domain cannot be found, then VIR_ERR_NO_DOMAIN error is raised.
+ * Returns 0 in case of success, -1 in case of failure
*/
-virDomainPtr
-virDomainLookupByName(virConnectPtr conn, const char *name)
+int
+virNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr secmodel)
{
- VIR_DEBUG("conn=%p, name=%s", conn, name);
+ VIR_DEBUG("conn=%p secmodel=%p", conn, secmodel);
virResetLastError();
- virCheckConnectReturn(conn, NULL);
- virCheckNonNullArgGoto(name, error);
+ virCheckConnectReturn(conn, -1);
+ virCheckNonNullArgGoto(secmodel, error);
- if (conn->driver->domainLookupByName) {
- virDomainPtr dom;
- dom = conn->driver->domainLookupByName(conn, name);
- if (!dom)
+ if (conn->driver->nodeGetSecurityModel) {
+ int ret;
+ ret = conn->driver->nodeGetSecurityModel(conn, secmodel);
+ if (ret < 0)
goto error;
- return dom;
+ return ret;
}
virReportUnsupportedError();
error:
virDispatchError(conn);
- return NULL;
+ return -1;
}
/**
- * virDomainDestroy:
- * @domain: a domain object
- *
- * Destroy the domain object. The running instance is shutdown if not down
- * already and all resources used by it are given back to the hypervisor. This
- * does not free the associated virDomainPtr object.
- * This function may require privileged access.
- *
- * virDomainDestroy first requests that a guest terminate
- * (e.g. SIGTERM), then waits for it to comply. After a reasonable
- * timeout, if the guest still exists, virDomainDestroy will
- * forcefully terminate the guest (e.g. SIGKILL) if necessary (which
- * may produce undesirable results, for example unflushed disk cache
- * in the guest). To avoid this possibility, it's recommended to
- * instead call virDomainDestroyFlags, sending the
- * VIR_DOMAIN_DESTROY_GRACEFUL flag.
- *
- * If the domain is transient and has any snapshot metadata (see
- * virDomainSnapshotNum()), then that metadata will automatically
- * be deleted when the domain quits.
+ * virNodeGetCellsFreeMemory:
+ * @conn: pointer to the hypervisor connection
+ * @freeMems: pointer to the array of unsigned long long
+ * @startCell: index of first cell to return freeMems info on.
+ * @maxCells: Maximum number of cells for which freeMems information can
+ * be returned.
*
- * Returns 0 in case of success and -1 in case of failure.
+ * This call returns the amount of free memory in one or more NUMA cells.
+ * The @freeMems array must be allocated by the caller and will be filled
+ * with the amount of free memory in bytes for each cell requested,
+ * starting with startCell (in freeMems[0]), up to either
+ * (startCell + maxCells), or the number of additional cells in the node,
+ * whichever is smaller.
+ *
+ * Returns the number of entries filled in freeMems, or -1 in case of error.
*/
int
-virDomainDestroy(virDomainPtr domain)
+virNodeGetCellsFreeMemory(virConnectPtr conn, unsigned long long *freeMems,
+ int startCell, int maxCells)
{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain);
+ VIR_DEBUG("conn=%p, freeMems=%p, startCell=%d, maxCells=%d",
+ conn, freeMems, startCell, maxCells);
virResetLastError();
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
+ virCheckConnectReturn(conn, -1);
+ virCheckNonNullArgGoto(freeMems, error);
+ virCheckPositiveArgGoto(maxCells, error);
+ virCheckNonNegativeArgGoto(startCell, error);
- if (conn->driver->domainDestroy) {
+ if (conn->driver->nodeGetCellsFreeMemory) {
int ret;
- ret = conn->driver->domainDestroy(domain);
+ ret = conn->driver->nodeGetCellsFreeMemory(conn, freeMems, startCell,
maxCells);
if (ret < 0)
goto error;
return ret;
@@ -2213,59 +2334,30 @@ virDomainDestroy(virDomainPtr domain)
/**
- * virDomainDestroyFlags:
- * @domain: a domain object
- * @flags: bitwise-OR of virDomainDestroyFlagsValues
- *
- * Destroy the domain object. The running instance is shutdown if not down
- * already and all resources used by it are given back to the hypervisor.
- * This does not free the associated virDomainPtr object.
- * This function may require privileged access.
- *
- * Calling this function with no @flags set (equal to zero) is
- * equivalent to calling virDomainDestroy, and after a reasonable
- * timeout will forcefully terminate the guest (e.g. SIGKILL) if
- * necessary (which may produce undesirable results, for example
- * unflushed disk cache in the guest). Including
- * VIR_DOMAIN_DESTROY_GRACEFUL in the flags will prevent the forceful
- * termination of the guest, and virDomainDestroyFlags will instead
- * return an error if the guest doesn't terminate by the end of the
- * timeout; at that time, the management application can decide if
- * calling again without VIR_DOMAIN_DESTROY_GRACEFUL is appropriate.
- *
- * Another alternative which may produce cleaner results for the
- * guest's disks is to use virDomainShutdown() instead, but that
- * depends on guest support (some hypervisor/guest combinations may
- * ignore the shutdown request).
+ * virConnectIsEncrypted:
+ * @conn: pointer to the connection object
*
+ * Determine if the connection to the hypervisor is encrypted
*
- * Returns 0 in case of success and -1 in case of failure.
+ * Returns 1 if encrypted, 0 if not encrypted, -1 on error
*/
int
-virDomainDestroyFlags(virDomainPtr domain,
- unsigned int flags)
+virConnectIsEncrypted(virConnectPtr conn)
{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+ VIR_DEBUG("conn=%p", conn);
virResetLastError();
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainDestroyFlags) {
+ virCheckConnectReturn(conn, -1);
+ if (conn->driver->connectIsEncrypted) {
int ret;
- ret = conn->driver->domainDestroyFlags(domain, flags);
+ ret = conn->driver->connectIsEncrypted(conn);
if (ret < 0)
goto error;
return ret;
}
virReportUnsupportedError();
-
error:
virDispatchError(conn);
return -1;
@@ -2273,238 +2365,120 @@ virDomainDestroyFlags(virDomainPtr domain,
/**
- * virDomainFree:
- * @domain: a domain object
+ * virConnectIsSecure:
+ * @conn: pointer to the connection object
*
- * Free the domain object. The running instance is kept alive.
- * The data structure is freed and should not be used thereafter.
+ * Determine if the connection to the hypervisor is secure
*
- * Returns 0 in case of success and -1 in case of failure.
+ * A connection will be classed as secure if it is either
+ * encrypted, or running over a channel which is not exposed
+ * to eavesdropping (eg a UNIX domain socket, or pipe)
+ *
+ * Returns 1 if secure, 0 if not secure, -1 on error
*/
int
-virDomainFree(virDomainPtr domain)
+virConnectIsSecure(virConnectPtr conn)
{
- VIR_DOMAIN_DEBUG(domain);
+ VIR_DEBUG("conn=%p", conn);
virResetLastError();
- virCheckDomainReturn(domain, -1);
+ virCheckConnectReturn(conn, -1);
+ if (conn->driver->connectIsSecure) {
+ int ret;
+ ret = conn->driver->connectIsSecure(conn);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
- virObjectUnref(domain);
- return 0;
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
}
/**
- * virDomainRef:
- * @domain: the domain to hold a reference on
- *
- * Increment the reference count on the domain. For each
- * additional call to this method, there shall be a corresponding
- * call to virDomainFree to release the reference count, once
- * the caller no longer needs the reference to this object.
+ * virConnectCompareCPU:
+ * @conn: virConnect connection
+ * @xmlDesc: XML describing the CPU to compare with host CPU
+ * @flags: bitwise-OR of virConnectCompareCPUFlags
*
- * This method is typically useful for applications where multiple
- * threads are using a connection, and it is required that the
- * connection remain open until all threads have finished using
- * it. ie, each new thread using a domain would increment
- * the reference count.
+ * Compares the given CPU description with the host CPU
*
- * Returns 0 in case of success and -1 in case of failure.
+ * Returns comparison result according to enum virCPUCompareResult. If
+ * VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE is used and @xmlDesc CPU is
+ * incompatible with host CPU, this function will return VIR_CPU_COMPARE_ERROR
+ * (instead of VIR_CPU_COMPARE_INCOMPATIBLE) and the error will use the
+ * VIR_ERR_CPU_INCOMPATIBLE code with a message providing more details about
+ * the incompatibility.
*/
int
-virDomainRef(virDomainPtr domain)
+virConnectCompareCPU(virConnectPtr conn,
+ const char *xmlDesc,
+ unsigned int flags)
{
- VIR_DOMAIN_DEBUG(domain, "refs=%d", domain ? domain->object.u.s.refs :
0);
+ VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, xmlDesc, flags);
virResetLastError();
- virCheckDomainReturn(domain, -1);
+ virCheckConnectReturn(conn, VIR_CPU_COMPARE_ERROR);
+ virCheckNonNullArgGoto(xmlDesc, error);
+
+ if (conn->driver->connectCompareCPU) {
+ int ret;
- virObjectRef(domain);
- return 0;
+ ret = conn->driver->connectCompareCPU(conn, xmlDesc, flags);
+ if (ret == VIR_CPU_COMPARE_ERROR)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return VIR_CPU_COMPARE_ERROR;
}
/**
- * virDomainSuspend:
- * @domain: a domain object
+ * virConnectGetCPUModelNames:
*
- * Suspends an active domain, the process is frozen without further access
- * to CPU resources and I/O but the memory used by the domain at the
- * hypervisor level will stay allocated. Use virDomainResume() to reactivate
- * the domain.
- * This function may require privileged access.
- * Moreover, suspend may not be supported if domain is in some
- * special state like VIR_DOMAIN_PMSUSPENDED.
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainSuspend(virDomainPtr domain)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainSuspend) {
- int ret;
- ret = conn->driver->domainSuspend(domain);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainResume:
- * @domain: a domain object
+ * @conn: virConnect connection
+ * @arch: Architecture
+ * @models: Pointer to a variable to store the NULL-terminated array of the
+ * CPU models supported for the specified architecture. Each element
+ * and the array itself must be freed by the caller with free. Pass
+ * NULL if only the list length is needed.
+ * @flags: extra flags; not used yet, so callers should always pass 0.
*
- * Resume a suspended domain, the process is restarted from the state where
- * it was frozen by calling virDomainSuspend().
- * This function may require privileged access
- * Moreover, resume may not be supported if domain is in some
- * special state like VIR_DOMAIN_PMSUSPENDED.
+ * Get the list of supported CPU models for a specific architecture.
*
- * Returns 0 in case of success and -1 in case of failure.
+ * Returns -1 on error, number of elements in @models on success.
*/
int
-virDomainResume(virDomainPtr domain)
+virConnectGetCPUModelNames(virConnectPtr conn, const char *arch, char ***models,
+ unsigned int flags)
{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain);
-
+ VIR_DEBUG("conn=%p, arch=%s, models=%p, flags=%x",
+ conn, arch, models, flags);
virResetLastError();
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
+ if (models)
+ *models = NULL;
- virCheckReadOnlyGoto(conn->flags, error);
+ virCheckConnectReturn(conn, -1);
+ virCheckNonNullArgGoto(arch, error);
- if (conn->driver->domainResume) {
+ if (conn->driver->connectGetCPUModelNames) {
int ret;
- ret = conn->driver->domainResume(domain);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainPMSuspendForDuration:
- * @dom: a domain object
- * @target: a value from virNodeSuspendTarget
- * @duration: duration in seconds to suspend, or 0 for indefinite
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Attempt to have the guest enter the given @target power management
- * suspension level. If @duration is non-zero, also schedule the guest to
- * resume normal operation after that many seconds, if nothing else has
- * resumed it earlier. Some hypervisors require that @duration be 0, for
- * an indefinite suspension.
- *
- * Dependent on hypervisor used, this may require a
- * guest agent to be available, e.g. QEMU.
- *
- * Beware that at least for QEMU, the domain's process will be terminated
- * when VIR_NODE_SUSPEND_TARGET_DISK is used and a new process will be
- * launched when libvirt is asked to wake up the domain. As a result of
- * this, any runtime changes, such as device hotplug or memory settings,
- * are lost unless such changes were made with VIR_DOMAIN_AFFECT_CONFIG
- * flag.
- *
- * Returns: 0 on success,
- * -1 on failure.
- */
-int
-virDomainPMSuspendForDuration(virDomainPtr dom,
- unsigned int target,
- unsigned long long duration,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "target=%u duration=%llu flags=%x",
- target, duration, flags);
-
- virResetLastError();
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainPMSuspendForDuration) {
- int ret;
- ret = conn->driver->domainPMSuspendForDuration(dom, target,
- duration, flags);
+ ret = conn->driver->connectGetCPUModelNames(conn, arch, models, flags);
if (ret < 0)
goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainPMWakeup:
- * @dom: a domain object
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Inject a wakeup into the guest that previously used
- * virDomainPMSuspendForDuration, rather than waiting for the
- * previously requested duration (if any) to elapse.
- *
- * Returns: 0 on success,
- * -1 on failure.
- */
-int
-virDomainPMWakeup(virDomainPtr dom,
- unsigned int flags)
-{
- virConnectPtr conn;
- VIR_DOMAIN_DEBUG(dom, "flags=%x", flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainPMWakeup) {
- int ret;
- ret = conn->driver->domainPMWakeup(dom, flags);
- if (ret < 0)
- goto error;
return ret;
}
@@ -2517,10843 +2491,101 @@ virDomainPMWakeup(virDomainPtr dom,
/**
- * virDomainSave:
- * @domain: a domain object
- * @to: path for the output file
+ * virConnectBaselineCPU:
*
- * This method will suspend a domain and save its memory contents to
- * a file on disk. After the call, if successful, the domain is not
- * listed as running anymore (this ends the life of a transient domain).
- * Use virDomainRestore() to restore a domain after saving.
+ * @conn: virConnect connection
+ * @xmlCPUs: array of XML descriptions of host CPUs
+ * @ncpus: number of CPUs in xmlCPUs
+ * @flags: bitwise-OR of virConnectBaselineCPUFlags
*
- * See virDomainSaveFlags() for more control. Also, a save file can
- * be inspected or modified slightly with virDomainSaveImageGetXMLDesc()
- * and virDomainSaveImageDefineXML().
+ * Computes the most feature-rich CPU which is compatible with all given
+ * host CPUs.
*
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainSave(virDomainPtr domain, const char *to)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "to=%s", to);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(to, error);
-
- if (conn->driver->domainSave) {
- int ret;
- char *absolute_to;
-
- /* We must absolutize the file path as the save is done out of process */
- if (virFileAbsPath(to, &absolute_to) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("could not build absolute output file path"));
- goto error;
- }
-
- ret = conn->driver->domainSave(domain, absolute_to);
-
- VIR_FREE(absolute_to);
-
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainSaveFlags:
- * @domain: a domain object
- * @to: path for the output file
- * @dxml: (optional) XML config for adjusting guest xml used on restore
- * @flags: bitwise-OR of virDomainSaveRestoreFlags
- *
- * This method will suspend a domain and save its memory contents to
- * a file on disk. After the call, if successful, the domain is not
- * listed as running anymore (this ends the life of a transient domain).
- * Use virDomainRestore() to restore a domain after saving.
- *
- * If the hypervisor supports it, @dxml can be used to alter
- * host-specific portions of the domain XML that will be used when
- * restoring an image. For example, it is possible to alter the
- * backing filename that is associated with a disk device, in order to
- * prepare for file renaming done as part of backing up the disk
- * device while the domain is stopped.
- *
- * If @flags includes VIR_DOMAIN_SAVE_BYPASS_CACHE, then libvirt will
- * attempt to bypass the file system cache while creating 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 saves to NFS.
- *
- * Normally, the saved state file will remember whether the domain was
- * running or paused, and restore defaults to the same state.
- * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in
- * @flags will override what state gets saved into the file. These
- * two flags are mutually exclusive.
- *
- * A save file can be inspected or modified slightly with
- * virDomainSaveImageGetXMLDesc() and virDomainSaveImageDefineXML().
- *
- * Some hypervisors may prevent this operation if there is a current
- * block copy operation; in that case, use virDomainBlockJobAbort()
- * to stop the block copy first.
+ * If @flags includes VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES then libvirt
+ * will explicitly list all CPU features that are part of the host CPU,
+ * without this flag features that are part of the CPU model will not be
+ * listed.
*
- * Returns 0 in case of success and -1 in case of failure.
+ * Returns XML description of the computed CPU (caller frees) or NULL on error.
*/
-int
-virDomainSaveFlags(virDomainPtr domain, const char *to,
- const char *dxml, unsigned int flags)
+char *
+virConnectBaselineCPU(virConnectPtr conn,
+ const char **xmlCPUs,
+ unsigned int ncpus,
+ unsigned int flags)
{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "to=%s, dxml=%s, flags=%x",
- to, NULLSTR(dxml), flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(to, error);
+ size_t i;
- if ((flags & VIR_DOMAIN_SAVE_RUNNING) && (flags &
VIR_DOMAIN_SAVE_PAUSED)) {
- virReportInvalidArg(flags, "%s",
- _("running and paused flags are mutually "
- "exclusive"));
- goto error;
+ VIR_DEBUG("conn=%p, xmlCPUs=%p, ncpus=%u, flags=%x",
+ conn, xmlCPUs, ncpus, flags);
+ if (xmlCPUs) {
+ for (i = 0; i < ncpus; i++)
+ VIR_DEBUG("xmlCPUs[%zu]=%s", i, NULLSTR(xmlCPUs[i]));
}
- if (conn->driver->domainSaveFlags) {
- int ret;
- char *absolute_to;
-
- /* We must absolutize the file path as the save is done out of process */
- if (virFileAbsPath(to, &absolute_to) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("could not build absolute output file path"));
- goto error;
- }
+ virResetLastError();
- ret = conn->driver->domainSaveFlags(domain, absolute_to, dxml, flags);
+ virCheckConnectReturn(conn, NULL);
+ virCheckNonNullArgGoto(xmlCPUs, error);
- VIR_FREE(absolute_to);
+ if (conn->driver->connectBaselineCPU) {
+ char *cpu;
- if (ret < 0)
+ cpu = conn->driver->connectBaselineCPU(conn, xmlCPUs, ncpus, flags);
+ if (!cpu)
goto error;
- return ret;
+ return cpu;
}
virReportUnsupportedError();
error:
- virDispatchError(domain->conn);
- return -1;
+ virDispatchError(conn);
+ return NULL;
}
/**
- * virDomainRestore:
- * @conn: pointer to the hypervisor connection
- * @from: path to the input file
+ * virConnectSetKeepAlive:
+ * @conn: pointer to a hypervisor connection
+ * @interval: number of seconds of inactivity before a keepalive message is sent
+ * @count: number of messages that can be sent in a row
*
- * This method will restore a domain saved to disk by virDomainSave().
+ * Start sending keepalive messages after @interval seconds of inactivity and
+ * consider the connection to be broken when no response is received after
+ * @count keepalive messages sent in a row. In other words, sending count + 1
+ * keepalive message results in closing the connection. When @interval is
+ * <= 0, no keepalive messages will be sent. When @count is 0, the connection
+ * will be automatically closed after @interval seconds of inactivity without
+ * sending any keepalive messages.
*
- * See virDomainRestoreFlags() for more control.
+ * Note: The client has to implement and run an event loop with
+ * virEventRegisterImpl() or virEventRegisterDefaultImpl() to be able to
+ * use keepalive messages. Failure to do so may result in connections
+ * being closed unexpectedly.
*
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainRestore(virConnectPtr conn, const char *from)
-{
- VIR_DEBUG("conn=%p, from=%s", conn, from);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(from, error);
-
- if (conn->driver->domainRestore) {
- int ret;
- char *absolute_from;
-
- /* We must absolutize the file path as the restore is done out of process */
- if (virFileAbsPath(from, &absolute_from) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("could not build absolute input file path"));
- goto error;
- }
-
- ret = conn->driver->domainRestore(conn, absolute_from);
-
- VIR_FREE(absolute_from);
-
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainRestoreFlags:
- * @conn: pointer to the hypervisor connection
- * @from: path to the input file
- * @dxml: (optional) XML config for adjusting guest xml used on restore
- * @flags: bitwise-OR of virDomainSaveRestoreFlags
- *
- * This method will restore a domain saved to disk by virDomainSave().
- *
- * If the hypervisor supports it, @dxml can be used to alter
- * host-specific portions of the domain XML that will be used when
- * restoring an image. For example, it is possible to alter the
- * backing filename that is associated with a disk device, in order to
- * prepare for file renaming done as part of backing up the disk
- * device while the domain is stopped.
- *
- * If @flags includes VIR_DOMAIN_SAVE_BYPASS_CACHE, 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 restores from NFS.
- *
- * Normally, the saved state file will remember whether the domain was
- * running or paused, and restore defaults to the same state.
- * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in
- * @flags will override the default read from the file. These two
- * flags are mutually exclusive.
+ * Note: This API function controls only keepalive messages sent by the client.
+ * If the server is configured to use keepalive you still need to run the event
+ * loop to respond to them, even if you disable keepalives by this function.
*
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainRestoreFlags(virConnectPtr conn, const char *from, const char *dxml,
- unsigned int flags)
-{
- VIR_DEBUG("conn=%p, from=%s, dxml=%s, flags=%x",
- conn, from, NULLSTR(dxml), flags);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(from, error);
-
- if ((flags & VIR_DOMAIN_SAVE_RUNNING) && (flags &
VIR_DOMAIN_SAVE_PAUSED)) {
- virReportInvalidArg(flags, "%s",
- _("running and paused flags are mutually "
- "exclusive"));
- goto error;
- }
-
- if (conn->driver->domainRestoreFlags) {
- int ret;
- char *absolute_from;
-
- /* We must absolutize the file path as the restore is done out of process */
- if (virFileAbsPath(from, &absolute_from) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("could not build absolute input file path"));
- goto error;
- }
-
- ret = conn->driver->domainRestoreFlags(conn, absolute_from, dxml,
- flags);
-
- VIR_FREE(absolute_from);
-
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainSaveImageGetXMLDesc:
- * @conn: pointer to the hypervisor connection
- * @file: path to saved state file
- * @flags: bitwise-OR of subset of virDomainXMLFlags
- *
- * This method will extract the XML describing the domain at the time
- * a saved state file was created. @file must be a file created
- * previously by virDomainSave() or virDomainSaveFlags().
- *
- * No security-sensitive data will be included unless @flags contains
- * VIR_DOMAIN_XML_SECURE; this flag is rejected on read-only
- * connections. For this API, @flags should not contain either
- * VIR_DOMAIN_XML_INACTIVE or VIR_DOMAIN_XML_UPDATE_CPU.
- *
- * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of
- * error. The caller must free() the returned value.
- */
-char *
-virDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *file,
- unsigned int flags)
-{
- VIR_DEBUG("conn=%p, file=%s, flags=%x",
- conn, file, flags);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, NULL);
- virCheckNonNullArgGoto(file, error);
-
- if ((conn->flags & VIR_CONNECT_RO) && (flags &
VIR_DOMAIN_XML_SECURE)) {
- virReportError(VIR_ERR_OPERATION_DENIED, "%s",
- _("virDomainSaveImageGetXMLDesc with secure flag"));
- goto error;
- }
-
- if (conn->driver->domainSaveImageGetXMLDesc) {
- char *ret;
- char *absolute_file;
-
- /* We must absolutize the file path as the read is done out of process */
- if (virFileAbsPath(file, &absolute_file) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("could not build absolute input file path"));
- goto error;
- }
-
- ret = conn->driver->domainSaveImageGetXMLDesc(conn, absolute_file,
- flags);
-
- VIR_FREE(absolute_file);
-
- if (!ret)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return NULL;
-}
-
-
-/**
- * virDomainSaveImageDefineXML:
- * @conn: pointer to the hypervisor connection
- * @file: path to saved state file
- * @dxml: XML config for adjusting guest xml used on restore
- * @flags: bitwise-OR of virDomainSaveRestoreFlags
- *
- * This updates the definition of a domain stored in a saved state
- * file. @file must be a file created previously by virDomainSave()
- * or virDomainSaveFlags().
- *
- * @dxml can be used to alter host-specific portions of the domain XML
- * that will be used when restoring an image. For example, it is
- * possible to alter the backing filename that is associated with a
- * disk device, to match renaming done as part of backing up the disk
- * device while the domain is stopped.
- *
- * Normally, the saved state file will remember whether the domain was
- * running or paused, and restore defaults to the same state.
- * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in
- * @flags will override the default saved into the file; omitting both
- * leaves the file's default unchanged. These two flags are mutually
- * exclusive.
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainSaveImageDefineXML(virConnectPtr conn, const char *file,
- const char *dxml, unsigned int flags)
-{
- VIR_DEBUG("conn=%p, file=%s, dxml=%s, flags=%x",
- conn, file, dxml, flags);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(file, error);
- virCheckNonNullArgGoto(dxml, error);
-
- if ((flags & VIR_DOMAIN_SAVE_RUNNING) && (flags &
VIR_DOMAIN_SAVE_PAUSED)) {
- virReportInvalidArg(flags, "%s",
- _("running and paused flags are mutually "
- "exclusive"));
- goto error;
- }
-
- if (conn->driver->domainSaveImageDefineXML) {
- int ret;
- char *absolute_file;
-
- /* We must absolutize the file path as the read is done out of process */
- if (virFileAbsPath(file, &absolute_file) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("could not build absolute input file path"));
- goto error;
- }
-
- ret = conn->driver->domainSaveImageDefineXML(conn, absolute_file,
- dxml, flags);
-
- VIR_FREE(absolute_file);
-
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainCoreDump:
- * @domain: a domain object
- * @to: path for the core file
- * @flags: bitwise-OR of virDomainCoreDumpFlags
- *
- * This method will dump the core of a domain on a given file for analysis.
- * Note that for remote Xen Daemon the file path will be interpreted in
- * the remote host. Hypervisors may require the user to manually ensure
- * proper permissions on the file named by @to.
- *
- * If @flags includes VIR_DUMP_CRASH, then leave the guest shut off with
- * a crashed state after the dump completes. If @flags includes
- * VIR_DUMP_LIVE, then make the core dump while continuing to allow
- * the guest to run; otherwise, the guest is suspended during the dump.
- * VIR_DUMP_RESET flag forces reset of the guest after dump.
- * The above three flags are mutually exclusive.
- *
- * Additionally, if @flags includes VIR_DUMP_BYPASS_CACHE, then libvirt
- * will attempt to bypass the file system cache while creating 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 saves to NFS.
- *
- * For more control over the output format, see virDomainCoreDumpWithFormat().
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainCoreDump(virDomainPtr domain, const char *to, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "to=%s, flags=%x", to, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(to, error);
-
- if ((flags & VIR_DUMP_CRASH) && (flags & VIR_DUMP_LIVE)) {
- virReportInvalidArg(flags, "%s",
- _("crash and live flags are mutually exclusive"));
- goto error;
- }
-
- if ((flags & VIR_DUMP_CRASH) && (flags & VIR_DUMP_RESET)) {
- virReportInvalidArg(flags, "%s",
- _("crash and reset flags are mutually exclusive"));
- goto error;
- }
-
- if ((flags & VIR_DUMP_LIVE) && (flags & VIR_DUMP_RESET)) {
- virReportInvalidArg(flags, "%s",
- _("live and reset flags are mutually exclusive"));
- goto error;
- }
-
- if (conn->driver->domainCoreDump) {
- int ret;
- char *absolute_to;
-
- /* We must absolutize the file path as the save is done out of process */
- if (virFileAbsPath(to, &absolute_to) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("could not build absolute core file path"));
- goto error;
- }
-
- ret = conn->driver->domainCoreDump(domain, absolute_to, flags);
-
- VIR_FREE(absolute_to);
-
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-/**
- * virDomainCoreDumpWithFormat:
- * @domain: a domain object
- * @to: path for the core file
- * @dumpformat: format of domain memory's dump
- * @flags: bitwise-OR of virDomainCoreDumpFlags
- *
- * This method will dump the core of a domain on a given file for analysis.
- * Note that for remote Xen Daemon the file path will be interpreted in
- * the remote host. Hypervisors may require the user to manually ensure
- * proper permissions on the file named by @to.
- *
- * @dumpformat controls which format the dump will have; use of
- * VIR_DOMAIN_CORE_DUMP_FORMAT_RAW mirrors what virDomainCoreDump() will
- * perform. Not all hypervisors are able to support all formats.
- *
- * If @flags includes VIR_DUMP_CRASH, then leave the guest shut off with
- * a crashed state after the dump completes. If @flags includes
- * VIR_DUMP_LIVE, then make the core dump while continuing to allow
- * the guest to run; otherwise, the guest is suspended during the dump.
- * VIR_DUMP_RESET flag forces reset of the guest after dump.
- * The above three flags are mutually exclusive.
- *
- * Additionally, if @flags includes VIR_DUMP_BYPASS_CACHE, then libvirt
- * will attempt to bypass the file system cache while creating 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 saves to NFS.
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainCoreDumpWithFormat(virDomainPtr domain, const char *to,
- unsigned int dumpformat, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "to=%s, dumpformat=%u, flags=%x",
- to, dumpformat, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(to, error);
-
- if (dumpformat >= VIR_DOMAIN_CORE_DUMP_FORMAT_LAST) {
- virReportInvalidArg(flags, _("dumpformat '%d' is not
supported"),
- dumpformat);
- goto error;
- }
-
- if ((flags & VIR_DUMP_CRASH) && (flags & VIR_DUMP_LIVE)) {
- virReportInvalidArg(flags, "%s",
- _("crash and live flags are mutually exclusive"));
- goto error;
- }
-
- if ((flags & VIR_DUMP_CRASH) && (flags & VIR_DUMP_RESET)) {
- virReportInvalidArg(flags, "%s",
- _("crash and reset flags are mutually
exclusive"));
- goto error;
- }
-
- if ((flags & VIR_DUMP_LIVE) && (flags & VIR_DUMP_RESET)) {
- virReportInvalidArg(flags, "%s",
- _("live and reset flags are mutually exclusive"));
- goto error;
- }
-
- if (conn->driver->domainCoreDumpWithFormat) {
- int ret;
- char *absolute_to;
-
- /* We must absolutize the file path as the save is done out of process */
- if (virFileAbsPath(to, &absolute_to) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("could not build absolute core file path"));
- goto error;
- }
-
- ret = conn->driver->domainCoreDumpWithFormat(domain, absolute_to,
- dumpformat, flags);
-
- VIR_FREE(absolute_to);
-
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainScreenshot:
- * @domain: a domain object
- * @stream: stream to use as output
- * @screen: monitor ID to take screenshot from
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Take a screenshot of current domain console as a stream. The image format
- * is hypervisor specific. Moreover, some hypervisors supports multiple
- * displays per domain. These can be distinguished by @screen argument.
- *
- * This call sets up a stream; subsequent use of stream API is necessary
- * to transfer actual data, determine how much data is successfully
- * transferred, and detect any errors.
- *
- * The screen ID is the sequential number of screen. In case of multiple
- * graphics cards, heads are enumerated before devices, e.g. having
- * two graphics cards, both with four heads, screen ID 5 addresses
- * the second head on the second card.
- *
- * Returns a string representing the mime-type of the image format, or
- * NULL upon error. The caller must free() the returned value.
- */
-char *
-virDomainScreenshot(virDomainPtr domain,
- virStreamPtr stream,
- unsigned int screen,
- unsigned int flags)
-{
- VIR_DOMAIN_DEBUG(domain, "stream=%p, flags=%x", stream, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, NULL);
- virCheckStreamGoto(stream, error);
- virCheckReadOnlyGoto(domain->conn->flags, error);
-
- if (domain->conn != stream->conn) {
- virReportInvalidArg(stream,
- _("stream in %s must match connection of domain
'%s'"),
- __FUNCTION__, domain->name);
- goto error;
- }
-
- if (domain->conn->driver->domainScreenshot) {
- char *ret;
- ret = domain->conn->driver->domainScreenshot(domain, stream,
- screen, flags);
-
- if (ret == NULL)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return NULL;
-}
-
-
-/**
- * virDomainShutdown:
- * @domain: a domain object
- *
- * Shutdown a domain, the domain object is still usable thereafter, but
- * the domain OS is being stopped. Note that the guest OS may ignore the
- * request. Additionally, the hypervisor may check and support the domain
- * 'on_poweroff' XML setting resulting in a domain that reboots instead of
- * shutting down. For guests that react to a shutdown request, the differences
- * from virDomainDestroy() are that the guests disk storage will be in a
- * stable state rather than having the (virtual) power cord pulled, and
- * this command returns as soon as the shutdown request is issued rather
- * than blocking until the guest is no longer running.
- *
- * If the domain is transient and has any snapshot metadata (see
- * virDomainSnapshotNum()), then that metadata will automatically
- * be deleted when the domain quits.
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainShutdown(virDomainPtr domain)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainShutdown) {
- int ret;
- ret = conn->driver->domainShutdown(domain);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainShutdownFlags:
- * @domain: a domain object
- * @flags: bitwise-OR of virDomainShutdownFlagValues
- *
- * Shutdown a domain, the domain object is still usable thereafter but
- * the domain OS is being stopped. Note that the guest OS may ignore the
- * request. Additionally, the hypervisor may check and support the domain
- * 'on_poweroff' XML setting resulting in a domain that reboots instead of
- * shutting down. For guests that react to a shutdown request, the differences
- * from virDomainDestroy() are that the guest's disk storage will be in a
- * stable state rather than having the (virtual) power cord pulled, and
- * this command returns as soon as the shutdown request is issued rather
- * than blocking until the guest is no longer running.
- *
- * If the domain is transient and has any snapshot metadata (see
- * virDomainSnapshotNum()), then that metadata will automatically
- * be deleted when the domain quits.
- *
- * If @flags is set to zero, then the hypervisor will choose the
- * method of shutdown it considers best. To have greater control
- * pass one or more of the virDomainShutdownFlagValues. The order
- * in which the hypervisor tries each shutdown method is undefined,
- * and a hypervisor is not required to support all methods.
- *
- * To use guest agent (VIR_DOMAIN_SHUTDOWN_GUEST_AGENT) the domain XML
- * must have <channel> configured.
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainShutdownFlags(virDomainPtr domain, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainShutdownFlags) {
- int ret;
- ret = conn->driver->domainShutdownFlags(domain, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainReboot:
- * @domain: a domain object
- * @flags: bitwise-OR of virDomainRebootFlagValues
- *
- * Reboot a domain, the domain object is still usable thereafter, but
- * the domain OS is being stopped for a restart.
- * Note that the guest OS may ignore the request.
- * Additionally, the hypervisor may check and support the domain
- * 'on_reboot' XML setting resulting in a domain that shuts down instead
- * of rebooting.
- *
- * If @flags is set to zero, then the hypervisor will choose the
- * method of shutdown it considers best. To have greater control
- * pass one or more of the virDomainRebootFlagValues. The order
- * in which the hypervisor tries each shutdown method is undefined,
- * and a hypervisor is not required to support all methods.
- *
- * To use guest agent (VIR_DOMAIN_REBOOT_GUEST_AGENT) the domain XML
- * must have <channel> configured.
- *
- * Due to implementation limitations in some drivers (the qemu driver,
- * for instance) it is not advised to migrate or save a guest that is
- * rebooting as a result of this API. Migrating such a guest can lead
- * to a plain shutdown on the destination.
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainReboot(virDomainPtr domain, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainReboot) {
- int ret;
- ret = conn->driver->domainReboot(domain, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainReset:
- * @domain: a domain object
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Reset a domain immediately without any guest OS shutdown.
- * Reset emulates the power reset button on a machine, where all
- * hardware sees the RST line set and reinitializes internal state.
- *
- * Note that there is a risk of data loss caused by reset without any
- * guest OS shutdown.
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainReset(virDomainPtr domain, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainReset) {
- int ret;
- ret = conn->driver->domainReset(domain, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetName:
- * @domain: a domain object
- *
- * Get the public name for that domain
- *
- * Returns a pointer to the name or NULL, the string need not be deallocated
- * its lifetime will be the same as the domain object.
- */
-const char *
-virDomainGetName(virDomainPtr domain)
-{
- VIR_DEBUG("domain=%p", domain);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, NULL);
-
- return domain->name;
-}
-
-
-/**
- * virDomainGetUUID:
- * @domain: a domain object
- * @uuid: pointer to a VIR_UUID_BUFLEN bytes array
- *
- * Get the UUID for a domain
- *
- * Returns -1 in case of error, 0 in case of success
- */
-int
-virDomainGetUUID(virDomainPtr domain, unsigned char *uuid)
-{
- VIR_DOMAIN_DEBUG(domain, "uuid=%p", uuid);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- virCheckNonNullArgGoto(uuid, error);
-
- memcpy(uuid, &domain->uuid[0], VIR_UUID_BUFLEN);
-
- return 0;
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetUUIDString:
- * @domain: a domain object
- * @buf: pointer to a VIR_UUID_STRING_BUFLEN bytes array
- *
- * Get the UUID for a domain as string. For more information about
- * UUID see RFC4122.
- *
- * Returns -1 in case of error, 0 in case of success
- */
-int
-virDomainGetUUIDString(virDomainPtr domain, char *buf)
-{
- VIR_DOMAIN_DEBUG(domain, "buf=%p", buf);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- virCheckNonNullArgGoto(buf, error);
-
- virUUIDFormat(domain->uuid, buf);
- return 0;
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetID:
- * @domain: a domain object
- *
- * Get the hypervisor ID number for the domain
- *
- * Returns the domain ID number or (unsigned int) -1 in case of error
- */
-unsigned int
-virDomainGetID(virDomainPtr domain)
-{
- VIR_DOMAIN_DEBUG(domain);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, (unsigned int)-1);
-
- return domain->id;
-}
-
-
-/**
- * virDomainGetOSType:
- * @domain: a domain object
- *
- * Get the type of domain operation system.
- *
- * Returns the new string or NULL in case of error, the string must be
- * freed by the caller.
- */
-char *
-virDomainGetOSType(virDomainPtr domain)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, NULL);
- conn = domain->conn;
-
- if (conn->driver->domainGetOSType) {
- char *ret;
- ret = conn->driver->domainGetOSType(domain);
- if (!ret)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return NULL;
-}
-
-
-/**
- * virDomainGetMaxMemory:
- * @domain: a domain object or NULL
- *
- * Retrieve the maximum amount of physical memory allocated to a
- * domain. If domain is NULL, then this get the amount of memory reserved
- * to Domain0 i.e. the domain where the application runs.
- *
- * Returns the memory size in kibibytes (blocks of 1024 bytes), or 0 in
- * case of error.
- */
-unsigned long
-virDomainGetMaxMemory(virDomainPtr domain)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, 0);
- conn = domain->conn;
-
- if (conn->driver->domainGetMaxMemory) {
- unsigned long long ret;
- ret = conn->driver->domainGetMaxMemory(domain);
- if (ret == 0)
- goto error;
- if ((unsigned long) ret != ret) {
- virReportError(VIR_ERR_OVERFLOW, _("result too large: %llu"),
- ret);
- goto error;
- }
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return 0;
-}
-
-
-/**
- * virDomainSetMaxMemory:
- * @domain: a domain object or NULL
- * @memory: the memory size in kibibytes (blocks of 1024 bytes)
- *
- * Dynamically change the maximum amount of physical memory allocated to a
- * domain. If domain is NULL, then this change the amount of memory reserved
- * to Domain0 i.e. the domain where the application runs.
- * This function may require privileged access to the hypervisor.
- *
- * This command is hypervisor-specific for whether active, persistent,
- * or both configurations are changed; for more control, use
- * virDomainSetMemoryFlags().
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "memory=%lu", memory);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonZeroArgGoto(memory, error);
-
- if (conn->driver->domainSetMaxMemory) {
- int ret;
- ret = conn->driver->domainSetMaxMemory(domain, memory);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainSetMemory:
- * @domain: a domain object or NULL
- * @memory: the memory size in kibibytes (blocks of 1024 bytes)
- *
- * Dynamically change the target amount of physical memory allocated to a
- * domain. If domain is NULL, then this change the amount of memory reserved
- * to Domain0 i.e. the domain where the application runs.
- * This function may require privileged access to the hypervisor.
- *
- * This command only changes the runtime configuration of the domain,
- * so can only be called on an active domain.
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainSetMemory(virDomainPtr domain, unsigned long memory)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "memory=%lu", memory);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonZeroArgGoto(memory, error);
-
- if (conn->driver->domainSetMemory) {
- int ret;
- ret = conn->driver->domainSetMemory(domain, memory);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainSetMemoryFlags:
- * @domain: a domain object or NULL
- * @memory: the memory size in kibibytes (blocks of 1024 bytes)
- * @flags: bitwise-OR of virDomainMemoryModFlags
- *
- * Dynamically change the target amount of physical memory allocated to a
- * domain. If domain is NULL, then this change the amount of memory reserved
- * to Domain0 i.e. the domain where the application runs.
- * This function may require privileged access to the hypervisor.
- *
- * @flags may include VIR_DOMAIN_AFFECT_LIVE or VIR_DOMAIN_AFFECT_CONFIG.
- * Both flags may be set. If VIR_DOMAIN_AFFECT_LIVE is set, the change affects
- * a running domain and will fail if domain is not active.
- * If VIR_DOMAIN_AFFECT_CONFIG is set, the change affects persistent state,
- * and will fail for transient domains. If neither flag is specified
- * (that is, @flags is VIR_DOMAIN_AFFECT_CURRENT), then an inactive domain
- * modifies persistent setup, while an active domain is hypervisor-dependent
- * on whether just live or both live and persistent state is changed.
- * If VIR_DOMAIN_MEM_MAXIMUM is set, the change affects domain's maximum memory
- * size rather than current memory size.
- * Not all hypervisors can support all flag combinations.
- *
- * Returns 0 in case of success, -1 in case of failure.
- */
-int
-virDomainSetMemoryFlags(virDomainPtr domain, unsigned long memory,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "memory=%lu, flags=%x", memory, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonZeroArgGoto(memory, error);
-
- if (conn->driver->domainSetMemoryFlags) {
- int ret;
- ret = conn->driver->domainSetMemoryFlags(domain, memory, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainSetMemoryStatsPeriod:
- * @domain: a domain object or NULL
- * @period: the period in seconds for stats collection
- * @flags: bitwise-OR of virDomainMemoryModFlags
- *
- * Dynamically change the domain memory balloon driver statistics collection
- * period. Use 0 to disable and a positive value to enable.
- *
- * @flags may include VIR_DOMAIN_AFFECT_LIVE or VIR_DOMAIN_AFFECT_CONFIG.
- * Both flags may be set. If VIR_DOMAIN_AFFECT_LIVE is set, the change affects
- * a running domain and will fail if domain is not active.
- * If VIR_DOMAIN_AFFECT_CONFIG is set, the change affects persistent state,
- * and will fail for transient domains. If neither flag is specified
- * (that is, @flags is VIR_DOMAIN_AFFECT_CURRENT), then an inactive domain
- * modifies persistent setup, while an active domain is hypervisor-dependent
- * on whether just live or both live and persistent state is changed.
- *
- * Not all hypervisors can support all flag combinations.
- *
- * Returns 0 in case of success, -1 in case of failure.
- */
-int
-virDomainSetMemoryStatsPeriod(virDomainPtr domain, int period,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "peroid=%d, flags=%x", period, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- /* This must be positive to set the balloon collection period */
- virCheckNonNegativeArgGoto(period, error);
-
- if (conn->driver->domainSetMemoryStatsPeriod) {
- int ret;
- ret = conn->driver->domainSetMemoryStatsPeriod(domain, period, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/* Helper function called to validate incoming client array on any
- * interface that sets typed parameters in the hypervisor. */
-static int
-virTypedParameterValidateSet(virConnectPtr conn,
- virTypedParameterPtr params,
- int nparams)
-{
- bool string_okay;
- size_t i;
-
- string_okay = VIR_DRV_SUPPORTS_FEATURE(conn->driver,
- conn,
- VIR_DRV_FEATURE_TYPED_PARAM_STRING);
- for (i = 0; i < nparams; i++) {
- if (strnlen(params[i].field, VIR_TYPED_PARAM_FIELD_LENGTH) ==
- VIR_TYPED_PARAM_FIELD_LENGTH) {
- virReportInvalidArg(params,
- _("string parameter name '%.*s' too
long"),
- VIR_TYPED_PARAM_FIELD_LENGTH,
- params[i].field);
- return -1;
- }
- if (params[i].type == VIR_TYPED_PARAM_STRING) {
- if (string_okay) {
- if (!params[i].value.s) {
- virReportInvalidArg(params,
- _("NULL string parameter
'%s'"),
- params[i].field);
- return -1;
- }
- } else {
- virReportInvalidArg(params,
- _("string parameter '%s'
unsupported"),
- params[i].field);
- return -1;
- }
- }
- }
- return 0;
-}
-
-
-/**
- * virDomainSetMemoryParameters:
- * @domain: pointer to domain object
- * @params: pointer to memory parameter objects
- * @nparams: number of memory parameter (this value can be the same or
- * less than the number of parameters supported)
- * @flags: bitwise-OR of virDomainModificationImpact
- *
- * Change all or a subset of the memory tunables.
- * This function may require privileged access to the hypervisor.
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virDomainSetMemoryParameters(virDomainPtr domain,
- virTypedParameterPtr params,
- int nparams, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
- params, nparams, flags);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(params, error);
- virCheckPositiveArgGoto(nparams, error);
-
- if (virTypedParameterValidateSet(conn, params, nparams) < 0)
- goto error;
-
- if (conn->driver->domainSetMemoryParameters) {
- int ret;
- ret = conn->driver->domainSetMemoryParameters(domain, params, nparams,
flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetMemoryParameters:
- * @domain: pointer to domain object
- * @params: pointer to memory parameter object
- * (return value, allocated by the caller)
- * @nparams: pointer to number of memory parameters; input and output
- * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
- *
- * Get all memory parameters. On input, @nparams gives the size of the
- * @params array; on output, @nparams gives how many slots were filled
- * with parameter information, which might be less but will not exceed
- * the input value.
- *
- * As a special case, calling with @params as NULL and @nparams as 0 on
- * input will cause @nparams on output to contain the number of parameters
- * supported by the hypervisor. The caller should then allocate @params
- * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
- * again.
- *
- * Here is a sample code snippet:
- *
- * if (virDomainGetMemoryParameters(dom, NULL, &nparams, 0) == 0 &&
- * nparams != 0) {
- * if ((params = malloc(sizeof(*params) * nparams)) == NULL)
- * goto error;
- * memset(params, 0, sizeof(*params) * nparams);
- * if (virDomainGetMemoryParameters(dom, params, &nparams, 0))
- * goto error;
- * }
- *
- * This function may require privileged access to the hypervisor. This function
- * expects the caller to allocate the @params.
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virDomainGetMemoryParameters(virDomainPtr domain,
- virTypedParameterPtr params,
- int *nparams, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
- params, (nparams) ? *nparams : -1, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- virCheckNonNullArgGoto(nparams, error);
- virCheckNonNegativeArgGoto(*nparams, error);
- if (*nparams != 0)
- virCheckNonNullArgGoto(params, error);
-
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_TYPED_PARAM_STRING))
- flags |= VIR_TYPED_PARAM_STRING_OKAY;
-
- /* At most one of these two flags should be set. */
- if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
- (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
- virReportInvalidArg(flags,
- _("flags 'affect live' and 'affect
config' in %s "
- "are mutually exclusive"),
- __FUNCTION__);
- goto error;
- }
- conn = domain->conn;
-
- if (conn->driver->domainGetMemoryParameters) {
- int ret;
- ret = conn->driver->domainGetMemoryParameters(domain, params, nparams,
flags);
- if (ret < 0)
- goto error;
- return ret;
- }
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainSetNumaParameters:
- * @domain: pointer to domain object
- * @params: pointer to numa parameter objects
- * @nparams: number of numa parameters (this value can be the same or
- * less than the number of parameters supported)
- * @flags: bitwise-OR of virDomainModificationImpact
- *
- * Change all or a subset of the numa tunables.
- * This function may require privileged access to the hypervisor.
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virDomainSetNumaParameters(virDomainPtr domain,
- virTypedParameterPtr params,
- int nparams, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
- params, nparams, flags);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- virCheckReadOnlyGoto(domain->conn->flags, error);
- virCheckNonNullArgGoto(params, error);
- virCheckPositiveArgGoto(nparams, error);
- if (virTypedParameterValidateSet(domain->conn, params, nparams) < 0)
- goto error;
-
- conn = domain->conn;
-
- if (conn->driver->domainSetNumaParameters) {
- int ret;
- ret = conn->driver->domainSetNumaParameters(domain, params, nparams,
- flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetNumaParameters:
- * @domain: pointer to domain object
- * @params: pointer to numa parameter object
- * (return value, allocated by the caller)
- * @nparams: pointer to number of numa parameters
- * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
- *
- * Get all numa parameters. On input, @nparams gives the size of the
- * @params array; on output, @nparams gives how many slots were filled
- * with parameter information, which might be less but will not exceed
- * the input value.
- *
- * As a special case, calling with @params as NULL and @nparams as 0 on
- * input will cause @nparams on output to contain the number of parameters
- * supported by the hypervisor. The caller should then allocate @params
- * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
- * again.
- *
- * See virDomainGetMemoryParameters() for an equivalent usage example.
- *
- * This function may require privileged access to the hypervisor. This function
- * expects the caller to allocate the @params.
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virDomainGetNumaParameters(virDomainPtr domain,
- virTypedParameterPtr params,
- int *nparams, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
- params, (nparams) ? *nparams : -1, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- virCheckNonNullArgGoto(nparams, error);
- virCheckNonNegativeArgGoto(*nparams, error);
- if (*nparams != 0)
- virCheckNonNullArgGoto(params, error);
-
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_TYPED_PARAM_STRING))
- flags |= VIR_TYPED_PARAM_STRING_OKAY;
-
- conn = domain->conn;
-
- if (conn->driver->domainGetNumaParameters) {
- int ret;
- ret = conn->driver->domainGetNumaParameters(domain, params, nparams,
- flags);
- if (ret < 0)
- goto error;
- return ret;
- }
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainSetBlkioParameters:
- * @domain: pointer to domain object
- * @params: pointer to blkio parameter objects
- * @nparams: number of blkio parameters (this value can be the same or
- * less than the number of parameters supported)
- * @flags: bitwise-OR of virDomainModificationImpact
- *
- * Change all or a subset of the blkio tunables.
- * This function may require privileged access to the hypervisor.
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virDomainSetBlkioParameters(virDomainPtr domain,
- virTypedParameterPtr params,
- int nparams, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
- params, nparams, flags);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(params, error);
- virCheckNonNegativeArgGoto(nparams, error);
-
- if (virTypedParameterValidateSet(conn, params, nparams) < 0)
- goto error;
-
- if (conn->driver->domainSetBlkioParameters) {
- int ret;
- ret = conn->driver->domainSetBlkioParameters(domain, params, nparams,
flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetBlkioParameters:
- * @domain: pointer to domain object
- * @params: pointer to blkio parameter object
- * (return value, allocated by the caller)
- * @nparams: pointer to number of blkio parameters; input and output
- * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
- *
- * Get all blkio parameters. On input, @nparams gives the size of the
- * @params array; on output, @nparams gives how many slots were filled
- * with parameter information, which might be less but will not exceed
- * the input value.
- *
- * As a special case, calling with @params as NULL and @nparams as 0 on
- * input will cause @nparams on output to contain the number of parameters
- * supported by the hypervisor. The caller should then allocate @params
- * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
- * again.
- *
- * See virDomainGetMemoryParameters() for an equivalent usage example.
- *
- * This function may require privileged access to the hypervisor. This function
- * expects the caller to allocate the @params.
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virDomainGetBlkioParameters(virDomainPtr domain,
- virTypedParameterPtr params,
- int *nparams, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
- params, (nparams) ? *nparams : -1, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- virCheckNonNullArgGoto(nparams, error);
- virCheckNonNegativeArgGoto(*nparams, error);
- if (*nparams != 0)
- virCheckNonNullArgGoto(params, error);
-
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_TYPED_PARAM_STRING))
- flags |= VIR_TYPED_PARAM_STRING_OKAY;
-
- /* At most one of these two flags should be set. */
- if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
- (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
- virReportInvalidArg(flags,
- _("flags 'affect live' and 'affect
config' in %s "
- "are mutually exclusive"),
- __FUNCTION__);
- goto error;
- }
- conn = domain->conn;
-
- if (conn->driver->domainGetBlkioParameters) {
- int ret;
- ret = conn->driver->domainGetBlkioParameters(domain, params, nparams,
flags);
- if (ret < 0)
- goto error;
- return ret;
- }
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetInfo:
- * @domain: a domain object
- * @info: pointer to a virDomainInfo structure allocated by the user
- *
- * Extract information about a domain. Note that if the connection
- * used to get the domain is limited only a partial set of the information
- * can be extracted.
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "info=%p", info);
-
- virResetLastError();
-
- if (info)
- memset(info, 0, sizeof(*info));
-
- virCheckDomainReturn(domain, -1);
- virCheckNonNullArgGoto(info, error);
-
- conn = domain->conn;
-
- if (conn->driver->domainGetInfo) {
- int ret;
- ret = conn->driver->domainGetInfo(domain, info);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetState:
- * @domain: a domain object
- * @state: returned state of the domain (one of virDomainState)
- * @reason: returned reason which led to @state (one of virDomain*Reason
- * corresponding to the current state); it is allowed to be NULL
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Extract domain state. Each state can be accompanied with a reason (if known)
- * which led to the state.
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainGetState(virDomainPtr domain,
- int *state,
- int *reason,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "state=%p, reason=%p, flags=%x",
- state, reason, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- virCheckNonNullArgGoto(state, error);
-
- conn = domain->conn;
- if (conn->driver->domainGetState) {
- int ret;
- ret = conn->driver->domainGetState(domain, state, reason, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetControlInfo:
- * @domain: a domain object
- * @info: pointer to a virDomainControlInfo structure allocated by the user
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Extract details about current state of control interface to a domain.
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainGetControlInfo(virDomainPtr domain,
- virDomainControlInfoPtr info,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "info=%p, flags=%x", info, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- virCheckNonNullArgGoto(info, error);
-
- conn = domain->conn;
- if (conn->driver->domainGetControlInfo) {
- int ret;
- ret = conn->driver->domainGetControlInfo(domain, info, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetXMLDesc:
- * @domain: a domain object
- * @flags: bitwise-OR of virDomainXMLFlags
- *
- * Provide an XML description of the domain. The description may be reused
- * later to relaunch the domain with virDomainCreateXML().
- *
- * No security-sensitive data will be included unless @flags contains
- * VIR_DOMAIN_XML_SECURE; this flag is rejected on read-only
- * connections. If @flags includes VIR_DOMAIN_XML_INACTIVE, then the
- * XML represents the configuration that will be used on the next boot
- * of a persistent domain; otherwise, the configuration represents the
- * currently running domain. If @flags contains
- * VIR_DOMAIN_XML_UPDATE_CPU, then the portion of the domain XML
- * describing CPU capabilities is modified to match actual
- * capabilities of the host.
- *
- * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
- * the caller must free() the returned value.
- */
-char *
-virDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, NULL);
- conn = domain->conn;
-
- if ((conn->flags & VIR_CONNECT_RO) && (flags &
VIR_DOMAIN_XML_SECURE)) {
- virReportError(VIR_ERR_OPERATION_DENIED, "%s",
- _("virDomainGetXMLDesc with secure flag"));
- goto error;
- }
-
- if (conn->driver->domainGetXMLDesc) {
- char *ret;
- ret = conn->driver->domainGetXMLDesc(domain, flags);
- if (!ret)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return NULL;
-}
-
-
-/**
- * virConnectDomainXMLFromNative:
- * @conn: a connection object
- * @nativeFormat: configuration format importing from
- * @nativeConfig: the configuration data to import
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Reads native configuration data describing a domain, and
- * generates libvirt domain XML. The format of the native
- * data is hypervisor dependant.
- *
- * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
- * the caller must free() the returned value.
- */
-char *
-virConnectDomainXMLFromNative(virConnectPtr conn,
- const char *nativeFormat,
- const char *nativeConfig,
- unsigned int flags)
-{
- VIR_DEBUG("conn=%p, format=%s, config=%s, flags=%x",
- conn, nativeFormat, nativeConfig, flags);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, NULL);
- virCheckReadOnlyGoto(conn->flags, error);
-
- virCheckNonNullArgGoto(nativeFormat, error);
- virCheckNonNullArgGoto(nativeConfig, error);
-
- if (conn->driver->connectDomainXMLFromNative) {
- char *ret;
- ret = conn->driver->connectDomainXMLFromNative(conn,
- nativeFormat,
- nativeConfig,
- flags);
- if (!ret)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return NULL;
-}
-
-
-/**
- * virConnectDomainXMLToNative:
- * @conn: a connection object
- * @nativeFormat: configuration format exporting to
- * @domainXml: the domain configuration to export
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Reads a domain XML configuration document, and generates
- * a native configuration file describing the domain.
- * The format of the native data is hypervisor dependant.
- *
- * Returns a 0 terminated UTF-8 encoded native config datafile, or NULL in case of
error.
- * the caller must free() the returned value.
- */
-char *
-virConnectDomainXMLToNative(virConnectPtr conn,
- const char *nativeFormat,
- const char *domainXml,
- unsigned int flags)
-{
- VIR_DEBUG("conn=%p, format=%s, xml=%s, flags=%x",
- conn, nativeFormat, domainXml, flags);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, NULL);
- virCheckReadOnlyGoto(conn->flags, error);
-
- virCheckNonNullArgGoto(nativeFormat, error);
- virCheckNonNullArgGoto(domainXml, error);
-
- if (conn->driver->connectDomainXMLToNative) {
- char *ret;
- ret = conn->driver->connectDomainXMLToNative(conn,
- nativeFormat,
- domainXml,
- flags);
- if (!ret)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return NULL;
-}
-
-
-/*
- * Sequence v1:
- *
- * Dst: Prepare
- * - Get ready to accept incoming VM
- * - Generate optional cookie to pass to src
- *
- * Src: Perform
- * - Start migration and wait for send completion
- * - Kill off VM if successful, resume if failed
- *
- * Dst: Finish
- * - Wait for recv completion and check status
- * - Kill off VM if unsuccessful
- *
- */
-static virDomainPtr
-virDomainMigrateVersion1(virDomainPtr domain,
- virConnectPtr dconn,
- unsigned long flags,
- const char *dname,
- const char *uri,
- unsigned long bandwidth)
-{
- virDomainPtr ddomain = NULL;
- char *uri_out = NULL;
- char *cookie = NULL;
- int cookielen = 0, ret;
- virDomainInfo info;
- unsigned int destflags;
-
- VIR_DOMAIN_DEBUG(domain,
- "dconn=%p, flags=%lx, dname=%s, uri=%s, bandwidth=%lu",
- dconn, flags, NULLSTR(dname), NULLSTR(uri), bandwidth);
-
- ret = virDomainGetInfo(domain, &info);
- if (ret == 0 && info.state == VIR_DOMAIN_PAUSED)
- flags |= VIR_MIGRATE_PAUSED;
-
- destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR |
- VIR_MIGRATE_AUTO_CONVERGE);
-
- /* Prepare the migration.
- *
- * The destination host may return a cookie, or leave cookie as
- * NULL.
- *
- * The destination host MUST set uri_out if uri_in is NULL.
- *
- * If uri_in is non-NULL, then the destination host may modify
- * the URI by setting uri_out. If it does not wish to modify
- * the URI, it should leave uri_out as NULL.
- */
- if (dconn->driver->domainMigratePrepare
- (dconn, &cookie, &cookielen, uri, &uri_out, destflags, dname,
- bandwidth) == -1)
- goto done;
-
- if (uri == NULL && uri_out == NULL) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("domainMigratePrepare did not set uri"));
- goto done;
- }
- if (uri_out)
- uri = uri_out; /* Did domainMigratePrepare change URI? */
-
- /* Perform the migration. The driver isn't supposed to return
- * until the migration is complete.
- */
- if (domain->conn->driver->domainMigratePerform
- (domain, cookie, cookielen, uri, flags, dname, bandwidth) == -1)
- goto done;
-
- /* Get the destination domain and return it or error.
- * 'domain' no longer actually exists at this point
- * (or so we hope), but we still use the object in memory
- * in order to get the name.
- */
- dname = dname ? dname : domain->name;
- if (dconn->driver->domainMigrateFinish)
- ddomain = dconn->driver->domainMigrateFinish
- (dconn, dname, cookie, cookielen, uri, destflags);
- else
- ddomain = virDomainLookupByName(dconn, dname);
-
- done:
- VIR_FREE(uri_out);
- VIR_FREE(cookie);
- return ddomain;
-}
-
-
-/*
- * Sequence v2:
- *
- * Src: DumpXML
- * - Generate XML to pass to dst
- *
- * Dst: Prepare
- * - Get ready to accept incoming VM
- * - Generate optional cookie to pass to src
- *
- * Src: Perform
- * - Start migration and wait for send completion
- * - Kill off VM if successful, resume if failed
- *
- * Dst: Finish
- * - Wait for recv completion and check status
- * - Kill off VM if unsuccessful
- *
- */
-static virDomainPtr
-virDomainMigrateVersion2(virDomainPtr domain,
- virConnectPtr dconn,
- unsigned long flags,
- const char *dname,
- const char *uri,
- unsigned long bandwidth)
-{
- virDomainPtr ddomain = NULL;
- char *uri_out = NULL;
- char *cookie = NULL;
- char *dom_xml = NULL;
- int cookielen = 0, ret;
- virDomainInfo info;
- virErrorPtr orig_err = NULL;
- unsigned int getxml_flags = 0;
- int cancelled;
- unsigned long destflags;
-
- VIR_DOMAIN_DEBUG(domain,
- "dconn=%p, flags=%lx, dname=%s, uri=%s, bandwidth=%lu",
- dconn, flags, NULLSTR(dname), NULLSTR(uri), bandwidth);
-
- /* Prepare the migration.
- *
- * The destination host may return a cookie, or leave cookie as
- * NULL.
- *
- * The destination host MUST set uri_out if uri_in is NULL.
- *
- * If uri_in is non-NULL, then the destination host may modify
- * the URI by setting uri_out. If it does not wish to modify
- * the URI, it should leave uri_out as NULL.
- */
-
- /* In version 2 of the protocol, the prepare step is slightly
- * different. We fetch the domain XML of the source domain
- * and pass it to Prepare2.
- */
- if (!domain->conn->driver->domainGetXMLDesc) {
- virReportUnsupportedError();
- return NULL;
- }
-
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_XML_MIGRATABLE)) {
- getxml_flags |= VIR_DOMAIN_XML_MIGRATABLE;
- } else {
- getxml_flags |= VIR_DOMAIN_XML_SECURE | VIR_DOMAIN_XML_UPDATE_CPU;
- }
-
- dom_xml = domain->conn->driver->domainGetXMLDesc(domain, getxml_flags);
- if (!dom_xml)
- return NULL;
-
- ret = virDomainGetInfo(domain, &info);
- if (ret == 0 && info.state == VIR_DOMAIN_PAUSED)
- flags |= VIR_MIGRATE_PAUSED;
-
- destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR |
- VIR_MIGRATE_AUTO_CONVERGE);
-
- VIR_DEBUG("Prepare2 %p flags=%lx", dconn, destflags);
- ret = dconn->driver->domainMigratePrepare2
- (dconn, &cookie, &cookielen, uri, &uri_out, destflags, dname,
- bandwidth, dom_xml);
- VIR_FREE(dom_xml);
- if (ret == -1)
- goto done;
-
- if (uri == NULL && uri_out == NULL) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("domainMigratePrepare2 did not set uri"));
- cancelled = 1;
- /* Make sure Finish doesn't overwrite the error */
- orig_err = virSaveLastError();
- goto finish;
- }
- if (uri_out)
- uri = uri_out; /* Did domainMigratePrepare2 change URI? */
-
- /* Perform the migration. The driver isn't supposed to return
- * until the migration is complete.
- */
- VIR_DEBUG("Perform %p", domain->conn);
- ret = domain->conn->driver->domainMigratePerform
- (domain, cookie, cookielen, uri, flags, dname, bandwidth);
-
- /* Perform failed. Make sure Finish doesn't overwrite the error */
- if (ret < 0)
- orig_err = virSaveLastError();
-
- /* If Perform returns < 0, then we need to cancel the VM
- * startup on the destination
- */
- cancelled = ret < 0 ? 1 : 0;
-
- finish:
- /* In version 2 of the migration protocol, we pass the
- * status code from the sender to the destination host,
- * so it can do any cleanup if the migration failed.
- */
- dname = dname ? dname : domain->name;
- VIR_DEBUG("Finish2 %p ret=%d", dconn, ret);
- ddomain = dconn->driver->domainMigrateFinish2
- (dconn, dname, cookie, cookielen, uri, destflags, cancelled);
- if (cancelled && ddomain)
- VIR_ERROR(_("finish step ignored that migration was cancelled"));
-
- done:
- if (orig_err) {
- virSetError(orig_err);
- virFreeError(orig_err);
- }
- VIR_FREE(uri_out);
- VIR_FREE(cookie);
- return ddomain;
-}
-
-
-/*
- * Sequence v3:
- *
- * Src: Begin
- * - Generate XML to pass to dst
- * - Generate optional cookie to pass to dst
- *
- * Dst: Prepare
- * - Get ready to accept incoming VM
- * - Generate optional cookie to pass to src
- *
- * Src: Perform
- * - Start migration and wait for send completion
- * - Generate optional cookie to pass to dst
- *
- * Dst: Finish
- * - Wait for recv completion and check status
- * - Kill off VM if failed, resume if success
- * - Generate optional cookie to pass to src
- *
- * Src: Confirm
- * - Kill off VM if success, resume if failed
- *
- * If useParams is true, params and nparams contain migration parameters and
- * we know it's safe to call the API which supports extensible parameters.
- * Otherwise, we have to use xmlin, dname, uri, and bandwidth and pass them
- * to the old-style APIs.
- */
-static virDomainPtr
-virDomainMigrateVersion3Full(virDomainPtr domain,
- virConnectPtr dconn,
- const char *xmlin,
- const char *dname,
- const char *uri,
- unsigned long long bandwidth,
- virTypedParameterPtr params,
- int nparams,
- bool useParams,
- unsigned int flags)
-{
- virDomainPtr ddomain = NULL;
- char *uri_out = NULL;
- char *cookiein = NULL;
- char *cookieout = NULL;
- char *dom_xml = NULL;
- int cookieinlen = 0;
- int cookieoutlen = 0;
- int ret;
- virDomainInfo info;
- virErrorPtr orig_err = NULL;
- int cancelled = 1;
- unsigned long protection = 0;
- bool notify_source = true;
- unsigned int destflags;
- int state;
- virTypedParameterPtr tmp;
-
- VIR_DOMAIN_DEBUG(domain,
- "dconn=%p, xmlin=%s, dname=%s, uri=%s, bandwidth=%llu, "
- "params=%p, nparams=%d, useParams=%d, flags=%x",
- dconn, NULLSTR(xmlin), NULLSTR(dname), NULLSTR(uri),
- bandwidth, params, nparams, useParams, flags);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- if ((!useParams &&
- (!domain->conn->driver->domainMigrateBegin3 ||
- !domain->conn->driver->domainMigratePerform3 ||
- !domain->conn->driver->domainMigrateConfirm3 ||
- !dconn->driver->domainMigratePrepare3 ||
- !dconn->driver->domainMigrateFinish3)) ||
- (useParams &&
- (!domain->conn->driver->domainMigrateBegin3Params ||
- !domain->conn->driver->domainMigratePerform3Params ||
- !domain->conn->driver->domainMigrateConfirm3Params ||
- !dconn->driver->domainMigratePrepare3Params ||
- !dconn->driver->domainMigrateFinish3Params))) {
- virReportUnsupportedError();
- return NULL;
- }
-
- if (virTypedParamsCopy(&tmp, params, nparams) < 0)
- return NULL;
- params = tmp;
-
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION))
- protection = VIR_MIGRATE_CHANGE_PROTECTION;
-
- VIR_DEBUG("Begin3 %p", domain->conn);
- if (useParams) {
- dom_xml = domain->conn->driver->domainMigrateBegin3Params
- (domain, params, nparams, &cookieout, &cookieoutlen,
- flags | protection);
- } else {
- dom_xml = domain->conn->driver->domainMigrateBegin3
- (domain, xmlin, &cookieout, &cookieoutlen,
- flags | protection, dname, bandwidth);
- }
- if (!dom_xml)
- goto done;
-
- if (useParams) {
- /* If source is new enough to support extensible migration parameters,
- * it's certainly new enough to support virDomainGetState. */
- ret = virDomainGetState(domain, &state, NULL, 0);
- } else {
- ret = virDomainGetInfo(domain, &info);
- state = info.state;
- }
- if (ret == 0 && state == VIR_DOMAIN_PAUSED)
- flags |= VIR_MIGRATE_PAUSED;
-
- destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR |
- VIR_MIGRATE_AUTO_CONVERGE);
-
- VIR_DEBUG("Prepare3 %p flags=%x", dconn, destflags);
- cookiein = cookieout;
- cookieinlen = cookieoutlen;
- cookieout = NULL;
- cookieoutlen = 0;
- if (useParams) {
- if (virTypedParamsReplaceString(¶ms, &nparams,
- VIR_MIGRATE_PARAM_DEST_XML,
- dom_xml) < 0)
- goto done;
- ret = dconn->driver->domainMigratePrepare3Params
- (dconn, params, nparams, cookiein, cookieinlen,
- &cookieout, &cookieoutlen, &uri_out, destflags);
- } else {
- ret = dconn->driver->domainMigratePrepare3
- (dconn, cookiein, cookieinlen, &cookieout, &cookieoutlen,
- uri, &uri_out, destflags, dname, bandwidth, dom_xml);
- }
- if (ret == -1) {
- if (protection) {
- /* Begin already started a migration job so we need to cancel it by
- * calling Confirm while making sure it doesn't overwrite the error
- */
- orig_err = virSaveLastError();
- goto confirm;
- } else {
- goto done;
- }
- }
-
- /* Did domainMigratePrepare3 change URI? */
- if (uri_out) {
- uri = uri_out;
- if (useParams &&
- virTypedParamsReplaceString(¶ms, &nparams,
- VIR_MIGRATE_PARAM_URI,
- uri_out) < 0) {
- cancelled = 1;
- orig_err = virSaveLastError();
- goto finish;
- }
- } else if (!uri &&
- virTypedParamsGetString(params, nparams,
- VIR_MIGRATE_PARAM_URI, &uri) <= 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("domainMigratePrepare3 did not set uri"));
- cancelled = 1;
- orig_err = virSaveLastError();
- goto finish;
- }
-
- if (flags & VIR_MIGRATE_OFFLINE) {
- VIR_DEBUG("Offline migration, skipping Perform phase");
- VIR_FREE(cookieout);
- cookieoutlen = 0;
- cancelled = 0;
- goto finish;
- }
-
- /* Perform the migration. The driver isn't supposed to return
- * until the migration is complete. The src VM should remain
- * running, but in paused state until the destination can
- * confirm migration completion.
- */
- VIR_DEBUG("Perform3 %p uri=%s", domain->conn, uri);
- VIR_FREE(cookiein);
- cookiein = cookieout;
- cookieinlen = cookieoutlen;
- cookieout = NULL;
- cookieoutlen = 0;
- /* dconnuri not relevant in non-P2P modes, so left NULL here */
- if (useParams) {
- ret = domain->conn->driver->domainMigratePerform3Params
- (domain, NULL, params, nparams, cookiein, cookieinlen,
- &cookieout, &cookieoutlen, flags | protection);
- } else {
- ret = domain->conn->driver->domainMigratePerform3
- (domain, NULL, cookiein, cookieinlen,
- &cookieout, &cookieoutlen, NULL,
- uri, flags | protection, dname, bandwidth);
- }
-
- /* Perform failed. Make sure Finish doesn't overwrite the error */
- if (ret < 0) {
- orig_err = virSaveLastError();
- /* Perform failed so we don't need to call confirm to let source know
- * about the failure.
- */
- notify_source = false;
- }
-
- /* If Perform returns < 0, then we need to cancel the VM
- * startup on the destination
- */
- cancelled = ret < 0 ? 1 : 0;
-
- finish:
- /*
- * The status code from the source is passed to the destination.
- * The dest can cleanup if the source indicated it failed to
- * send all migration data. Returns NULL for ddomain if
- * the dest was unable to complete migration.
- */
- VIR_DEBUG("Finish3 %p ret=%d", dconn, ret);
- VIR_FREE(cookiein);
- cookiein = cookieout;
- cookieinlen = cookieoutlen;
- cookieout = NULL;
- cookieoutlen = 0;
- if (useParams) {
- if (virTypedParamsGetString(params, nparams,
- VIR_MIGRATE_PARAM_DEST_NAME, NULL) <= 0
&&
- virTypedParamsReplaceString(¶ms, &nparams,
- VIR_MIGRATE_PARAM_DEST_NAME,
- domain->name) < 0) {
- ddomain = NULL;
- } else {
- ddomain = dconn->driver->domainMigrateFinish3Params
- (dconn, params, nparams, cookiein, cookieinlen,
- &cookieout, &cookieoutlen, destflags, cancelled);
- }
- } else {
- dname = dname ? dname : domain->name;
- ddomain = dconn->driver->domainMigrateFinish3
- (dconn, dname, cookiein, cookieinlen, &cookieout, &cookieoutlen,
- NULL, uri, destflags, cancelled);
- }
- if (cancelled && ddomain)
- VIR_ERROR(_("finish step ignored that migration was cancelled"));
-
- /* If ddomain is NULL, then we were unable to start
- * the guest on the target, and must restart on the
- * source. There is a small chance that the ddomain
- * is NULL due to an RPC failure, in which case
- * ddomain could in fact be running on the dest.
- * The lock manager plugins should take care of
- * safety in this scenario.
- */
- cancelled = ddomain == NULL ? 1 : 0;
-
- /* If finish3 set an error, and we don't have an earlier
- * one we need to preserve it in case confirm3 overwrites
- */
- if (!orig_err)
- orig_err = virSaveLastError();
-
- confirm:
- /*
- * If cancelled, then src VM will be restarted, else it will be killed.
- * Don't do this if migration failed on source and thus it was already
- * cancelled there.
- */
- if (notify_source) {
- VIR_DEBUG("Confirm3 %p ret=%d domain=%p", domain->conn, ret,
domain);
- VIR_FREE(cookiein);
- cookiein = cookieout;
- cookieinlen = cookieoutlen;
- cookieout = NULL;
- cookieoutlen = 0;
- if (useParams) {
- ret = domain->conn->driver->domainMigrateConfirm3Params
- (domain, params, nparams, cookiein, cookieinlen,
- flags | protection, cancelled);
- } else {
- ret = domain->conn->driver->domainMigrateConfirm3
- (domain, cookiein, cookieinlen,
- flags | protection, cancelled);
- }
- /* If Confirm3 returns -1, there's nothing more we can
- * do, but fortunately worst case is that there is a
- * domain left in 'paused' state on source.
- */
- if (ret < 0) {
- VIR_WARN("Guest %s probably left in 'paused' state on
source",
- domain->name);
- }
- }
-
- done:
- if (orig_err) {
- virSetError(orig_err);
- virFreeError(orig_err);
- }
- VIR_FREE(dom_xml);
- VIR_FREE(uri_out);
- VIR_FREE(cookiein);
- VIR_FREE(cookieout);
- virTypedParamsFree(params, nparams);
- return ddomain;
-}
-
-
-static virDomainPtr
-virDomainMigrateVersion3(virDomainPtr domain,
- virConnectPtr dconn,
- const char *xmlin,
- unsigned long flags,
- const char *dname,
- const char *uri,
- unsigned long bandwidth)
-{
- return virDomainMigrateVersion3Full(domain, dconn, xmlin, dname, uri,
- bandwidth, NULL, 0, false, flags);
-}
-
-
-static virDomainPtr
-virDomainMigrateVersion3Params(virDomainPtr domain,
- virConnectPtr dconn,
- virTypedParameterPtr params,
- int nparams,
- unsigned int flags)
-{
- return virDomainMigrateVersion3Full(domain, dconn, NULL, NULL, NULL, 0,
- params, nparams, true, flags);
-}
-
-
-/*
- * In normal migration, the libvirt client co-ordinates communication
- * between the 2 libvirtd instances on source & dest hosts.
- *
- * In this peer-2-peer migration alternative, the libvirt client
- * only talks to the source libvirtd instance. The source libvirtd
- * then opens its own connection to the destination and co-ordinates
- * migration itself.
- *
- * If useParams is true, params and nparams contain migration parameters and
- * we know it's safe to call the API which supports extensible parameters.
- * Otherwise, we have to use xmlin, dname, uri, and bandwidth and pass them
- * to the old-style APIs.
- */
-static int
-virDomainMigratePeer2PeerFull(virDomainPtr domain,
- const char *dconnuri,
- const char *xmlin,
- const char *dname,
- const char *uri,
- unsigned long long bandwidth,
- virTypedParameterPtr params,
- int nparams,
- bool useParams,
- unsigned int flags)
-{
- virURIPtr tempuri = NULL;
-
- VIR_DOMAIN_DEBUG(domain,
- "dconnuri=%s, xmlin=%s, dname=%s, uri=%s, bandwidth=%llu
"
- "params=%p, nparams=%d, useParams=%d, flags=%x",
- dconnuri, NULLSTR(xmlin), NULLSTR(dname), NULLSTR(uri),
- bandwidth, params, nparams, useParams, flags);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- if ((useParams &&
!domain->conn->driver->domainMigratePerform3Params) ||
- (!useParams &&
- !domain->conn->driver->domainMigratePerform &&
- !domain->conn->driver->domainMigratePerform3)) {
- virReportUnsupportedError();
- return -1;
- }
-
- if (!(tempuri = virURIParse(dconnuri)))
- return -1;
- if (!tempuri->server || STRPREFIX(tempuri->server, "localhost")) {
- virReportInvalidArg(dconnuri,
- _("unable to parse server from dconnuri in %s"),
- __FUNCTION__);
- virURIFree(tempuri);
- return -1;
- }
- virURIFree(tempuri);
-
- if (useParams) {
- VIR_DEBUG("Using migration protocol 3 with extensible parameters");
- return domain->conn->driver->domainMigratePerform3Params
- (domain, dconnuri, params, nparams,
- NULL, 0, NULL, NULL, flags);
- } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_V3)) {
- VIR_DEBUG("Using migration protocol 3");
- return domain->conn->driver->domainMigratePerform3
- (domain, xmlin, NULL, 0, NULL, NULL, dconnuri,
- uri, flags, dname, bandwidth);
- } else {
- VIR_DEBUG("Using migration protocol 2");
- if (xmlin) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("Unable to change target guest XML during "
- "migration"));
- return -1;
- }
- if (uri) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Unable to override peer2peer migration URI"));
- return -1;
- }
- return domain->conn->driver->domainMigratePerform
- (domain, NULL, 0, dconnuri, flags, dname, bandwidth);
- }
-}
-
-
-static int
-virDomainMigratePeer2Peer(virDomainPtr domain,
- const char *xmlin,
- unsigned long flags,
- const char *dname,
- const char *dconnuri,
- const char *uri,
- unsigned long bandwidth)
-{
- return virDomainMigratePeer2PeerFull(domain, dconnuri, xmlin, dname, uri,
- bandwidth, NULL, 0, false, flags);
-}
-
-
-static int
-virDomainMigratePeer2PeerParams(virDomainPtr domain,
- const char *dconnuri,
- virTypedParameterPtr params,
- int nparams,
- unsigned int flags)
-{
- return virDomainMigratePeer2PeerFull(domain, dconnuri, NULL, NULL, NULL, 0,
- params, nparams, true, flags);
-}
-
-
-/*
- * In normal migration, the libvirt client co-ordinates communication
- * between the 2 libvirtd instances on source & dest hosts.
- *
- * Some hypervisors support an alternative, direct migration where
- * there is no requirement for a libvirtd instance on the dest host.
- * In this case
- *
- * eg, XenD can talk direct to XenD, so libvirtd on dest does not
- * need to be involved at all, or even running
- */
-static int
-virDomainMigrateDirect(virDomainPtr domain,
- const char *xmlin,
- unsigned long flags,
- const char *dname,
- const char *uri,
- unsigned long bandwidth)
-{
- VIR_DOMAIN_DEBUG(domain,
- "xmlin=%s, flags=%lx, dname=%s, uri=%s, bandwidth=%lu",
- NULLSTR(xmlin), flags, NULLSTR(dname), NULLSTR(uri),
- bandwidth);
-
- if (!domain->conn->driver->domainMigratePerform) {
- virReportUnsupportedError();
- return -1;
- }
-
- /* Perform the migration. The driver isn't supposed to return
- * until the migration is complete.
- */
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_V3)) {
- VIR_DEBUG("Using migration protocol 3");
- /* dconn URI not relevant in direct migration, since no
- * target libvirtd is involved */
- return domain->conn->driver->domainMigratePerform3(domain,
- xmlin,
- NULL, /* cookiein */
- 0, /* cookieinlen */
- NULL, /* cookieoutlen */
- NULL, /* cookieoutlen */
- NULL, /* dconnuri */
- uri,
- flags,
- dname,
- bandwidth);
- } else {
- VIR_DEBUG("Using migration protocol 2");
- if (xmlin) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("Unable to change target guest XML during
migration"));
- return -1;
- }
- return domain->conn->driver->domainMigratePerform(domain,
- NULL, /* cookie */
- 0, /* cookielen */
- uri,
- flags,
- dname,
- bandwidth);
- }
-}
-
-
-/**
- * virDomainMigrate:
- * @domain: a domain object
- * @dconn: destination host (a connection object)
- * @flags: bitwise-OR of virDomainMigrateFlags
- * @dname: (optional) rename domain to this at destination
- * @uri: (optional) dest hostname/URI as seen from the source host
- * @bandwidth: (optional) specify migration bandwidth limit in MiB/s
- *
- * Migrate the domain object from its current host to the destination
- * host given by dconn (a connection to the destination host).
- *
- * Flags may be one of more of the following:
- * VIR_MIGRATE_LIVE Do not pause the VM during migration
- * VIR_MIGRATE_PEER2PEER Direct connection between source & destination hosts
- * VIR_MIGRATE_TUNNELLED Tunnel migration data over the libvirt RPC channel
- * VIR_MIGRATE_PERSIST_DEST If the migration is successful, persist the domain
- * on the destination host.
- * VIR_MIGRATE_UNDEFINE_SOURCE If the migration is successful, undefine the
- * domain on the source host.
- * VIR_MIGRATE_PAUSED Leave the domain suspended on the remote side.
- * VIR_MIGRATE_NON_SHARED_DISK Migration with non-shared storage with full
- * disk copy
- * VIR_MIGRATE_NON_SHARED_INC Migration with non-shared storage with
- * incremental disk copy
- * VIR_MIGRATE_CHANGE_PROTECTION Protect against domain configuration
- * changes during the migration process (set
- * automatically when supported).
- * VIR_MIGRATE_UNSAFE Force migration even if it is considered unsafe.
- * VIR_MIGRATE_OFFLINE Migrate offline
- *
- * VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set.
- * Applications using the VIR_MIGRATE_PEER2PEER flag will probably
- * prefer to invoke virDomainMigrateToURI, avoiding the need to
- * open connection to the destination host themselves.
- *
- * If a hypervisor supports renaming domains during migration,
- * then you may set the dname parameter to the new name (otherwise
- * it keeps the same name). If this is not supported by the
- * hypervisor, dname must be NULL or else you will get an error.
- *
- * If the VIR_MIGRATE_PEER2PEER flag is set, the uri parameter
- * must be a valid libvirt connection URI, by which the source
- * libvirt driver can connect to the destination libvirt. If
- * omitted, the dconn connection object will be queried for its
- * current URI.
- *
- * If the VIR_MIGRATE_PEER2PEER flag is NOT set, the URI parameter
- * takes a hypervisor specific format. The hypervisor capabilities
- * XML includes details of the support URI schemes. If omitted
- * the dconn will be asked for a default URI.
- *
- * If you want to copy non-shared storage within migration you
- * can use either VIR_MIGRATE_NON_SHARED_DISK or
- * VIR_MIGRATE_NON_SHARED_INC as they are mutually exclusive.
- *
- * In either case it is typically only necessary to specify a
- * URI if the destination host has multiple interfaces and a
- * specific interface is required to transmit migration data.
- *
- * The maximum bandwidth (in MiB/s) that will be used to do migration
- * can be specified with the bandwidth parameter. If set to 0,
- * libvirt will choose a suitable default. Some hypervisors do
- * not support this feature and will return an error if bandwidth
- * is not 0.
- *
- * To see which features are supported by the current hypervisor,
- * see virConnectGetCapabilities, /capabilities/host/migration_features.
- *
- * There are many limitations on migration imposed by the underlying
- * technology - for example it may not be possible to migrate between
- * different processors even with the same architecture, or between
- * different types of hypervisor.
- *
- * virDomainFree should be used to free the resources after the
- * returned domain object is no longer needed.
- *
- * Returns the new domain object if the migration was successful,
- * or NULL in case of error. Note that the new domain object
- * exists in the scope of the destination connection (dconn).
- */
-virDomainPtr
-virDomainMigrate(virDomainPtr domain,
- virConnectPtr dconn,
- unsigned long flags,
- const char *dname,
- const char *uri,
- unsigned long bandwidth)
-{
- virDomainPtr ddomain = NULL;
-
- VIR_DOMAIN_DEBUG(domain,
- "dconn=%p, flags=%lx, dname=%s, uri=%s, bandwidth=%lu",
- dconn, flags, NULLSTR(dname), NULLSTR(uri), bandwidth);
-
- virResetLastError();
-
- /* First checkout the source */
- virCheckDomainReturn(domain, NULL);
- virCheckReadOnlyGoto(domain->conn->flags, error);
-
- /* Now checkout the destination */
- virCheckConnectGoto(dconn, error);
- virCheckReadOnlyGoto(dconn->flags, error);
-
- if (flags & VIR_MIGRATE_NON_SHARED_DISK &&
- flags & VIR_MIGRATE_NON_SHARED_INC) {
- virReportInvalidArg(flags,
- _("flags 'shared disk' and 'shared
incremental' "
- "in %s are mutually exclusive"),
- __FUNCTION__);
- goto error;
- }
-
- if (flags & VIR_MIGRATE_OFFLINE) {
- if (!VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("offline migration is not supported by "
- "the source host"));
- goto error;
- }
- if (!VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
- VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("offline migration is not supported by "
- "the destination host"));
- goto error;
- }
- }
-
- if (flags & VIR_MIGRATE_PEER2PEER) {
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_P2P)) {
- char *dstURI = NULL;
- if (uri == NULL) {
- dstURI = virConnectGetURI(dconn);
- if (!dstURI)
- return NULL;
- }
-
- VIR_DEBUG("Using peer2peer migration");
- if (virDomainMigratePeer2Peer(domain, NULL, flags, dname,
- uri ? uri : dstURI, NULL, bandwidth) < 0) {
- VIR_FREE(dstURI);
- goto error;
- }
- VIR_FREE(dstURI);
-
- ddomain = virDomainLookupByName(dconn, dname ? dname : domain->name);
- } else {
- /* This driver does not support peer to peer migration */
- virReportUnsupportedError();
- goto error;
- }
- } else {
- /* Change protection requires support only on source side, and
- * is only needed in v3 migration, which automatically re-adds
- * the flag for just the source side. We mask it out for
- * non-peer2peer to allow migration from newer source to an
- * older destination that rejects the flag. */
- if (flags & VIR_MIGRATE_CHANGE_PROTECTION &&
- !VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION)) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("cannot enforce change protection"));
- goto error;
- }
- flags &= ~VIR_MIGRATE_CHANGE_PROTECTION;
- if (flags & VIR_MIGRATE_TUNNELLED) {
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("cannot perform tunnelled migration without using
peer2peer flag"));
- goto error;
- }
-
- /* Check that migration is supported by both drivers. */
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_V3) &&
- VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
- VIR_DRV_FEATURE_MIGRATION_V3)) {
- VIR_DEBUG("Using migration protocol 3");
- ddomain = virDomainMigrateVersion3(domain, dconn, NULL,
- flags, dname, uri, bandwidth);
- } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_V2) &&
- VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
- VIR_DRV_FEATURE_MIGRATION_V2)) {
- VIR_DEBUG("Using migration protocol 2");
- ddomain = virDomainMigrateVersion2(domain, dconn, flags,
- dname, uri, bandwidth);
- } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_V1) &&
- VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
- VIR_DRV_FEATURE_MIGRATION_V1)) {
- VIR_DEBUG("Using migration protocol 1");
- ddomain = virDomainMigrateVersion1(domain, dconn, flags,
- dname, uri, bandwidth);
- } else {
- /* This driver does not support any migration method */
- virReportUnsupportedError();
- goto error;
- }
- }
-
- if (ddomain == NULL)
- goto error;
-
- return ddomain;
-
- error:
- virDispatchError(domain->conn);
- return NULL;
-}
-
-
-/**
- * virDomainMigrate2:
- * @domain: a domain object
- * @dconn: destination host (a connection object)
- * @flags: bitwise-OR of virDomainMigrateFlags
- * @dxml: (optional) XML config for launching guest on target
- * @dname: (optional) rename domain to this at destination
- * @uri: (optional) dest hostname/URI as seen from the source host
- * @bandwidth: (optional) specify migration bandwidth limit in MiB/s
- *
- * Migrate the domain object from its current host to the destination
- * host given by dconn (a connection to the destination host).
- *
- * Flags may be one of more of the following:
- * VIR_MIGRATE_LIVE Do not pause the VM during migration
- * VIR_MIGRATE_PEER2PEER Direct connection between source & destination hosts
- * VIR_MIGRATE_TUNNELLED Tunnel migration data over the libvirt RPC channel
- * VIR_MIGRATE_PERSIST_DEST If the migration is successful, persist the domain
- * on the destination host.
- * VIR_MIGRATE_UNDEFINE_SOURCE If the migration is successful, undefine the
- * domain on the source host.
- * VIR_MIGRATE_PAUSED Leave the domain suspended on the remote side.
- * VIR_MIGRATE_NON_SHARED_DISK Migration with non-shared storage with full
- * disk copy
- * VIR_MIGRATE_NON_SHARED_INC Migration with non-shared storage with
- * incremental disk copy
- * VIR_MIGRATE_CHANGE_PROTECTION Protect against domain configuration
- * changes during the migration process (set
- * automatically when supported).
- * VIR_MIGRATE_UNSAFE Force migration even if it is considered unsafe.
- * VIR_MIGRATE_OFFLINE Migrate offline
- *
- * VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set.
- * Applications using the VIR_MIGRATE_PEER2PEER flag will probably
- * prefer to invoke virDomainMigrateToURI, avoiding the need to
- * open connection to the destination host themselves.
- *
- * If a hypervisor supports renaming domains during migration,
- * then you may set the dname parameter to the new name (otherwise
- * it keeps the same name). If this is not supported by the
- * hypervisor, dname must be NULL or else you will get an error.
- *
- * If the VIR_MIGRATE_PEER2PEER flag is set, the uri parameter
- * must be a valid libvirt connection URI, by which the source
- * libvirt driver can connect to the destination libvirt. If
- * omitted, the dconn connection object will be queried for its
- * current URI.
- *
- * If the VIR_MIGRATE_PEER2PEER flag is NOT set, the URI parameter
- * takes a hypervisor specific format. The hypervisor capabilities
- * XML includes details of the support URI schemes. If omitted
- * the dconn will be asked for a default URI.
- *
- * If you want to copy non-shared storage within migration you
- * can use either VIR_MIGRATE_NON_SHARED_DISK or
- * VIR_MIGRATE_NON_SHARED_INC as they are mutually exclusive.
- *
- * In either case it is typically only necessary to specify a
- * URI if the destination host has multiple interfaces and a
- * specific interface is required to transmit migration data.
- *
- * The maximum bandwidth (in MiB/s) that will be used to do migration
- * can be specified with the bandwidth parameter. If set to 0,
- * libvirt will choose a suitable default. Some hypervisors do
- * not support this feature and will return an error if bandwidth
- * is not 0.
- *
- * To see which features are supported by the current hypervisor,
- * see virConnectGetCapabilities, /capabilities/host/migration_features.
- *
- * There are many limitations on migration imposed by the underlying
- * technology - for example it may not be possible to migrate between
- * different processors even with the same architecture, or between
- * different types of hypervisor.
- *
- * If the hypervisor supports it, @dxml can be used to alter
- * host-specific portions of the domain XML that will be used on
- * the destination. For example, it is possible to alter the
- * backing filename that is associated with a disk device, in order
- * to account for naming differences between source and destination
- * in accessing the underlying storage. The migration will fail
- * if @dxml would cause any guest-visible changes. Pass NULL
- * if no changes are needed to the XML between source and destination.
- * @dxml cannot be used to rename the domain during migration (use
- * @dname for that purpose). Domain name in @dxml must match the
- * original domain name.
- *
- * virDomainFree should be used to free the resources after the
- * returned domain object is no longer needed.
- *
- * Returns the new domain object if the migration was successful,
- * or NULL in case of error. Note that the new domain object
- * exists in the scope of the destination connection (dconn).
- */
-virDomainPtr
-virDomainMigrate2(virDomainPtr domain,
- virConnectPtr dconn,
- const char *dxml,
- unsigned long flags,
- const char *dname,
- const char *uri,
- unsigned long bandwidth)
-{
- virDomainPtr ddomain = NULL;
-
- VIR_DOMAIN_DEBUG(domain,
- "dconn=%p, flags=%lx, dname=%s, uri=%s, bandwidth=%lu",
- dconn, flags, NULLSTR(dname), NULLSTR(uri), bandwidth);
-
- virResetLastError();
-
- /* First checkout the source */
- virCheckDomainReturn(domain, NULL);
- virCheckReadOnlyGoto(domain->conn->flags, error);
-
- /* Now checkout the destination */
- virCheckConnectGoto(dconn, error);
- virCheckReadOnlyGoto(dconn->flags, error);
-
- if (flags & VIR_MIGRATE_NON_SHARED_DISK &&
- flags & VIR_MIGRATE_NON_SHARED_INC) {
- virReportInvalidArg(flags,
- _("flags 'shared disk' and 'shared
incremental' "
- "in %s are mutually exclusive"),
- __FUNCTION__);
- goto error;
- }
-
- if (flags & VIR_MIGRATE_OFFLINE) {
- if (!VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("offline migration is not supported by "
- "the source host"));
- goto error;
- }
- if (!VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
- VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("offline migration is not supported by "
- "the destination host"));
- goto error;
- }
- }
-
- if (flags & VIR_MIGRATE_PEER2PEER) {
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_P2P)) {
- char *dstURI = virConnectGetURI(dconn);
- if (!dstURI)
- return NULL;
-
- VIR_DEBUG("Using peer2peer migration");
- if (virDomainMigratePeer2Peer(domain, dxml, flags, dname,
- dstURI, uri, bandwidth) < 0) {
- VIR_FREE(dstURI);
- goto error;
- }
- VIR_FREE(dstURI);
-
- ddomain = virDomainLookupByName(dconn, dname ? dname : domain->name);
- } else {
- /* This driver does not support peer to peer migration */
- virReportUnsupportedError();
- goto error;
- }
- } else {
- /* Change protection requires support only on source side, and
- * is only needed in v3 migration, which automatically re-adds
- * the flag for just the source side. We mask it out for
- * non-peer2peer to allow migration from newer source to an
- * older destination that rejects the flag. */
- if (flags & VIR_MIGRATE_CHANGE_PROTECTION &&
- !VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION)) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("cannot enforce change protection"));
- goto error;
- }
- flags &= ~VIR_MIGRATE_CHANGE_PROTECTION;
- if (flags & VIR_MIGRATE_TUNNELLED) {
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("cannot perform tunnelled migration without using
peer2peer flag"));
- goto error;
- }
-
- /* Check that migration is supported by both drivers. */
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_V3) &&
- VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
- VIR_DRV_FEATURE_MIGRATION_V3)) {
- VIR_DEBUG("Using migration protocol 3");
- ddomain = virDomainMigrateVersion3(domain, dconn, dxml,
- flags, dname, uri, bandwidth);
- } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_V2) &&
- VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
- VIR_DRV_FEATURE_MIGRATION_V2)) {
- VIR_DEBUG("Using migration protocol 2");
- if (dxml) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("Unable to change target guest XML during
migration"));
- goto error;
- }
- ddomain = virDomainMigrateVersion2(domain, dconn, flags,
- dname, uri, bandwidth);
- } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_V1) &&
- VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
- VIR_DRV_FEATURE_MIGRATION_V1)) {
- VIR_DEBUG("Using migration protocol 1");
- if (dxml) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("Unable to change target guest XML during
migration"));
- goto error;
- }
- ddomain = virDomainMigrateVersion1(domain, dconn, flags,
- dname, uri, bandwidth);
- } else {
- /* This driver does not support any migration method */
- virReportUnsupportedError();
- goto error;
- }
- }
-
- if (ddomain == NULL)
- goto error;
-
- return ddomain;
-
- error:
- virDispatchError(domain->conn);
- return NULL;
-}
-
-
-/**
- * virDomainMigrate3:
- * @domain: a domain object
- * @dconn: destination host (a connection object)
- * @params: (optional) migration parameters
- * @nparams: (optional) number of migration parameters in @params
- * @flags: bitwise-OR of virDomainMigrateFlags
- *
- * Migrate the domain object from its current host to the destination host
- * given by dconn (a connection to the destination host).
- *
- * See virDomainMigrateFlags documentation for description of individual flags.
- *
- * VIR_MIGRATE_TUNNELLED and VIR_MIGRATE_PEER2PEER are not supported by this
- * API, use virDomainMigrateToURI3 instead.
- *
- * If you want to copy non-shared storage within migration you
- * can use either VIR_MIGRATE_NON_SHARED_DISK or
- * VIR_MIGRATE_NON_SHARED_INC as they are mutually exclusive.
- *
- * There are many limitations on migration imposed by the underlying
- * technology - for example it may not be possible to migrate between
- * different processors even with the same architecture, or between
- * different types of hypervisor.
- *
- * virDomainFree should be used to free the resources after the
- * returned domain object is no longer needed.
- *
- * Returns the new domain object if the migration was successful,
- * or NULL in case of error. Note that the new domain object
- * exists in the scope of the destination connection (dconn).
- */
-virDomainPtr
-virDomainMigrate3(virDomainPtr domain,
- virConnectPtr dconn,
- virTypedParameterPtr params,
- unsigned int nparams,
- unsigned int flags)
-{
- virDomainPtr ddomain = NULL;
- const char *compatParams[] = { VIR_MIGRATE_PARAM_URI,
- VIR_MIGRATE_PARAM_DEST_NAME,
- VIR_MIGRATE_PARAM_DEST_XML,
- VIR_MIGRATE_PARAM_BANDWIDTH };
- const char *uri = NULL;
- const char *dname = NULL;
- const char *dxml = NULL;
- unsigned long long bandwidth = 0;
-
- VIR_DOMAIN_DEBUG(domain, "dconn=%p, params=%p, nparms=%u flags=%x",
- dconn, params, nparams, flags);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- /* First checkout the source */
- virCheckDomainReturn(domain, NULL);
- virCheckReadOnlyGoto(domain->conn->flags, error);
-
- /* Now checkout the destination */
- virCheckConnectGoto(dconn, error);
- virCheckReadOnlyGoto(dconn->flags, error);
-
- if (flags & VIR_MIGRATE_NON_SHARED_DISK &&
- flags & VIR_MIGRATE_NON_SHARED_INC) {
- virReportInvalidArg(flags,
- _("flags 'shared disk' and 'shared
incremental' "
- "in %s are mutually exclusive"),
- __FUNCTION__);
- goto error;
- }
- if (flags & VIR_MIGRATE_PEER2PEER) {
- virReportInvalidArg(flags, "%s",
- _("use virDomainMigrateToURI3 for peer-to-peer "
- "migration"));
- goto error;
- }
- if (flags & VIR_MIGRATE_TUNNELLED) {
- virReportInvalidArg(flags, "%s",
- _("cannot perform tunnelled migration "
- "without using peer2peer flag"));
- goto error;
- }
-
- if (flags & VIR_MIGRATE_OFFLINE) {
- if (!VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("offline migration is not supported by "
- "the source host"));
- goto error;
- }
- if (!VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
- VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("offline migration is not supported by "
- "the destination host"));
- goto error;
- }
- }
-
- /* Change protection requires support only on source side, and
- * is only needed in v3 migration, which automatically re-adds
- * the flag for just the source side. We mask it out to allow
- * migration from newer source to an older destination that
- * rejects the flag. */
- if (flags & VIR_MIGRATE_CHANGE_PROTECTION &&
- !VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION)) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("cannot enforce change protection"));
- goto error;
- }
- flags &= ~VIR_MIGRATE_CHANGE_PROTECTION;
-
- /* Prefer extensible API but fall back to older migration APIs if params
- * only contains parameters which were supported by the older API. */
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_PARAMS) &&
- VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
- VIR_DRV_FEATURE_MIGRATION_PARAMS)) {
- VIR_DEBUG("Using migration protocol 3 with extensible parameters");
- ddomain = virDomainMigrateVersion3Params(domain, dconn, params,
- nparams, flags);
- goto done;
- }
-
- if (!virTypedParamsCheck(params, nparams, compatParams,
- ARRAY_CARDINALITY(compatParams))) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("Migration APIs with extensible parameters are not "
- "supported but extended parameters were passed"));
- goto error;
- }
-
- if (virTypedParamsGetString(params, nparams,
- VIR_MIGRATE_PARAM_URI, &uri) < 0 ||
- virTypedParamsGetString(params, nparams,
- VIR_MIGRATE_PARAM_DEST_NAME, &dname) < 0 ||
- virTypedParamsGetString(params, nparams,
- VIR_MIGRATE_PARAM_DEST_XML, &dxml) < 0 ||
- virTypedParamsGetULLong(params, nparams,
- VIR_MIGRATE_PARAM_BANDWIDTH, &bandwidth) < 0) {
- goto error;
- }
-
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_V3) &&
- VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
- VIR_DRV_FEATURE_MIGRATION_V3)) {
- VIR_DEBUG("Using migration protocol 3");
- ddomain = virDomainMigrateVersion3(domain, dconn, dxml, flags,
- dname, uri, bandwidth);
- } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_V2) &&
- VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
- VIR_DRV_FEATURE_MIGRATION_V2)) {
- VIR_DEBUG("Using migration protocol 2");
- if (dxml) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("Unable to change target guest XML during "
- "migration"));
- goto error;
- }
- ddomain = virDomainMigrateVersion2(domain, dconn, flags,
- dname, uri, bandwidth);
- } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_V1) &&
- VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
- VIR_DRV_FEATURE_MIGRATION_V1)) {
- VIR_DEBUG("Using migration protocol 1");
- if (dxml) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("Unable to change target guest XML during "
- "migration"));
- goto error;
- }
- ddomain = virDomainMigrateVersion1(domain, dconn, flags,
- dname, uri, bandwidth);
- } else {
- /* This driver does not support any migration method */
- virReportUnsupportedError();
- goto error;
- }
-
- done:
- if (ddomain == NULL)
- goto error;
-
- return ddomain;
-
- error:
- virDispatchError(domain->conn);
- return NULL;
-}
-
-
-/**
- * virDomainMigrateToURI:
- * @domain: a domain object
- * @duri: mandatory URI for the destination host
- * @flags: bitwise-OR of virDomainMigrateFlags
- * @dname: (optional) rename domain to this at destination
- * @bandwidth: (optional) specify migration bandwidth limit in MiB/s
- *
- * Migrate the domain object from its current host to the destination
- * host given by duri.
- *
- * Flags may be one of more of the following:
- * VIR_MIGRATE_LIVE Do not pause the VM during migration
- * VIR_MIGRATE_PEER2PEER Direct connection between source & destination hosts
- * VIR_MIGRATE_TUNNELLED Tunnel migration data over the libvirt RPC channel
- * VIR_MIGRATE_PERSIST_DEST If the migration is successful, persist the domain
- * on the destination host.
- * VIR_MIGRATE_UNDEFINE_SOURCE If the migration is successful, undefine the
- * domain on the source host.
- * VIR_MIGRATE_PAUSED Leave the domain suspended on the remote side.
- * VIR_MIGRATE_NON_SHARED_DISK Migration with non-shared storage with full
- * disk copy
- * VIR_MIGRATE_NON_SHARED_INC Migration with non-shared storage with
- * incremental disk copy
- * VIR_MIGRATE_CHANGE_PROTECTION Protect against domain configuration
- * changes during the migration process (set
- * automatically when supported).
- * VIR_MIGRATE_UNSAFE Force migration even if it is considered unsafe.
- * VIR_MIGRATE_OFFLINE Migrate offline
- *
- * The operation of this API hinges on the VIR_MIGRATE_PEER2PEER flag.
- * If the VIR_MIGRATE_PEER2PEER flag is NOT set, the duri parameter
- * takes a hypervisor specific format. The uri_transports element of the
- * hypervisor capabilities XML includes details of the supported URI
- * schemes. Not all hypervisors will support this mode of migration, so
- * if the VIR_MIGRATE_PEER2PEER flag is not set, then it may be necessary
- * to use the alternative virDomainMigrate API providing and explicit
- * virConnectPtr for the destination host.
- *
- * If the VIR_MIGRATE_PEER2PEER flag IS set, the duri parameter
- * must be a valid libvirt connection URI, by which the source
- * libvirt driver can connect to the destination libvirt.
- *
- * VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set.
- *
- * If you want to copy non-shared storage within migration you
- * can use either VIR_MIGRATE_NON_SHARED_DISK or
- * VIR_MIGRATE_NON_SHARED_INC as they are mutually exclusive.
- *
- * If a hypervisor supports renaming domains during migration,
- * the dname parameter specifies the new name for the domain.
- * Setting dname to NULL keeps the domain name the same. If domain
- * renaming is not supported by the hypervisor, dname must be NULL or
- * else an error will be returned.
- *
- * The maximum bandwidth (in MiB/s) that will be used to do migration
- * can be specified with the bandwidth parameter. If set to 0,
- * libvirt will choose a suitable default. Some hypervisors do
- * not support this feature and will return an error if bandwidth
- * is not 0.
- *
- * To see which features are supported by the current hypervisor,
- * see virConnectGetCapabilities, /capabilities/host/migration_features.
- *
- * There are many limitations on migration imposed by the underlying
- * technology - for example it may not be possible to migrate between
- * different processors even with the same architecture, or between
- * different types of hypervisor.
- *
- * Returns 0 if the migration succeeded, -1 upon error.
- */
-int
-virDomainMigrateToURI(virDomainPtr domain,
- const char *duri,
- unsigned long flags,
- const char *dname,
- unsigned long bandwidth)
-{
- VIR_DOMAIN_DEBUG(domain, "duri=%p, flags=%lx, dname=%s, bandwidth=%lu",
- NULLSTR(duri), flags, NULLSTR(dname), bandwidth);
-
- virResetLastError();
-
- /* First checkout the source */
- virCheckDomainReturn(domain, -1);
- virCheckReadOnlyGoto(domain->conn->flags, error);
-
- virCheckNonNullArgGoto(duri, error);
-
- if (flags & VIR_MIGRATE_NON_SHARED_DISK &&
- flags & VIR_MIGRATE_NON_SHARED_INC) {
- virReportInvalidArg(flags,
- _("flags 'shared disk' and 'shared
incremental' "
- "in %s are mutually exclusive"),
- __FUNCTION__);
- goto error;
- }
-
- if (flags & VIR_MIGRATE_OFFLINE &&
- !VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_OFFLINE)) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("offline migration is not supported by "
- "the source host"));
- goto error;
- }
-
- if (flags & VIR_MIGRATE_PEER2PEER) {
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_P2P)) {
- VIR_DEBUG("Using peer2peer migration");
- if (virDomainMigratePeer2Peer(domain, NULL, flags,
- dname, duri, NULL, bandwidth) < 0)
- goto error;
- } else {
- /* No peer to peer migration supported */
- virReportUnsupportedError();
- goto error;
- }
- } else {
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_DIRECT)) {
- VIR_DEBUG("Using direct migration");
- if (virDomainMigrateDirect(domain, NULL, flags,
- dname, duri, bandwidth) < 0)
- goto error;
- } else {
- /* Cannot do a migration with only the perform step */
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("direct migration is not supported by the"
- " connection driver"));
- goto error;
- }
- }
-
- return 0;
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainMigrateToURI2:
- * @domain: a domain object
- * @dconnuri: (optional) URI for target libvirtd if @flags includes
VIR_MIGRATE_PEER2PEER
- * @miguri: (optional) URI for invoking the migration, not if @flags includs
VIR_MIGRATE_TUNNELLED
- * @dxml: (optional) XML config for launching guest on target
- * @flags: bitwise-OR of virDomainMigrateFlags
- * @dname: (optional) rename domain to this at destination
- * @bandwidth: (optional) specify migration bandwidth limit in MiB/s
- *
- * Migrate the domain object from its current host to the destination
- * host given by duri.
- *
- * Flags may be one of more of the following:
- * VIR_MIGRATE_LIVE Do not pause the VM during migration
- * VIR_MIGRATE_PEER2PEER Direct connection between source & destination hosts
- * VIR_MIGRATE_TUNNELLED Tunnel migration data over the libvirt RPC channel
- * VIR_MIGRATE_PERSIST_DEST If the migration is successful, persist the domain
- * on the destination host.
- * VIR_MIGRATE_UNDEFINE_SOURCE If the migration is successful, undefine the
- * domain on the source host.
- * VIR_MIGRATE_PAUSED Leave the domain suspended on the remote side.
- * VIR_MIGRATE_NON_SHARED_DISK Migration with non-shared storage with full
- * disk copy
- * VIR_MIGRATE_NON_SHARED_INC Migration with non-shared storage with
- * incremental disk copy
- * VIR_MIGRATE_CHANGE_PROTECTION Protect against domain configuration
- * changes during the migration process (set
- * automatically when supported).
- * VIR_MIGRATE_UNSAFE Force migration even if it is considered unsafe.
- * VIR_MIGRATE_OFFLINE Migrate offline
- *
- * The operation of this API hinges on the VIR_MIGRATE_PEER2PEER flag.
- *
- * If the VIR_MIGRATE_PEER2PEER flag is set, the @dconnuri parameter
- * must be a valid libvirt connection URI, by which the source
- * libvirt driver can connect to the destination libvirt. If the
- * VIR_MIGRATE_PEER2PEER flag is NOT set, then @dconnuri must be
- * NULL.
- *
- * If the VIR_MIGRATE_TUNNELLED flag is NOT set, then the @miguri
- * parameter allows specification of a URI to use to initiate the
- * VM migration. It takes a hypervisor specific format. The uri_transports
- * element of the hypervisor capabilities XML includes details of the
- * supported URI schemes.
- *
- * VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set.
- *
- * If you want to copy non-shared storage within migration you
- * can use either VIR_MIGRATE_NON_SHARED_DISK or
- * VIR_MIGRATE_NON_SHARED_INC as they are mutually exclusive.
- *
- * If a hypervisor supports changing the configuration of the guest
- * during migration, the @dxml parameter specifies the new config
- * for the guest. The configuration must include an identical set
- * of virtual devices, to ensure a stable guest ABI across migration.
- * Only parameters related to host side configuration can be
- * changed in the XML. Hypervisors will validate this and refuse to
- * allow migration if the provided XML would cause a change in the
- * guest ABI,
- *
- * If a hypervisor supports renaming domains during migration,
- * the dname parameter specifies the new name for the domain.
- * Setting dname to NULL keeps the domain name the same. If domain
- * renaming is not supported by the hypervisor, dname must be NULL or
- * else an error will be returned.
- *
- * The maximum bandwidth (in MiB/s) that will be used to do migration
- * can be specified with the bandwidth parameter. If set to 0,
- * libvirt will choose a suitable default. Some hypervisors do
- * not support this feature and will return an error if bandwidth
- * is not 0.
- *
- * To see which features are supported by the current hypervisor,
- * see virConnectGetCapabilities, /capabilities/host/migration_features.
- *
- * There are many limitations on migration imposed by the underlying
- * technology - for example it may not be possible to migrate between
- * different processors even with the same architecture, or between
- * different types of hypervisor.
- *
- * Returns 0 if the migration succeeded, -1 upon error.
- */
-int
-virDomainMigrateToURI2(virDomainPtr domain,
- const char *dconnuri,
- const char *miguri,
- const char *dxml,
- unsigned long flags,
- const char *dname,
- unsigned long bandwidth)
-{
- VIR_DOMAIN_DEBUG(domain, "dconnuri=%s, miguri=%s, dxml=%s, "
- "flags=%lx, dname=%s, bandwidth=%lu",
- NULLSTR(dconnuri), NULLSTR(miguri), NULLSTR(dxml),
- flags, NULLSTR(dname), bandwidth);
-
- virResetLastError();
-
- /* First checkout the source */
- virCheckDomainReturn(domain, -1);
- virCheckReadOnlyGoto(domain->conn->flags, error);
-
- if (flags & VIR_MIGRATE_NON_SHARED_DISK &&
- flags & VIR_MIGRATE_NON_SHARED_INC) {
- virReportInvalidArg(flags,
- _("flags 'shared disk' and 'shared
incremental' "
- "in %s are mutually exclusive"),
- __FUNCTION__);
- goto error;
- }
-
- if (flags & VIR_MIGRATE_PEER2PEER) {
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_P2P)) {
- VIR_DEBUG("Using peer2peer migration");
- if (virDomainMigratePeer2Peer(domain, dxml, flags,
- dname, dconnuri, miguri, bandwidth) < 0)
- goto error;
- } else {
- /* No peer to peer migration supported */
- virReportUnsupportedError();
- goto error;
- }
- } else {
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_DIRECT)) {
- VIR_DEBUG("Using direct migration");
- if (virDomainMigrateDirect(domain, dxml, flags,
- dname, miguri, bandwidth) < 0)
- goto error;
- } else {
- /* Cannot do a migration with only the perform step */
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("direct migration is not supported by the"
- " connection driver"));
- goto error;
- }
- }
-
- return 0;
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainMigrateToURI3:
- * @domain: a domain object
- * @dconnuri: (optional) URI for target libvirtd if @flags includes
VIR_MIGRATE_PEER2PEER
- * @params: (optional) migration parameters
- * @nparams: (optional) number of migration parameters in @params
- * @flags: bitwise-OR of virDomainMigrateFlags
- *
- * Migrate the domain object from its current host to the destination host
- * given by URI.
- *
- * See virDomainMigrateFlags documentation for description of individual flags.
- *
- * The operation of this API hinges on the VIR_MIGRATE_PEER2PEER flag.
- *
- * If the VIR_MIGRATE_PEER2PEER flag is set, the @dconnuri parameter must be a
- * valid libvirt connection URI, by which the source libvirt daemon can connect
- * to the destination libvirt.
- *
- * If the VIR_MIGRATE_PEER2PEER flag is NOT set, then @dconnuri must be NULL
- * and VIR_MIGRATE_PARAM_URI migration parameter must be filled in with
- * hypervisor specific URI used to initiate the migration. This is called
- * "direct" migration.
- *
- * VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set.
- *
- * If you want to copy non-shared storage within migration you
- * can use either VIR_MIGRATE_NON_SHARED_DISK or
- * VIR_MIGRATE_NON_SHARED_INC as they are mutually exclusive.
- *
- * There are many limitations on migration imposed by the underlying
- * technology - for example it may not be possible to migrate between
- * different processors even with the same architecture, or between
- * different types of hypervisor.
- *
- * Returns 0 if the migration succeeded, -1 upon error.
- */
-int
-virDomainMigrateToURI3(virDomainPtr domain,
- const char *dconnuri,
- virTypedParameterPtr params,
- unsigned int nparams,
- unsigned int flags)
-{
- bool compat;
- const char *compatParams[] = { VIR_MIGRATE_PARAM_URI,
- VIR_MIGRATE_PARAM_DEST_NAME,
- VIR_MIGRATE_PARAM_DEST_XML,
- VIR_MIGRATE_PARAM_BANDWIDTH };
- const char *uri = NULL;
- const char *dname = NULL;
- const char *dxml = NULL;
- unsigned long long bandwidth = 0;
-
- VIR_DOMAIN_DEBUG(domain, "dconnuri=%s, params=%p, nparms=%u flags=%x",
- NULLSTR(dconnuri), params, nparams, flags);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- /* First checkout the source */
- virCheckDomainReturn(domain, -1);
- virCheckReadOnlyGoto(domain->conn->flags, error);
-
- if (flags & VIR_MIGRATE_NON_SHARED_DISK &&
- flags & VIR_MIGRATE_NON_SHARED_INC) {
- virReportInvalidArg(flags,
- _("flags 'shared disk' and 'shared
incremental' "
- "in %s are mutually exclusive"),
- __FUNCTION__);
- goto error;
- }
-
- compat = virTypedParamsCheck(params, nparams, compatParams,
- ARRAY_CARDINALITY(compatParams));
-
- if (virTypedParamsGetString(params, nparams,
- VIR_MIGRATE_PARAM_URI, &uri) < 0 ||
- virTypedParamsGetString(params, nparams,
- VIR_MIGRATE_PARAM_DEST_NAME, &dname) < 0 ||
- virTypedParamsGetString(params, nparams,
- VIR_MIGRATE_PARAM_DEST_XML, &dxml) < 0 ||
- virTypedParamsGetULLong(params, nparams,
- VIR_MIGRATE_PARAM_BANDWIDTH, &bandwidth) < 0) {
- goto error;
- }
-
- if (flags & VIR_MIGRATE_PEER2PEER) {
- if (!VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_P2P)) {
- virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
- _("Peer-to-peer migration is not supported by "
- "the connection driver"));
- goto error;
- }
-
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_PARAMS)) {
- VIR_DEBUG("Using peer2peer migration with extensible parameters");
- if (virDomainMigratePeer2PeerParams(domain, dconnuri, params,
- nparams, flags) < 0)
- goto error;
- } else if (compat) {
- VIR_DEBUG("Using peer2peer migration");
- if (virDomainMigratePeer2Peer(domain, dxml, flags, dname,
- dconnuri, uri, bandwidth) < 0)
- goto error;
- } else {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("Peer-to-peer migration with extensible "
- "parameters is not supported but extended "
- "parameters were passed"));
- goto error;
- }
- } else {
- if (!VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_MIGRATION_DIRECT)) {
- /* Cannot do a migration with only the perform step */
- virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
- _("Direct migration is not supported by the"
- " connection driver"));
- goto error;
- }
-
- if (!compat) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("Direct migration does not support extensible "
- "parameters"));
- goto error;
- }
-
- VIR_DEBUG("Using direct migration");
- if (virDomainMigrateDirect(domain, dxml, flags,
- dname, uri, bandwidth) < 0)
- goto error;
- }
-
- return 0;
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-int
-virDomainMigratePrepare(virConnectPtr dconn,
- char **cookie,
- int *cookielen,
- const char *uri_in,
- char **uri_out,
- unsigned long flags,
- const char *dname,
- unsigned long bandwidth)
-{
- VIR_DEBUG("dconn=%p, cookie=%p, cookielen=%p, uri_in=%s, uri_out=%p, "
- "flags=%lx, dname=%s, bandwidth=%lu", dconn, cookie, cookielen,
- NULLSTR(uri_in), uri_out, flags, NULLSTR(dname), bandwidth);
-
- virResetLastError();
-
- virCheckConnectReturn(dconn, -1);
- virCheckReadOnlyGoto(dconn->flags, error);
-
- if (dconn->driver->domainMigratePrepare) {
- int ret;
- ret = dconn->driver->domainMigratePrepare(dconn, cookie, cookielen,
- uri_in, uri_out,
- flags, dname, bandwidth);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dconn);
- return -1;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-int
-virDomainMigratePerform(virDomainPtr domain,
- const char *cookie,
- int cookielen,
- const char *uri,
- unsigned long flags,
- const char *dname,
- unsigned long bandwidth)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "cookie=%p, cookielen=%d, uri=%s, flags=%lx, "
- "dname=%s, bandwidth=%lu", cookie, cookielen, uri, flags,
- NULLSTR(dname), bandwidth);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainMigratePerform) {
- int ret;
- ret = conn->driver->domainMigratePerform(domain, cookie, cookielen,
- uri,
- flags, dname, bandwidth);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-virDomainPtr
-virDomainMigrateFinish(virConnectPtr dconn,
- const char *dname,
- const char *cookie,
- int cookielen,
- const char *uri,
- unsigned long flags)
-{
- VIR_DEBUG("dconn=%p, dname=%s, cookie=%p, cookielen=%d, uri=%s, "
- "flags=%lx", dconn, NULLSTR(dname), cookie, cookielen,
- uri, flags);
-
- virResetLastError();
-
- virCheckConnectReturn(dconn, NULL);
- virCheckReadOnlyGoto(dconn->flags, error);
-
- if (dconn->driver->domainMigrateFinish) {
- virDomainPtr ret;
- ret = dconn->driver->domainMigrateFinish(dconn, dname,
- cookie, cookielen,
- uri, flags);
- if (!ret)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dconn);
- return NULL;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-int
-virDomainMigratePrepare2(virConnectPtr dconn,
- char **cookie,
- int *cookielen,
- const char *uri_in,
- char **uri_out,
- unsigned long flags,
- const char *dname,
- unsigned long bandwidth,
- const char *dom_xml)
-{
- VIR_DEBUG("dconn=%p, cookie=%p, cookielen=%p, uri_in=%s, uri_out=%p,"
- "flags=%lx, dname=%s, bandwidth=%lu, dom_xml=%s", dconn,
- cookie, cookielen, uri_in, uri_out, flags, NULLSTR(dname),
- bandwidth, dom_xml);
-
- virResetLastError();
-
- virCheckConnectReturn(dconn, -1);
- virCheckReadOnlyGoto(dconn->flags, error);
-
- if (dconn->driver->domainMigratePrepare2) {
- int ret;
- ret = dconn->driver->domainMigratePrepare2(dconn, cookie, cookielen,
- uri_in, uri_out,
- flags, dname, bandwidth,
- dom_xml);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dconn);
- return -1;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-virDomainPtr
-virDomainMigrateFinish2(virConnectPtr dconn,
- const char *dname,
- const char *cookie,
- int cookielen,
- const char *uri,
- unsigned long flags,
- int retcode)
-{
- VIR_DEBUG("dconn=%p, dname=%s, cookie=%p, cookielen=%d, uri=%s, "
- "flags=%lx, retcode=%d", dconn, NULLSTR(dname), cookie,
- cookielen, uri, flags, retcode);
-
- virResetLastError();
-
- virCheckConnectReturn(dconn, NULL);
- virCheckReadOnlyGoto(dconn->flags, error);
-
- if (dconn->driver->domainMigrateFinish2) {
- virDomainPtr ret;
- ret = dconn->driver->domainMigrateFinish2(dconn, dname,
- cookie, cookielen,
- uri, flags,
- retcode);
- if (!ret && !retcode)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dconn);
- return NULL;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-int
-virDomainMigratePrepareTunnel(virConnectPtr conn,
- virStreamPtr st,
- unsigned long flags,
- const char *dname,
- unsigned long bandwidth,
- const char *dom_xml)
-{
- VIR_DEBUG("conn=%p, stream=%p, flags=%lx, dname=%s, "
- "bandwidth=%lu, dom_xml=%s", conn, st, flags,
- NULLSTR(dname), bandwidth, dom_xml);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn != st->conn) {
- virReportInvalidArg(conn,
- _("conn in %s must match stream connection"),
- __FUNCTION__);
- goto error;
- }
-
- if (conn->driver->domainMigratePrepareTunnel) {
- int rv = conn->driver->domainMigratePrepareTunnel(conn, st,
- flags, dname,
- bandwidth, dom_xml);
- if (rv < 0)
- goto error;
- return rv;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-char *
-virDomainMigrateBegin3(virDomainPtr domain,
- const char *xmlin,
- char **cookieout,
- int *cookieoutlen,
- unsigned long flags,
- const char *dname,
- unsigned long bandwidth)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "xmlin=%s cookieout=%p, cookieoutlen=%p, "
- "flags=%lx, dname=%s, bandwidth=%lu",
- NULLSTR(xmlin), cookieout, cookieoutlen, flags,
- NULLSTR(dname), bandwidth);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, NULL);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainMigrateBegin3) {
- char *xml;
- xml = conn->driver->domainMigrateBegin3(domain, xmlin,
- cookieout, cookieoutlen,
- flags, dname, bandwidth);
- VIR_DEBUG("xml %s", NULLSTR(xml));
- if (!xml)
- goto error;
- return xml;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return NULL;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-int
-virDomainMigratePrepare3(virConnectPtr dconn,
- const char *cookiein,
- int cookieinlen,
- char **cookieout,
- int *cookieoutlen,
- const char *uri_in,
- char **uri_out,
- unsigned long flags,
- const char *dname,
- unsigned long bandwidth,
- const char *dom_xml)
-{
- VIR_DEBUG("dconn=%p, cookiein=%p, cookieinlen=%d, cookieout=%p, "
- "cookieoutlen=%p, uri_in=%s, uri_out=%p, flags=%lx, dname=%s, "
- "bandwidth=%lu, dom_xml=%s",
- dconn, cookiein, cookieinlen, cookieout, cookieoutlen, uri_in,
- uri_out, flags, NULLSTR(dname), bandwidth, dom_xml);
-
- virResetLastError();
-
- virCheckConnectReturn(dconn, -1);
- virCheckReadOnlyGoto(dconn->flags, error);
-
- if (dconn->driver->domainMigratePrepare3) {
- int ret;
- ret = dconn->driver->domainMigratePrepare3(dconn,
- cookiein, cookieinlen,
- cookieout, cookieoutlen,
- uri_in, uri_out,
- flags, dname, bandwidth,
- dom_xml);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dconn);
- return -1;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-int
-virDomainMigratePrepareTunnel3(virConnectPtr conn,
- virStreamPtr st,
- const char *cookiein,
- int cookieinlen,
- char **cookieout,
- int *cookieoutlen,
- unsigned long flags,
- const char *dname,
- unsigned long bandwidth,
- const char *dom_xml)
-{
- VIR_DEBUG("conn=%p, stream=%p, cookiein=%p, cookieinlen=%d, cookieout=%p,
"
- "cookieoutlen=%p, flags=%lx, dname=%s, bandwidth=%lu, "
- "dom_xml=%s",
- conn, st, cookiein, cookieinlen, cookieout, cookieoutlen, flags,
- NULLSTR(dname), bandwidth, dom_xml);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn != st->conn) {
- virReportInvalidArg(conn,
- _("conn in %s must match stream connection"),
- __FUNCTION__);
- goto error;
- }
-
- if (conn->driver->domainMigratePrepareTunnel3) {
- int rv = conn->driver->domainMigratePrepareTunnel3(conn, st,
- cookiein, cookieinlen,
- cookieout, cookieoutlen,
- flags, dname,
- bandwidth, dom_xml);
- if (rv < 0)
- goto error;
- return rv;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-int
-virDomainMigratePerform3(virDomainPtr domain,
- const char *xmlin,
- const char *cookiein,
- int cookieinlen,
- char **cookieout,
- int *cookieoutlen,
- const char *dconnuri,
- const char *uri,
- unsigned long flags,
- const char *dname,
- unsigned long bandwidth)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "xmlin=%s cookiein=%p, cookieinlen=%d, "
- "cookieout=%p, cookieoutlen=%p, dconnuri=%s, "
- "uri=%s, flags=%lx, dname=%s, bandwidth=%lu",
- NULLSTR(xmlin), cookiein, cookieinlen,
- cookieout, cookieoutlen, NULLSTR(dconnuri),
- NULLSTR(uri), flags, NULLSTR(dname), bandwidth);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainMigratePerform3) {
- int ret;
- ret = conn->driver->domainMigratePerform3(domain, xmlin,
- cookiein, cookieinlen,
- cookieout, cookieoutlen,
- dconnuri, uri,
- flags, dname, bandwidth);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-virDomainPtr
-virDomainMigrateFinish3(virConnectPtr dconn,
- const char *dname,
- const char *cookiein,
- int cookieinlen,
- char **cookieout,
- int *cookieoutlen,
- const char *dconnuri,
- const char *uri,
- unsigned long flags,
- int cancelled)
-{
- VIR_DEBUG("dconn=%p, dname=%s, cookiein=%p, cookieinlen=%d, cookieout=%p,"
- "cookieoutlen=%p, dconnuri=%s, uri=%s, flags=%lx, retcode=%d",
- dconn, NULLSTR(dname), cookiein, cookieinlen, cookieout,
- cookieoutlen, NULLSTR(dconnuri), NULLSTR(uri), flags, cancelled);
-
- virResetLastError();
-
- virCheckConnectReturn(dconn, NULL);
- virCheckReadOnlyGoto(dconn->flags, error);
-
- if (dconn->driver->domainMigrateFinish3) {
- virDomainPtr ret;
- ret = dconn->driver->domainMigrateFinish3(dconn, dname,
- cookiein, cookieinlen,
- cookieout, cookieoutlen,
- dconnuri, uri, flags,
- cancelled);
- if (!ret && !cancelled)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dconn);
- return NULL;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-int
-virDomainMigrateConfirm3(virDomainPtr domain,
- const char *cookiein,
- int cookieinlen,
- unsigned long flags,
- int cancelled)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain,
- "cookiein=%p, cookieinlen=%d, flags=%lx, cancelled=%d",
- cookiein, cookieinlen, flags, cancelled);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainMigrateConfirm3) {
- int ret;
- ret = conn->driver->domainMigrateConfirm3(domain,
- cookiein, cookieinlen,
- flags, cancelled);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-char *
-virDomainMigrateBegin3Params(virDomainPtr domain,
- virTypedParameterPtr params,
- int nparams,
- char **cookieout,
- int *cookieoutlen,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, "
- "cookieout=%p, cookieoutlen=%p, flags=%x",
- params, nparams, cookieout, cookieoutlen, flags);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, NULL);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainMigrateBegin3Params) {
- char *xml;
- xml = conn->driver->domainMigrateBegin3Params(domain, params, nparams,
- cookieout, cookieoutlen,
- flags);
- VIR_DEBUG("xml %s", NULLSTR(xml));
- if (!xml)
- goto error;
- return xml;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return NULL;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-int
-virDomainMigratePrepare3Params(virConnectPtr dconn,
- virTypedParameterPtr params,
- int nparams,
- const char *cookiein,
- int cookieinlen,
- char **cookieout,
- int *cookieoutlen,
- char **uri_out,
- unsigned int flags)
-{
- VIR_DEBUG("dconn=%p, params=%p, nparams=%d, cookiein=%p, cookieinlen=%d, "
- "cookieout=%p, cookieoutlen=%p, uri_out=%p, flags=%x",
- dconn, params, nparams, cookiein, cookieinlen,
- cookieout, cookieoutlen, uri_out, flags);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- virCheckConnectReturn(dconn, -1);
- virCheckReadOnlyGoto(dconn->flags, error);
-
- if (dconn->driver->domainMigratePrepare3Params) {
- int ret;
- ret = dconn->driver->domainMigratePrepare3Params(dconn, params, nparams,
- cookiein, cookieinlen,
- cookieout, cookieoutlen,
- uri_out, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dconn);
- return -1;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-int
-virDomainMigratePrepareTunnel3Params(virConnectPtr conn,
- virStreamPtr st,
- virTypedParameterPtr params,
- int nparams,
- const char *cookiein,
- int cookieinlen,
- char **cookieout,
- int *cookieoutlen,
- unsigned int flags)
-{
- VIR_DEBUG("conn=%p, stream=%p, params=%p, nparams=%d, cookiein=%p, "
- "cookieinlen=%d, cookieout=%p, cookieoutlen=%p, flags=%x",
- conn, st, params, nparams, cookiein, cookieinlen,
- cookieout, cookieoutlen, flags);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn != st->conn) {
- virReportInvalidArg(conn,
- _("conn in %s must match stream connection"),
- __FUNCTION__);
- goto error;
- }
-
- if (conn->driver->domainMigratePrepareTunnel3Params) {
- int rv;
- rv = conn->driver->domainMigratePrepareTunnel3Params(
- conn, st, params, nparams, cookiein, cookieinlen,
- cookieout, cookieoutlen, flags);
- if (rv < 0)
- goto error;
- return rv;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-int
-virDomainMigratePerform3Params(virDomainPtr domain,
- const char *dconnuri,
- virTypedParameterPtr params,
- int nparams,
- const char *cookiein,
- int cookieinlen,
- char **cookieout,
- int *cookieoutlen,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "dconnuri=%s, params=%p, nparams=%d, cookiein=%p,
"
- "cookieinlen=%d, cookieout=%p, cookieoutlen=%p,
flags=%x",
- NULLSTR(dconnuri), params, nparams, cookiein,
- cookieinlen, cookieout, cookieoutlen, flags);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainMigratePerform3Params) {
- int ret;
- ret = conn->driver->domainMigratePerform3Params(
- domain, dconnuri, params, nparams, cookiein, cookieinlen,
- cookieout, cookieoutlen, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-virDomainPtr
-virDomainMigrateFinish3Params(virConnectPtr dconn,
- virTypedParameterPtr params,
- int nparams,
- const char *cookiein,
- int cookieinlen,
- char **cookieout,
- int *cookieoutlen,
- unsigned int flags,
- int cancelled)
-{
- VIR_DEBUG("dconn=%p, params=%p, nparams=%d, cookiein=%p, cookieinlen=%d, "
- "cookieout=%p, cookieoutlen=%p, flags=%x, cancelled=%d",
- dconn, params, nparams, cookiein, cookieinlen, cookieout,
- cookieoutlen, flags, cancelled);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- virCheckConnectReturn(dconn, NULL);
- virCheckReadOnlyGoto(dconn->flags, error);
-
- if (dconn->driver->domainMigrateFinish3Params) {
- virDomainPtr ret;
- ret = dconn->driver->domainMigrateFinish3Params(
- dconn, params, nparams, cookiein, cookieinlen,
- cookieout, cookieoutlen, flags, cancelled);
- if (!ret && !cancelled)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dconn);
- return NULL;
-}
-
-
-/*
- * Not for public use. This function is part of the internal
- * implementation of migration in the remote case.
- */
-int
-virDomainMigrateConfirm3Params(virDomainPtr domain,
- virTypedParameterPtr params,
- int nparams,
- const char *cookiein,
- int cookieinlen,
- unsigned int flags,
- int cancelled)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, cookiein=%p, "
- "cookieinlen=%d, flags=%x, cancelled=%d",
- params, nparams, cookiein, cookieinlen, flags, cancelled);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainMigrateConfirm3Params) {
- int ret;
- ret = conn->driver->domainMigrateConfirm3Params(
- domain, params, nparams,
- cookiein, cookieinlen, flags, cancelled);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virNodeGetInfo:
- * @conn: pointer to the hypervisor connection
- * @info: pointer to a virNodeInfo structure allocated by the user
- *
- * Extract hardware information about the node.
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
-{
- VIR_DEBUG("conn=%p, info=%p", conn, info);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckNonNullArgGoto(info, error);
-
- if (conn->driver->nodeGetInfo) {
- int ret;
- ret = conn->driver->nodeGetInfo(conn, info);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virConnectGetCapabilities:
- * @conn: pointer to the hypervisor connection
- *
- * Provides capabilities of the hypervisor / driver.
- *
- * Returns NULL in case of error, or an XML string
- * defining the capabilities.
- * The client must free the returned string after use.
- */
-char *
-virConnectGetCapabilities(virConnectPtr conn)
-{
- VIR_DEBUG("conn=%p", conn);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, NULL);
-
- if (conn->driver->connectGetCapabilities) {
- char *ret;
- ret = conn->driver->connectGetCapabilities(conn);
- if (!ret)
- goto error;
- VIR_DEBUG("conn=%p ret=%s", conn, ret);
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return NULL;
-}
-
-
-/**
- * virNodeGetCPUStats:
- * @conn: pointer to the hypervisor connection.
- * @cpuNum: number of node cpu. (VIR_NODE_CPU_STATS_ALL_CPUS means total cpu
- * statistics)
- * @params: pointer to node cpu time parameter objects
- * @nparams: number of node cpu time parameter (this value should be same or
- * less than the number of parameters supported)
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * This function provides individual cpu statistics of the node.
- * If you want to get total cpu statistics of the node, you must specify
- * VIR_NODE_CPU_STATS_ALL_CPUS to @cpuNum.
- * The @params array will be filled with the values equal to the number of
- * parameters suggested by @nparams
- *
- * As the value of @nparams is dynamic, call the API setting @nparams to 0 and
- * @params as NULL, the API returns the number of parameters supported by the
- * HV by updating @nparams on SUCCESS. The caller should then allocate @params
- * array, i.e. (sizeof(@virNodeCPUStats) * @nparams) bytes and call
- * the API again.
- *
- * Here is a sample code snippet:
- *
- * if (virNodeGetCPUStats(conn, cpuNum, NULL, &nparams, 0) == 0 &&
- * nparams != 0) {
- * if ((params = malloc(sizeof(virNodeCPUStats) * nparams)) == NULL)
- * goto error;
- * memset(params, 0, sizeof(virNodeCPUStats) * nparams);
- * if (virNodeGetCPUStats(conn, cpuNum, params, &nparams, 0))
- * goto error;
- * }
- *
- * This function doesn't require privileged access to the hypervisor.
- * This function expects the caller to allocate the @params.
- *
- * CPU time Statistics:
- *
- * VIR_NODE_CPU_STATS_KERNEL:
- * The cumulative CPU time which spends by kernel,
- * when the node booting up.(nanoseconds)
- * VIR_NODE_CPU_STATS_USER:
- * The cumulative CPU time which spends by user processes,
- * when the node booting up.(nanoseconds)
- * VIR_NODE_CPU_STATS_IDLE:
- * The cumulative idle CPU time, when the node booting up.(nanoseconds)
- * VIR_NODE_CPU_STATS_IOWAIT:
- * The cumulative I/O wait CPU time, when the node booting up.(nanoseconds)
- * VIR_NODE_CPU_STATS_UTILIZATION:
- * The CPU utilization. The usage value is in percent and 100%
- * represents all CPUs on the server.
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virNodeGetCPUStats(virConnectPtr conn,
- int cpuNum,
- virNodeCPUStatsPtr params,
- int *nparams, unsigned int flags)
-{
- VIR_DEBUG("conn=%p, cpuNum=%d, params=%p, nparams=%d, flags=%x",
- conn, cpuNum, params, nparams ? *nparams : -1, flags);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckNonNullArgGoto(nparams, error);
- virCheckNonNegativeArgGoto(*nparams, error);
- if (cpuNum < 0 && cpuNum != VIR_NODE_CPU_STATS_ALL_CPUS) {
- virReportInvalidArg(cpuNum,
- _("cpuNum in %s only accepts %d as a negative "
- "value"),
- __FUNCTION__, VIR_NODE_CPU_STATS_ALL_CPUS);
- goto error;
- }
-
- if (conn->driver->nodeGetCPUStats) {
- int ret;
- ret = conn->driver->nodeGetCPUStats(conn, cpuNum, params, nparams, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virNodeGetMemoryStats:
- * @conn: pointer to the hypervisor connection.
- * @cellNum: number of node cell. (VIR_NODE_MEMORY_STATS_ALL_CELLS means total
- * cell statistics)
- * @params: pointer to node memory stats objects
- * @nparams: number of node memory stats (this value should be same or
- * less than the number of stats supported)
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * This function provides memory stats of the node.
- * If you want to get total memory statistics of the node, you must specify
- * VIR_NODE_MEMORY_STATS_ALL_CELLS to @cellNum.
- * The @params array will be filled with the values equal to the number of
- * stats suggested by @nparams
- *
- * As the value of @nparams is dynamic, call the API setting @nparams to 0 and
- * @params as NULL, the API returns the number of parameters supported by the
- * HV by updating @nparams on SUCCESS. The caller should then allocate @params
- * array, i.e. (sizeof(@virNodeMemoryStats) * @nparams) bytes and call
- * the API again.
- *
- * Here is the sample code snippet:
- *
- * if (virNodeGetMemoryStats(conn, cellNum, NULL, &nparams, 0) == 0 &&
- * nparams != 0) {
- * if ((params = malloc(sizeof(virNodeMemoryStats) * nparams)) == NULL)
- * goto error;
- * memset(params, cellNum, 0, sizeof(virNodeMemoryStats) * nparams);
- * if (virNodeGetMemoryStats(conn, params, &nparams, 0))
- * goto error;
- * }
- *
- * This function doesn't require privileged access to the hypervisor.
- * This function expects the caller to allocate the @params.
- *
- * Memory Stats:
- *
- * VIR_NODE_MEMORY_STATS_TOTAL:
- * The total memory usage.(KB)
- * VIR_NODE_MEMORY_STATS_FREE:
- * The free memory usage.(KB)
- * On linux, this usage includes buffers and cached.
- * VIR_NODE_MEMORY_STATS_BUFFERS:
- * The buffers memory usage.(KB)
- * VIR_NODE_MEMORY_STATS_CACHED:
- * The cached memory usage.(KB)
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virNodeGetMemoryStats(virConnectPtr conn,
- int cellNum,
- virNodeMemoryStatsPtr params,
- int *nparams, unsigned int flags)
-{
- VIR_DEBUG("conn=%p, cellNum=%d, params=%p, nparams=%d, flags=%x",
- conn, cellNum, params, nparams ? *nparams : -1, flags);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckNonNullArgGoto(nparams, error);
- virCheckNonNegativeArgGoto(*nparams, error);
- if (cellNum < 0 && cellNum != VIR_NODE_MEMORY_STATS_ALL_CELLS) {
- virReportInvalidArg(cpuNum,
- _("cellNum in %s only accepts %d as a negative "
- "value"),
- __FUNCTION__, VIR_NODE_MEMORY_STATS_ALL_CELLS);
- goto error;
- }
-
- if (conn->driver->nodeGetMemoryStats) {
- int ret;
- ret = conn->driver->nodeGetMemoryStats(conn, cellNum, params, nparams,
flags);
- if (ret < 0)
- goto error;
- return ret;
- }
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virNodeGetFreeMemory:
- * @conn: pointer to the hypervisor connection
- *
- * provides the free memory available on the Node
- * Note: most libvirt APIs provide memory sizes in kibibytes, but in this
- * function the returned value is in bytes. Divide by 1024 as necessary.
- *
- * Returns the available free memory in bytes or 0 in case of error
- */
-unsigned long long
-virNodeGetFreeMemory(virConnectPtr conn)
-{
- VIR_DEBUG("conn=%p", conn);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, 0);
-
- if (conn->driver->nodeGetFreeMemory) {
- unsigned long long ret;
- ret = conn->driver->nodeGetFreeMemory(conn);
- if (ret == 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return 0;
-}
-
-
-/**
- * virNodeSuspendForDuration:
- * @conn: pointer to the hypervisor connection
- * @target: the state to which the host must be suspended to,
- * such as: VIR_NODE_SUSPEND_TARGET_MEM (Suspend-to-RAM)
- * VIR_NODE_SUSPEND_TARGET_DISK (Suspend-to-Disk)
- * VIR_NODE_SUSPEND_TARGET_HYBRID (Hybrid-Suspend,
- * which is a combination of the former modes).
- * @duration: the time duration in seconds for which the host
- * has to be suspended
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Attempt to suspend the node (host machine) for the given duration of
- * time in the specified state (Suspend-to-RAM, Suspend-to-Disk or
- * Hybrid-Suspend). Schedule the node's Real-Time-Clock interrupt to
- * resume the node after the duration is complete.
- *
- * Returns 0 on success (i.e., the node will be suspended after a short
- * delay), -1 on failure (the operation is not supported, or an attempted
- * suspend is already underway).
- */
-int
-virNodeSuspendForDuration(virConnectPtr conn,
- unsigned int target,
- unsigned long long duration,
- unsigned int flags)
-{
- VIR_DEBUG("conn=%p, target=%d, duration=%lld, flags=%x",
- conn, target, duration, flags);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->nodeSuspendForDuration) {
- int ret;
- ret = conn->driver->nodeSuspendForDuration(conn, target,
- duration, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/*
- * virNodeGetMemoryParameters:
- * @conn: pointer to the hypervisor connection
- * @params: pointer to memory parameter object
- * (return value, allocated by the caller)
- * @nparams: pointer to number of memory parameters; input and output
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Get all node memory parameters (parameters unsupported by OS will be
- * omitted). On input, @nparams gives the size of the @params array;
- * on output, @nparams gives how many slots were filled with parameter
- * information, which might be less but will not exceed the input value.
- *
- * As a special case, calling with @params as NULL and @nparams as 0 on
- * input will cause @nparams on output to contain the number of parameters
- * supported by the hypervisor. The caller should then allocate @params
- * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
- * again. See virDomainGetMemoryParameters() for an equivalent usage
- * example.
- *
- * Returns 0 in case of success, and -1 in case of failure.
- */
-int
-virNodeGetMemoryParameters(virConnectPtr conn,
- virTypedParameterPtr params,
- int *nparams,
- unsigned int flags)
-{
- VIR_DEBUG("conn=%p, params=%p, nparams=%p, flags=%x",
- conn, params, nparams, flags);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckNonNullArgGoto(nparams, error);
- virCheckNonNegativeArgGoto(*nparams, error);
- if (*nparams != 0)
- virCheckNonNullArgGoto(params, error);
-
- if (VIR_DRV_SUPPORTS_FEATURE(conn->driver, conn,
- VIR_DRV_FEATURE_TYPED_PARAM_STRING))
- flags |= VIR_TYPED_PARAM_STRING_OKAY;
-
- if (conn->driver->nodeGetMemoryParameters) {
- int ret;
- ret = conn->driver->nodeGetMemoryParameters(conn, params,
- nparams, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/*
- * virNodeSetMemoryParameters:
- * @conn: pointer to the hypervisor connection
- * @params: pointer to scheduler parameter objects
- * @nparams: number of scheduler parameter objects
- * (this value can be the same or less than the returned
- * value nparams of virDomainGetSchedulerType)
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Change all or a subset of the node memory tunables. The function
- * fails if not all of the tunables are supported.
- *
- * Note that it's not recommended to use this function while the
- * outside tuning program is running (such as ksmtuned under Linux),
- * as they could change the tunables in parallel, which could cause
- * conflicts.
- *
- * This function may require privileged access to the hypervisor.
- *
- * Returns 0 in case of success, -1 in case of failure.
- */
-int
-virNodeSetMemoryParameters(virConnectPtr conn,
- virTypedParameterPtr params,
- int nparams,
- unsigned int flags)
-{
- VIR_DEBUG("conn=%p, params=%p, nparams=%d, flags=%x",
- conn, params, nparams, flags);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(params, error);
- virCheckNonNegativeArgGoto(nparams, error);
-
- if (virTypedParameterValidateSet(conn, params, nparams) < 0)
- goto error;
-
- if (conn->driver->nodeSetMemoryParameters) {
- int ret;
- ret = conn->driver->nodeSetMemoryParameters(conn, params,
- nparams, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainGetSchedulerType:
- * @domain: pointer to domain object
- * @nparams: pointer to number of scheduler parameters, can be NULL
- * (return value)
- *
- * Get the scheduler type and the number of scheduler parameters.
- *
- * Returns NULL in case of error. The caller must free the returned string.
- */
-char *
-virDomainGetSchedulerType(virDomainPtr domain, int *nparams)
-{
- virConnectPtr conn;
- char *schedtype;
-
- VIR_DOMAIN_DEBUG(domain, "nparams=%p", nparams);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, NULL);
- conn = domain->conn;
-
- if (conn->driver->domainGetSchedulerType) {
- schedtype = conn->driver->domainGetSchedulerType(domain, nparams);
- if (!schedtype)
- goto error;
- return schedtype;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return NULL;
-}
-
-
-/**
- * virDomainGetSchedulerParameters:
- * @domain: pointer to domain object
- * @params: pointer to scheduler parameter objects
- * (return value)
- * @nparams: pointer to number of scheduler parameter objects
- * (this value should generally be as large as the returned value
- * nparams of virDomainGetSchedulerType()); input and output
- *
- * Get all scheduler parameters. On input, @nparams gives the size of the
- * @params array; on output, @nparams gives how many slots were filled
- * with parameter information, which might be less but will not exceed
- * the input value. @nparams cannot be 0.
- *
- * It is hypervisor specific whether this returns the live or
- * persistent state; for more control, use
- * virDomainGetSchedulerParametersFlags().
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virDomainGetSchedulerParameters(virDomainPtr domain,
- virTypedParameterPtr params, int *nparams)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%p", params, nparams);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
-
- virCheckNonNullArgGoto(params, error);
- virCheckNonNullArgGoto(nparams, error);
- virCheckPositiveArgGoto(*nparams, error);
-
- conn = domain->conn;
-
- if (conn->driver->domainGetSchedulerParameters) {
- int ret;
- ret = conn->driver->domainGetSchedulerParameters(domain, params, nparams);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetSchedulerParametersFlags:
- * @domain: pointer to domain object
- * @params: pointer to scheduler parameter object
- * (return value)
- * @nparams: pointer to number of scheduler parameter
- * (this value should be same than the returned value
- * nparams of virDomainGetSchedulerType()); input and output
- * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
- *
- * Get all scheduler parameters. On input, @nparams gives the size of the
- * @params array; on output, @nparams gives how many slots were filled
- * with parameter information, which might be less but will not exceed
- * the input value. @nparams cannot be 0.
- *
- * The value of @flags can be exactly VIR_DOMAIN_AFFECT_CURRENT,
- * VIR_DOMAIN_AFFECT_LIVE, or VIR_DOMAIN_AFFECT_CONFIG.
- *
- * Here is a sample code snippet:
- *
- * char *ret = virDomainGetSchedulerType(dom, &nparams);
- * if (ret && nparams != 0) {
- * if ((params = malloc(sizeof(*params) * nparams)) == NULL)
- * goto error;
- * memset(params, 0, sizeof(*params) * nparams);
- * if (virDomainGetSchedulerParametersFlags(dom, params, &nparams, 0))
- * goto error;
- * }
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virDomainGetSchedulerParametersFlags(virDomainPtr domain,
- virTypedParameterPtr params, int *nparams,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%p, flags=%x",
- params, nparams, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
-
- virCheckNonNullArgGoto(params, error);
- virCheckNonNullArgGoto(nparams, error);
- virCheckPositiveArgGoto(*nparams, error);
-
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_TYPED_PARAM_STRING))
- flags |= VIR_TYPED_PARAM_STRING_OKAY;
-
- /* At most one of these two flags should be set. */
- if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
- (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
- virReportInvalidArg(flags,
- _("flags 'affect live' and 'affect
config' in %s "
- "are mutually exclusive"),
- __FUNCTION__);
- goto error;
- }
- conn = domain->conn;
-
- if (conn->driver->domainGetSchedulerParametersFlags) {
- int ret;
- ret = conn->driver->domainGetSchedulerParametersFlags(domain, params,
- nparams, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainSetSchedulerParameters:
- * @domain: pointer to domain object
- * @params: pointer to scheduler parameter objects
- * @nparams: number of scheduler parameter objects
- * (this value can be the same or less than the returned value
- * nparams of virDomainGetSchedulerType)
- *
- * Change all or a subset or the scheduler parameters. It is
- * hypervisor-specific whether this sets live, persistent, or both
- * settings; for more control, use
- * virDomainSetSchedulerParametersFlags.
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virDomainSetSchedulerParameters(virDomainPtr domain,
- virTypedParameterPtr params, int nparams)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d", params, nparams);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(params, error);
- virCheckNonNegativeArgGoto(nparams, error);
-
- if (virTypedParameterValidateSet(conn, params, nparams) < 0)
- goto error;
-
- if (conn->driver->domainSetSchedulerParameters) {
- int ret;
- ret = conn->driver->domainSetSchedulerParameters(domain, params, nparams);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainSetSchedulerParametersFlags:
- * @domain: pointer to domain object
- * @params: pointer to scheduler parameter objects
- * @nparams: number of scheduler parameter objects
- * (this value can be the same or less than the returned value
- * nparams of virDomainGetSchedulerType)
- * @flags: bitwise-OR of virDomainModificationImpact
- *
- * Change a subset or all scheduler parameters. The value of @flags
- * should be either VIR_DOMAIN_AFFECT_CURRENT, or a bitwise-or of
- * values from VIR_DOMAIN_AFFECT_LIVE and
- * VIR_DOMAIN_AFFECT_CURRENT, although hypervisors vary in which
- * flags are supported.
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virDomainSetSchedulerParametersFlags(virDomainPtr domain,
- virTypedParameterPtr params,
- int nparams,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=%x",
- params, nparams, flags);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(params, error);
- virCheckNonNegativeArgGoto(nparams, error);
-
- if (virTypedParameterValidateSet(conn, params, nparams) < 0)
- goto error;
-
- if (conn->driver->domainSetSchedulerParametersFlags) {
- int ret;
- ret = conn->driver->domainSetSchedulerParametersFlags(domain,
- params,
- nparams,
- flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainBlockStats:
- * @dom: pointer to the domain object
- * @disk: path to the block device, or device shorthand
- * @stats: block device stats (returned)
- * @size: size of stats structure
- *
- * This function returns block device (disk) stats for block
- * devices attached to the domain.
- *
- * The @disk parameter is either the device target shorthand (the
- * <target dev='...'/> sub-element, such as "vda"), or (since
0.9.8)
- * an unambiguous source name of the block device (the <source
- * file='...'/> sub-element, such as "/path/to/image"). Valid
names
- * can be found by calling virDomainGetXMLDesc() and inspecting
- * elements within //domain/devices/disk. Some drivers might also
- * accept the empty string for the @disk parameter, and then yield
- * summary stats for the entire domain.
- *
- * Domains may have more than one block device. To get stats for
- * each you should make multiple calls to this function.
- *
- * Individual fields within the stats structure may be returned
- * as -1, which indicates that the hypervisor does not support
- * that particular statistic.
- *
- * Returns: 0 in case of success or -1 in case of failure.
- */
-int
-virDomainBlockStats(virDomainPtr dom, const char *disk,
- virDomainBlockStatsPtr stats, size_t size)
-{
- virConnectPtr conn;
- virDomainBlockStatsStruct stats2 = { -1, -1, -1, -1, -1 };
-
- VIR_DOMAIN_DEBUG(dom, "disk=%s, stats=%p, size=%zi", disk, stats, size);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- virCheckNonNullArgGoto(disk, error);
- virCheckNonNullArgGoto(stats, error);
- if (size > sizeof(stats2)) {
- virReportInvalidArg(size,
- _("size in %s must not exceed %zu"),
- __FUNCTION__, sizeof(stats2));
- goto error;
- }
- conn = dom->conn;
-
- if (conn->driver->domainBlockStats) {
- if (conn->driver->domainBlockStats(dom, disk, &stats2) == -1)
- goto error;
-
- memcpy(stats, &stats2, size);
- return 0;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainBlockStatsFlags:
- * @dom: pointer to domain object
- * @disk: path to the block device, or device shorthand
- * @params: pointer to block stats parameter object
- * (return value, allocated by the caller)
- * @nparams: pointer to number of block stats; input and output
- * @flags: bitwise-OR of virTypedParameterFlags
- *
- * This function is to get block stats parameters for block
- * devices attached to the domain.
- *
- * The @disk parameter is either the device target shorthand (the
- * <target dev='...'/> sub-element, such as "vda"), or (since
0.9.8)
- * an unambiguous source name of the block device (the <source
- * file='...'/> sub-element, such as "/path/to/image"). Valid
names
- * can be found by calling virDomainGetXMLDesc() and inspecting
- * elements within //domain/devices/disk. Some drivers might also
- * accept the empty string for the @disk parameter, and then yield
- * summary stats for the entire domain.
- *
- * Domains may have more than one block device. To get stats for
- * each you should make multiple calls to this function.
- *
- * On input, @nparams gives the size of the @params array; on output,
- * @nparams gives how many slots were filled with parameter
- * information, which might be less but will not exceed the input
- * value.
- *
- * As a special case, calling with @params as NULL and @nparams as 0 on
- * input will cause @nparams on output to contain the number of parameters
- * supported by the hypervisor. (Note that block devices of different types
- * might support different parameters, so it might be necessary to compute
- * @nparams for each block device). The caller should then allocate @params
- * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
- * again. See virDomainGetMemoryParameters() for more details.
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virDomainBlockStatsFlags(virDomainPtr dom,
- const char *disk,
- virTypedParameterPtr params,
- int *nparams,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "disk=%s, params=%p, nparams=%d, flags=%x",
- disk, params, nparams ? *nparams : -1, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- virCheckNonNullArgGoto(disk, error);
- virCheckNonNullArgGoto(nparams, error);
- virCheckNonNegativeArgGoto(*nparams, error);
- if (*nparams != 0)
- virCheckNonNullArgGoto(params, error);
-
- if (VIR_DRV_SUPPORTS_FEATURE(dom->conn->driver, dom->conn,
- VIR_DRV_FEATURE_TYPED_PARAM_STRING))
- flags |= VIR_TYPED_PARAM_STRING_OKAY;
- conn = dom->conn;
-
- if (conn->driver->domainBlockStatsFlags) {
- int ret;
- ret = conn->driver->domainBlockStatsFlags(dom, disk, params, nparams,
flags);
- if (ret < 0)
- goto error;
- return ret;
- }
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainInterfaceStats:
- * @dom: pointer to the domain object
- * @path: path to the interface
- * @stats: network interface stats (returned)
- * @size: size of stats structure
- *
- * This function returns network interface stats for interfaces
- * attached to the domain.
- *
- * The path parameter is the name of the network interface.
- *
- * Domains may have more than one network interface. To get stats for
- * each you should make multiple calls to this function.
- *
- * Individual fields within the stats structure may be returned
- * as -1, which indicates that the hypervisor does not support
- * that particular statistic.
- *
- * Returns: 0 in case of success or -1 in case of failure.
- */
-int
-virDomainInterfaceStats(virDomainPtr dom, const char *path,
- virDomainInterfaceStatsPtr stats, size_t size)
-{
- virConnectPtr conn;
- virDomainInterfaceStatsStruct stats2 = { -1, -1, -1, -1,
- -1, -1, -1, -1 };
-
- VIR_DOMAIN_DEBUG(dom, "path=%s, stats=%p, size=%zi",
- path, stats, size);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- virCheckNonNullArgGoto(path, error);
- virCheckNonNullArgGoto(stats, error);
- if (size > sizeof(stats2)) {
- virReportInvalidArg(size,
- _("size in %s must not exceed %zu"),
- __FUNCTION__, sizeof(stats2));
- goto error;
- }
-
- conn = dom->conn;
-
- if (conn->driver->domainInterfaceStats) {
- if (conn->driver->domainInterfaceStats(dom, path, &stats2) == -1)
- goto error;
-
- memcpy(stats, &stats2, size);
- return 0;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainSetInterfaceParameters:
- * @domain: pointer to domain object
- * @device: the interface name or mac address
- * @params: pointer to interface parameter objects
- * @nparams: number of interface parameter (this value can be the same or
- * less than the number of parameters supported)
- * @flags: bitwise-OR of virDomainModificationImpact
- *
- * Change a subset or all parameters of interface; currently this
- * includes bandwidth parameters. The value of @flags should be
- * either VIR_DOMAIN_AFFECT_CURRENT, or a bitwise-or of values
- * VIR_DOMAIN_AFFECT_LIVE and VIR_DOMAIN_AFFECT_CONFIG, although
- * hypervisors vary in which flags are supported.
- *
- * This function may require privileged access to the hypervisor.
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virDomainSetInterfaceParameters(virDomainPtr domain,
- const char *device,
- virTypedParameterPtr params,
- int nparams, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "device=%s, params=%p, nparams=%d, flags=%x",
- device, params, nparams, flags);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(params, error);
- virCheckPositiveArgGoto(nparams, error);
-
- if (virTypedParameterValidateSet(conn, params, nparams) < 0)
- goto error;
-
- if (conn->driver->domainSetInterfaceParameters) {
- int ret;
- ret = conn->driver->domainSetInterfaceParameters(domain, device,
- params, nparams,
- flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetInterfaceParameters:
- * @domain: pointer to domain object
- * @device: the interface name or mac address
- * @params: pointer to interface parameter objects
- * (return value, allocated by the caller)
- * @nparams: pointer to number of interface parameter; input and output
- * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
- *
- * Get all interface parameters. On input, @nparams gives the size of
- * the @params array; on output, @nparams gives how many slots were
- * filled with parameter information, which might be less but will not
- * exceed the input value.
- *
- * As a special case, calling with @params as NULL and @nparams as 0 on
- * input will cause @nparams on output to contain the number of parameters
- * supported by the hypervisor. The caller should then allocate @params
- * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the
- * API again. See virDomainGetMemoryParameters() for an equivalent usage
- * example.
- *
- * This function may require privileged access to the hypervisor. This function
- * expects the caller to allocate the @params.
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virDomainGetInterfaceParameters(virDomainPtr domain,
- const char *device,
- virTypedParameterPtr params,
- int *nparams, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "device=%s, params=%p, nparams=%d, flags=%x",
- device, params, (nparams) ? *nparams : -1, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- virCheckNonNullArgGoto(nparams, error);
- virCheckNonNegativeArgGoto(*nparams, error);
- if (*nparams != 0)
- virCheckNonNullArgGoto(params, error);
-
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_TYPED_PARAM_STRING))
- flags |= VIR_TYPED_PARAM_STRING_OKAY;
-
- conn = domain->conn;
-
- if (conn->driver->domainGetInterfaceParameters) {
- int ret;
- ret = conn->driver->domainGetInterfaceParameters(domain, device,
- params, nparams,
- flags);
- if (ret < 0)
- goto error;
- return ret;
- }
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainMemoryStats:
- * @dom: pointer to the domain object
- * @stats: nr_stats-sized array of stat structures (returned)
- * @nr_stats: number of memory statistics requested
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * This function provides memory statistics for the domain.
- *
- * Up to 'nr_stats' elements of 'stats' will be populated with memory
statistics
- * from the domain. Only statistics supported by the domain, the driver, and
- * this version of libvirt will be returned.
- *
- * Memory Statistics:
- *
- * VIR_DOMAIN_MEMORY_STAT_SWAP_IN:
- * The total amount of data read from swap space (in kb).
- * VIR_DOMAIN_MEMORY_STAT_SWAP_OUT:
- * The total amount of memory written out to swap space (in kb).
- * VIR_DOMAIN_MEMORY_STAT_MAJOR_FAULT:
- * The number of page faults that required disk IO to service.
- * VIR_DOMAIN_MEMORY_STAT_MINOR_FAULT:
- * The number of page faults serviced without disk IO.
- * VIR_DOMAIN_MEMORY_STAT_UNUSED:
- * The amount of memory which is not being used for any purpose (in kb).
- * VIR_DOMAIN_MEMORY_STAT_AVAILABLE:
- * The total amount of memory available to the domain's OS (in kb).
- * VIR_DOMAIN_MEMORY_STAT_ACTUAL_BALLOON:
- * Current balloon value (in kb).
- *
- * Returns: The number of stats provided or -1 in case of failure.
- */
-int
-virDomainMemoryStats(virDomainPtr dom, virDomainMemoryStatPtr stats,
- unsigned int nr_stats, unsigned int flags)
-{
- virConnectPtr conn;
- unsigned long nr_stats_ret = 0;
-
- VIR_DOMAIN_DEBUG(dom, "stats=%p, nr_stats=%u, flags=%x",
- stats, nr_stats, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
-
- if (!stats || nr_stats == 0)
- return 0;
-
- if (nr_stats > VIR_DOMAIN_MEMORY_STAT_NR)
- nr_stats = VIR_DOMAIN_MEMORY_STAT_NR;
-
- conn = dom->conn;
- if (conn->driver->domainMemoryStats) {
- nr_stats_ret = conn->driver->domainMemoryStats(dom, stats, nr_stats,
- flags);
- if (nr_stats_ret == -1)
- goto error;
- return nr_stats_ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainBlockPeek:
- * @dom: pointer to the domain object
- * @disk: path to the block device, or device shorthand
- * @offset: offset within block device
- * @size: size to read
- * @buffer: return buffer (must be at least size bytes)
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * This function allows you to read the contents of a domain's
- * disk device.
- *
- * Typical uses for this are to determine if the domain has
- * written a Master Boot Record (indicating that the domain
- * has completed installation), or to try to work out the state
- * of the domain's filesystems.
- *
- * (Note that in the local case you might try to open the
- * block device or file directly, but that won't work in the
- * remote case, nor if you don't have sufficient permission.
- * Hence the need for this call).
- *
- * The @disk parameter is either an unambiguous source name of the
- * block device (the <source file='...'/> sub-element, such as
- * "/path/to/image"), or (since 0.9.5) the device target shorthand
- * (the <target dev='...'/> sub-element, such as "vda"). Valid
names
- * can be found by calling virDomainGetXMLDesc() and inspecting
- * elements within //domain/devices/disk.
- *
- * 'offset' and 'size' represent an area which must lie entirely
- * within the device or file. 'size' may be 0 to test if the
- * call would succeed.
- *
- * 'buffer' is the return buffer and must be at least 'size' bytes.
- *
- * NB. The remote driver imposes a 64K byte limit on 'size'.
- * For your program to be able to work reliably over a remote
- * connection you should split large requests to <= 65536 bytes.
- * However, with 0.9.13 this RPC limit has been raised to 1M byte.
- * Starting with version 1.0.6 the RPC limit has been raised again.
- * Now large requests up to 16M byte are supported.
- *
- * Returns: 0 in case of success or -1 in case of failure.
- */
-int
-virDomainBlockPeek(virDomainPtr dom,
- const char *disk,
- unsigned long long offset /* really 64 bits */,
- size_t size,
- void *buffer,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "disk=%s, offset=%lld, size=%zi, buffer=%p,
flags=%x",
- disk, offset, size, buffer, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(disk, error);
-
- /* Allow size == 0 as an access test. */
- if (size > 0)
- virCheckNonNullArgGoto(buffer, error);
-
- if (conn->driver->domainBlockPeek) {
- int ret;
- ret = conn->driver->domainBlockPeek(dom, disk, offset, size,
- buffer, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainBlockResize:
- * @dom: pointer to the domain object
- * @disk: path to the block image, or shorthand
- * @size: new size of the block image, see below for unit
- * @flags: bitwise-OR of virDomainBlockResizeFlags
- *
- * Resize a block device of domain while the domain is running. If
- * @flags is 0, then @size is in kibibytes (blocks of 1024 bytes);
- * since 0.9.11, if @flags includes VIR_DOMAIN_BLOCK_RESIZE_BYTES,
- * @size is in bytes instead. @size is taken directly as the new
- * size. Depending on the file format, the hypervisor may round up
- * to the next alignment boundary.
- *
- * The @disk parameter is either an unambiguous source name of the
- * block device (the <source file='...'/> sub-element, such as
- * "/path/to/image"), or (since 0.9.5) the device target shorthand
- * (the <target dev='...'/> sub-element, such as "vda"). Valid
names
- * can be found by calling virDomainGetXMLDesc() and inspecting
- * elements within //domain/devices/disk.
- *
- * Note that this call may fail if the underlying virtualization hypervisor
- * does not support it; this call requires privileged access to the
- * hypervisor.
- *
- * Returns: 0 in case of success or -1 in case of failure.
- */
-int
-virDomainBlockResize(virDomainPtr dom,
- const char *disk,
- unsigned long long size,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "disk=%s, size=%llu, flags=%x", disk, size, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(disk, error);
-
- if (conn->driver->domainBlockResize) {
- int ret;
- ret = conn->driver->domainBlockResize(dom, disk, size, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainMemoryPeek:
- * @dom: pointer to the domain object
- * @start: start of memory to peek
- * @size: size of memory to peek
- * @buffer: return buffer (must be at least size bytes)
- * @flags: bitwise-OR of virDomainMemoryFlags
- *
- * This function allows you to read the contents of a domain's
- * memory.
- *
- * The memory which is read is controlled by the 'start', 'size'
- * and 'flags' parameters.
- *
- * If 'flags' is VIR_MEMORY_VIRTUAL then the 'start' and 'size'
- * parameters are interpreted as virtual memory addresses for
- * whichever task happens to be running on the domain at the
- * moment. Although this sounds haphazard it is in fact what
- * you want in order to read Linux kernel state, because it
- * ensures that pointers in the kernel image can be interpreted
- * coherently.
- *
- * 'buffer' is the return buffer and must be at least 'size' bytes.
- * 'size' may be 0 to test if the call would succeed.
- *
- * NB. The remote driver imposes a 64K byte limit on 'size'.
- * For your program to be able to work reliably over a remote
- * connection you should split large requests to <= 65536 bytes.
- * However, with 0.9.13 this RPC limit has been raised to 1M byte.
- * Starting with version 1.0.6 the RPC limit has been raised again.
- * Now large requests up to 16M byte are supported.
- *
- * Returns: 0 in case of success or -1 in case of failure.
- */
-int
-virDomainMemoryPeek(virDomainPtr dom,
- unsigned long long start /* really 64 bits */,
- size_t size,
- void *buffer,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "start=%lld, size=%zi, buffer=%p, flags=%x",
- start, size, buffer, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- /* Note on access to physical memory: A VIR_MEMORY_PHYSICAL flag is
- * a possibility. However it isn't really useful unless the caller
- * can also access registers, particularly CR3 on x86 in order to
- * get the Page Table Directory. Since registers are different on
- * every architecture, that would imply another call to get the
- * machine registers.
- *
- * The QEMU driver handles VIR_MEMORY_VIRTUAL, mapping it
- * to the qemu 'memsave' command which does the virtual to physical
- * mapping inside qemu.
- *
- * The QEMU driver also handles VIR_MEMORY_PHYSICAL, mapping it
- * to the qemu 'pmemsave' command.
- *
- * At time of writing there is no Xen driver. However the Xen
- * hypervisor only lets you map physical pages from other domains,
- * and so the Xen driver would have to do the virtual to physical
- * mapping by chasing 2, 3 or 4-level page tables from the PTD.
- * There is example code in libxc (xc_translate_foreign_address)
- * which does this, although we cannot copy this code directly
- * because of incompatible licensing.
- */
-
- /* Exactly one of these two flags must be set. */
- if (!(flags & VIR_MEMORY_VIRTUAL) == !(flags & VIR_MEMORY_PHYSICAL)) {
- virReportInvalidArg(flags,
- _("flags in %s must include VIR_MEMORY_VIRTUAL or
"
- "VIR_MEMORY_PHYSICAL"),
- __FUNCTION__);
- goto error;
- }
-
- /* Allow size == 0 as an access test. */
- if (size > 0)
- virCheckNonNullArgGoto(buffer, error);
-
- if (conn->driver->domainMemoryPeek) {
- int ret;
- ret = conn->driver->domainMemoryPeek(dom, start, size,
- buffer, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetBlockInfo:
- * @domain: a domain object
- * @disk: path to the block device, or device shorthand
- * @info: pointer to a virDomainBlockInfo structure allocated by the user
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Extract information about a domain's block device.
- *
- * The @disk parameter is either an unambiguous source name of the
- * block device (the <source file='...'/> sub-element, such as
- * "/path/to/image"), or (since 0.9.5) the device target shorthand
- * (the <target dev='...'/> sub-element, such as "vda"). Valid
names
- * can be found by calling virDomainGetXMLDesc() and inspecting
- * elements within //domain/devices/disk.
- *
- * For QEMU domains, the allocation and physical virDomainBlockInfo
- * values returned will generally be the same, except when using a
- * non raw, block backing device, such as qcow2 for an active domain.
- * When the persistent domain is not active, QEMU will return the
- * default which is the same value for allocation and physical.
- *
- * Active QEMU domains can return an allocation value which is more
- * representative of the currently used blocks by the device compared
- * to the physical size of the device. Applications can use/monitor
- * the allocation value with the understanding that if the domain
- * becomes inactive during an attempt to get the value, the default
- * values will be returned. Thus, the application should check
- * after the call for the domain being inactive if the values are
- * the same. Optionally, the application could be watching for a
- * shutdown event and then ignore any values received afterwards.
- * This can be an issue when a domain is being migrated and the
- * exact timing of the domain being made inactive and check of
- * the allocation value results the default being returned. For
- * a transient domain in the similar situation, this call will return
- * -1 and an error message indicating the "domain is not running".
- *
- * The following is some pseudo code illustrating the call sequence:
- *
- * ...
- * virDomainPtr dom;
- * virDomainBlockInfo info;
- * char *device;
- * ...
- * // Either get a list of all domains or a specific domain
- * // via a virDomainLookupBy*() call.
- * //
- * // It's also required to fill in the device pointer, but that's
- * // specific to the implementation. For the purposes of this example
- * // a qcow2 backed device name string would need to be provided.
- * ...
- * // If the following call is made on a persistent domain with a
- * // qcow2 block backed block device, then it's possible the returned
- * // allocation equals the physical value. In that case, the domain
- * // that may have been active prior to calling has become inactive,
- * // such as is the case during a domain migration. Thus once we
- * // get data returned, check for active domain when the values are
- * // the same.
- * if (virDomainGetBlockInfo(dom, device, &info, 0) < 0)
- * goto failure;
- * if (info.allocation == info.physical) {
- * // If the domain is no longer active,
- * // then the defaults are being returned.
- * if (!virDomainIsActive())
- * goto ignore_return;
- * }
- * // Do something with the allocation and physical values
- * ...
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainGetBlockInfo(virDomainPtr domain, const char *disk,
- virDomainBlockInfoPtr info, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "info=%p, flags=%x", info, flags);
-
- virResetLastError();
-
- if (info)
- memset(info, 0, sizeof(*info));
-
- virCheckDomainReturn(domain, -1);
- virCheckNonNullArgGoto(disk, error);
- virCheckNonNullArgGoto(info, error);
-
- conn = domain->conn;
-
- if (conn->driver->domainGetBlockInfo) {
- int ret;
- ret = conn->driver->domainGetBlockInfo(domain, disk, info, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/************************************************************************
- * *
- * Handling of defined but not running domains *
- * *
- ************************************************************************/
-
-/**
- * virDomainDefineXML:
- * @conn: pointer to the hypervisor connection
- * @xml: the XML description for the domain, preferably in UTF-8
- *
- * Define 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
-virDomainDefineXML(virConnectPtr conn, const char *xml)
-{
- VIR_DEBUG("conn=%p, xml=%s", conn, xml);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, NULL);
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(xml, error);
-
- if (conn->driver->domainDefineXML) {
- virDomainPtr ret;
- ret = conn->driver->domainDefineXML(conn, xml);
- if (!ret)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return NULL;
-}
-
-
-/**
- * virDomainUndefine:
- * @domain: pointer to a defined domain
- *
- * Undefine a domain. If the domain is running, it's converted to
- * transient domain, without stopping it. If the domain is inactive,
- * the domain configuration is removed.
- *
- * If the domain has a managed save image (see
- * virDomainHasManagedSaveImage()), or if it is inactive and has any
- * snapshot metadata (see virDomainSnapshotNum()), then the undefine will
- * fail. See virDomainUndefineFlags() for more control.
- *
- * Returns 0 in case of success, -1 in case of error
- */
-int
-virDomainUndefine(virDomainPtr domain)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainUndefine) {
- int ret;
- ret = conn->driver->domainUndefine(domain);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainUndefineFlags:
- * @domain: pointer to a defined domain
- * @flags: bitwise-OR of supported virDomainUndefineFlagsValues
- *
- * Undefine a domain. If the domain is running, it's converted to
- * transient domain, without stopping it. If the domain is inactive,
- * the domain configuration is removed.
- *
- * If the domain has a managed save image (see virDomainHasManagedSaveImage()),
- * then including VIR_DOMAIN_UNDEFINE_MANAGED_SAVE in @flags will also remove
- * that file, and omitting the flag will cause the undefine process to fail.
- *
- * If the domain is inactive and has any snapshot metadata (see
- * virDomainSnapshotNum()), then including
- * VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA in @flags will also remove
- * that metadata. Omitting the flag will cause the undefine of an
- * inactive domain to fail. Active snapshots will retain snapshot
- * metadata until the (now-transient) domain halts, regardless of
- * whether this flag is present. On hypervisors where snapshots do
- * not use libvirt metadata, this flag has no effect.
- *
- * If the domain has any nvram specified, then including
- * VIR_DOMAIN_UNDEFINE_NVRAM will also remove that file, and omitting the flag
- * will cause the undefine process to fail.
- *
- * Returns 0 in case of success, -1 in case of error
- */
-int
-virDomainUndefineFlags(virDomainPtr domain,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainUndefineFlags) {
- int ret;
- ret = conn->driver->domainUndefineFlags(domain, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virConnectNumOfDefinedDomains:
- * @conn: pointer to the hypervisor connection
- *
- * Provides the number of defined but inactive domains.
- *
- * Returns the number of domain found or -1 in case of error
- */
-int
-virConnectNumOfDefinedDomains(virConnectPtr conn)
-{
- VIR_DEBUG("conn=%p", conn);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
-
- if (conn->driver->connectNumOfDefinedDomains) {
- int ret;
- ret = conn->driver->connectNumOfDefinedDomains(conn);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virConnectListDefinedDomains:
- * @conn: pointer to the hypervisor connection
- * @names: pointer to an array to store the names
- * @maxnames: size of the array
- *
- * list the defined but inactive domains, stores the pointers to the names
- * in @names
- *
- * For active domains, see virConnectListDomains(). For more control over
- * the results, see virConnectListAllDomains().
- *
- * Returns the number of names provided in the array or -1 in case of error.
- * Note that this command is inherently racy; a domain can be defined between
- * a call to virConnectNumOfDefinedDomains() and this call; you are only
- * guaranteed that all currently defined domains were listed if the return
- * is less than @maxids. The client must call free() on each returned name.
- */
-int
-virConnectListDefinedDomains(virConnectPtr conn, char **const names,
- int maxnames)
-{
- VIR_DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckNonNullArgGoto(names, error);
- virCheckNonNegativeArgGoto(maxnames, error);
-
- if (conn->driver->connectListDefinedDomains) {
- int ret;
- ret = conn->driver->connectListDefinedDomains(conn, names, maxnames);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virConnectListAllDomains:
- * @conn: Pointer to the hypervisor connection.
- * @domains: Pointer to a variable to store the array containing domain objects
- * or NULL if the list is not required (just returns number of guests).
- * @flags: bitwise-OR of virConnectListAllDomainsFlags
- *
- * Collect a possibly-filtered list of all domains, and return an allocated
- * array of information for each. This API solves the race inherent in
- * virConnectListDomains() and virConnectListDefinedDomains().
- *
- * Normally, all domains are returned; however, @flags can be used to
- * filter the results for a smaller list of targeted domains. The valid
- * flags are divided into groups, where each group contains bits that
- * describe mutually exclusive attributes of a domain, and where all bits
- * within a group describe all possible domains. Some hypervisors might
- * reject explicit bits from a group where the hypervisor cannot make a
- * distinction (for example, not all hypervisors can tell whether domains
- * have snapshots). For a group supported by a given hypervisor, the
- * behavior when no bits of a group are set is identical to the behavior
- * when all bits in that group are set. When setting bits from more than
- * one group, it is possible to select an impossible combination (such
- * as an inactive transient domain), in that case a hypervisor may return
- * either 0 or an error.
- *
- * The first group of @flags is VIR_CONNECT_LIST_DOMAINS_ACTIVE (online
- * domains) and VIR_CONNECT_LIST_DOMAINS_INACTIVE (offline domains).
- *
- * The next group of @flags is VIR_CONNECT_LIST_DOMAINS_PERSISTENT (defined
- * domains) and VIR_CONNECT_LIST_DOMAINS_TRANSIENT (running but not defined).
- *
- * The next group of @flags covers various domain states:
- * VIR_CONNECT_LIST_DOMAINS_RUNNING, VIR_CONNECT_LIST_DOMAINS_PAUSED,
- * VIR_CONNECT_LIST_DOMAINS_SHUTOFF, and a catch-all for all other states
- * (such as crashed, this catch-all covers the possibility of adding new
- * states).
- *
- * The remaining groups cover boolean attributes commonly asked about
- * domains; they include VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE and
- * VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE, for filtering based on whether
- * a managed save image exists; VIR_CONNECT_LIST_DOMAINS_AUTOSTART and
- * VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART, for filtering based on autostart;
- * VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT and
- * VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT, for filtering based on whether
- * a domain has snapshots.
- *
- * Example of usage:
- *
- * virDomainPtr *domains;
- * size_t i;
- * int ret;
- * unsigned int flags = VIR_CONNECT_LIST_DOMAINS_RUNNING |
- * VIR_CONNECT_LIST_DOMAINS_PERSISTENT;
- * ret = virConnectListAllDomains(conn, &domains, flags);
- * if (ret < 0)
- * error();
- * for (i = 0; i < ret; i++) {
- * do_something_with_domain(domains[i]);
- * //here or in a separate loop if needed
- * virDomainFree(domains[i]);
- * }
- * free(domains);
- *
- * Returns the number of domains found or -1 and sets domains to NULL in case of
- * error. On success, the array stored into @domains is guaranteed to have an
- * extra allocated element set to NULL but not included in the return count, to
- * make iteration easier. The caller is responsible for calling virDomainFree()
- * on each array element, then calling free() on @domains.
- */
-int
-virConnectListAllDomains(virConnectPtr conn,
- virDomainPtr **domains,
- unsigned int flags)
-{
- VIR_DEBUG("conn=%p, domains=%p, flags=%x", conn, domains, flags);
-
- virResetLastError();
-
- if (domains)
- *domains = NULL;
-
- virCheckConnectReturn(conn, -1);
-
- if (conn->driver->connectListAllDomains) {
- int ret;
- ret = conn->driver->connectListAllDomains(conn, domains, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainCreate:
- * @domain: pointer to a defined domain
- *
- * Launch a defined domain. If the call succeeds the domain moves from the
- * defined to the running domains pools. The domain will be paused only
- * if restoring from managed state created from a paused domain. For more
- * control, see virDomainCreateWithFlags().
- *
- * Returns 0 in case of success, -1 in case of error
- */
-int
-virDomainCreate(virDomainPtr domain)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainCreate) {
- int ret;
- ret = conn->driver->domainCreate(domain);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainCreateWithFlags:
- * @domain: pointer to a defined domain
- * @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.
- *
- * 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
-virDomainCreateWithFlags(virDomainPtr domain, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainCreateWithFlags) {
- int ret;
- ret = conn->driver->domainCreateWithFlags(domain, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- 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();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainCreateWithFiles) {
- int ret;
- ret = conn->driver->domainCreateWithFiles(domain,
- nfiles, files,
- flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetAutostart:
- * @domain: a domain object
- * @autostart: the value returned
- *
- * Provides a boolean value indicating whether the domain
- * configured to be automatically started when the host
- * machine boots.
- *
- * Returns -1 in case of error, 0 in case of success
- */
-int
-virDomainGetAutostart(virDomainPtr domain,
- int *autostart)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "autostart=%p", autostart);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- virCheckNonNullArgGoto(autostart, error);
-
- conn = domain->conn;
-
- if (conn->driver->domainGetAutostart) {
- int ret;
- ret = conn->driver->domainGetAutostart(domain, autostart);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainSetAutostart:
- * @domain: a domain object
- * @autostart: whether the domain should be automatically started 0 or 1
- *
- * Configure the domain to be automatically started
- * when the host machine boots.
- *
- * Returns -1 in case of error, 0 in case of success
- */
-int
-virDomainSetAutostart(virDomainPtr domain,
- int autostart)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "autostart=%d", autostart);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainSetAutostart) {
- int ret;
- ret = conn->driver->domainSetAutostart(domain, autostart);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainInjectNMI:
- * @domain: pointer to domain object, or NULL for Domain0
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Send NMI to the guest
- *
- * Returns 0 in case of success, -1 in case of failure.
- */
-int
-virDomainInjectNMI(virDomainPtr domain, unsigned int flags)
-{
- virConnectPtr conn;
- VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainInjectNMI) {
- int ret;
- ret = conn->driver->domainInjectNMI(domain, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainSendKey:
- * @domain: pointer to domain object, or NULL for Domain0
- * @codeset: the code set of keycodes, from virKeycodeSet
- * @holdtime: the duration (in milliseconds) that the keys will be held
- * @keycodes: array of keycodes
- * @nkeycodes: number of keycodes, up to VIR_DOMAIN_SEND_KEY_MAX_KEYS
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Send key(s) to the guest.
- *
- * Returns 0 in case of success, -1 in case of failure.
- */
-int
-virDomainSendKey(virDomainPtr domain,
- unsigned int codeset,
- unsigned int holdtime,
- unsigned int *keycodes,
- int nkeycodes,
- unsigned int flags)
-{
- virConnectPtr conn;
- VIR_DOMAIN_DEBUG(domain, "codeset=%u, holdtime=%u, nkeycodes=%u,
flags=%x",
- codeset, holdtime, nkeycodes, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(keycodes, error);
- virCheckPositiveArgGoto(nkeycodes, error);
-
- if (nkeycodes > VIR_DOMAIN_SEND_KEY_MAX_KEYS) {
- virReportInvalidArg(nkeycodes,
- _("nkeycodes in %s must be <= %d"),
- __FUNCTION__, VIR_DOMAIN_SEND_KEY_MAX_KEYS);
- goto error;
- }
-
- if (conn->driver->domainSendKey) {
- int ret;
- ret = conn->driver->domainSendKey(domain, codeset, holdtime,
- keycodes, nkeycodes, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainSendProcessSignal:
- * @domain: pointer to domain object
- * @pid_value: a positive integer process ID, or negative integer process group ID
- * @signum: a signal from the virDomainProcessSignal enum
- * @flags: one of the virDomainProcessSignalFlag values
- *
- * Send a signal to the designated process in the guest
- *
- * The signal numbers must be taken from the virDomainProcessSignal
- * enum. These will be translated to the corresponding signal
- * number for the guest OS, by the guest agent delivering the
- * signal. If there is no mapping from virDomainProcessSignal to
- * the native OS signals, this API will report an error.
- *
- * If @pid_value is an integer greater than zero, it is
- * treated as a process ID. If @pid_value is an integer
- * less than zero, it is treated as a process group ID.
- * All the @pid_value numbers are from the container/guest
- * namespace. The value zero is not valid.
- *
- * Not all hypervisors will support sending signals to
- * arbitrary processes or process groups. If this API is
- * implemented the minimum requirement is to be able to
- * use @pid_value == 1 (i.e. kill init). No other value is
- * required to be supported.
- *
- * If the @signum is VIR_DOMAIN_PROCESS_SIGNAL_NOP then this
- * API will simply report whether the process is running in
- * the container/guest.
- *
- * Returns 0 in case of success, -1 in case of failure.
- */
-int
-virDomainSendProcessSignal(virDomainPtr domain,
- long long pid_value,
- unsigned int signum,
- unsigned int flags)
-{
- virConnectPtr conn;
- VIR_DOMAIN_DEBUG(domain, "pid=%lld, signum=%u flags=%x",
- pid_value, signum, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckNonZeroArgGoto(pid_value, error);
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainSendProcessSignal) {
- int ret;
- ret = conn->driver->domainSendProcessSignal(domain,
- pid_value,
- signum,
- flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainSetVcpus:
- * @domain: pointer to domain object, or NULL for Domain0
- * @nvcpus: the new number of virtual CPUs for this domain
- *
- * Dynamically change the number of virtual CPUs used by the domain.
- * Note that this call may fail if the underlying virtualization hypervisor
- * does not support it or if growing the number is arbitrarily limited.
- * This function may require privileged access to the hypervisor.
- *
- * Note that if this call is executed before the guest has finished booting,
- * the guest may fail to process the change.
- *
- * This command only changes the runtime configuration of the domain,
- * so can only be called on an active domain. It is hypervisor-dependent
- * whether it also affects persistent configuration; for more control,
- * use virDomainSetVcpusFlags().
- *
- * Returns 0 in case of success, -1 in case of failure.
- */
-int
-virDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "nvcpus=%u", nvcpus);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonZeroArgGoto(nvcpus, error);
-
- if (conn->driver->domainSetVcpus) {
- int ret;
- ret = conn->driver->domainSetVcpus(domain, nvcpus);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainSetVcpusFlags:
- * @domain: pointer to domain object, or NULL for Domain0
- * @nvcpus: the new number of virtual CPUs for this domain, must be at least 1
- * @flags: bitwise-OR of virDomainVcpuFlags
- *
- * Dynamically change the number of virtual CPUs used by the domain.
- * Note that this call may fail if the underlying virtualization hypervisor
- * does not support it or if growing the number is arbitrarily limited.
- * This function may require privileged access to the hypervisor.
- *
- * @flags may include VIR_DOMAIN_AFFECT_LIVE to affect a running
- * domain (which may fail if domain is not active), or
- * VIR_DOMAIN_AFFECT_CONFIG to affect the next boot via the XML
- * description of the domain. Both flags may be set.
- * If neither flag is specified (that is, @flags is VIR_DOMAIN_AFFECT_CURRENT),
- * then an inactive domain modifies persistent setup, while an active domain
- * is hypervisor-dependent on whether just live or both live and persistent
- * state is changed.
- *
- * Note that if this call is executed before the guest has finished booting,
- * the guest may fail to process the change.
- *
- * If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then
- * VIR_DOMAIN_AFFECT_LIVE must be clear, and only the maximum virtual
- * CPU limit is altered; generally, this value must be less than or
- * equal to virConnectGetMaxVcpus(). Otherwise, this call affects the
- * current virtual CPU limit, which must be less than or equal to the
- * maximum limit.
- *
- * If @flags includes VIR_DOMAIN_VCPU_GUEST, then the state of processors is
- * modified inside the guest instead of the hypervisor. This flag can only
- * be used with live guests and is incompatible with VIR_DOMAIN_VCPU_MAXIMUM.
- * The usage of this flag may require a guest agent configured.
- *
- * Not all hypervisors can support all flag combinations.
- *
- * Returns 0 in case of success, -1 in case of failure.
- */
-int
-virDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "nvcpus=%u, flags=%x", nvcpus, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- virCheckReadOnlyGoto(domain->conn->flags, error);
-
- if (flags & VIR_DOMAIN_VCPU_GUEST &&
- flags & VIR_DOMAIN_VCPU_MAXIMUM) {
- virReportInvalidArg(flags,
- _("flags 'VIR_DOMAIN_VCPU_MAXIMUM' and "
- "'VIR_DOMAIN_VCPU_GUEST' in '%s' are
mutually "
- "exclusive"), __FUNCTION__);
- goto error;
- }
-
- virCheckNonZeroArgGoto(nvcpus, error);
-
- if ((unsigned short) nvcpus != nvcpus) {
- virReportError(VIR_ERR_OVERFLOW, _("input too large: %u"), nvcpus);
- goto error;
- }
- conn = domain->conn;
-
- if (conn->driver->domainSetVcpusFlags) {
- int ret;
- ret = conn->driver->domainSetVcpusFlags(domain, nvcpus, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetVcpusFlags:
- * @domain: pointer to domain object, or NULL for Domain0
- * @flags: bitwise-OR of virDomainVcpuFlags
- *
- * Query the number of virtual CPUs used by the domain. Note that
- * this call may fail if the underlying virtualization hypervisor does
- * not support it. This function may require privileged access to the
- * hypervisor.
- *
- * If @flags includes VIR_DOMAIN_AFFECT_LIVE, this will query a
- * running domain (which will fail if domain is not active); if
- * it includes VIR_DOMAIN_AFFECT_CONFIG, this will query the XML
- * description of the domain. It is an error to set both flags.
- * If neither flag is set (that is, VIR_DOMAIN_AFFECT_CURRENT),
- * then the configuration queried depends on whether the domain
- * is currently running.
- *
- * If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then the maximum
- * virtual CPU limit is queried. Otherwise, this call queries the
- * current virtual CPU count.
- *
- * If @flags includes VIR_DOMAIN_VCPU_GUEST, then the state of the processors
- * is queried in the guest instead of the hypervisor. This flag is only usable
- * on live domains. Guest agent may be needed for this flag to be available.
- *
- * Returns the number of vCPUs in case of success, -1 in case of failure.
- */
-int
-virDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- if (flags & VIR_DOMAIN_VCPU_GUEST)
- virCheckReadOnlyGoto(conn->flags, error);
-
- /* At most one of these two flags should be set. */
- if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
- (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
- virReportInvalidArg(flags,
- _("flags 'affect live' and 'affect
config' in %s "
- "are mutually exclusive"),
- __FUNCTION__);
- goto error;
- }
-
- if (conn->driver->domainGetVcpusFlags) {
- int ret;
- ret = conn->driver->domainGetVcpusFlags(domain, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainPinVcpu:
- * @domain: pointer to domain object, or NULL for Domain0
- * @vcpu: virtual CPU number
- * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN)
- * Each bit set to 1 means that corresponding CPU is usable.
- * Bytes are stored in little-endian order: CPU0-7, 8-15...
- * In each byte, lowest CPU number is least significant bit.
- * @maplen: number of bytes in cpumap, from 1 up to size of CPU map in
- * underlying virtualization system (Xen...).
- * If maplen < size, missing bytes are set to zero.
- * If maplen > size, failure code is returned.
- *
- * Dynamically change the real CPUs which can be allocated to a virtual CPU.
- * This function may require privileged access to the hypervisor.
- *
- * This command only changes the runtime configuration of the domain,
- * so can only be called on an active domain.
- *
- * Returns 0 in case of success, -1 in case of failure.
- */
-int
-virDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
- unsigned char *cpumap, int maplen)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "vcpu=%u, cpumap=%p, maplen=%d",
- vcpu, cpumap, maplen);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(cpumap, error);
- virCheckPositiveArgGoto(maplen, error);
-
- if ((unsigned short) vcpu != vcpu) {
- virReportError(VIR_ERR_OVERFLOW, _("input too large: %u"), vcpu);
- goto error;
- }
-
- if (conn->driver->domainPinVcpu) {
- int ret;
- ret = conn->driver->domainPinVcpu(domain, vcpu, cpumap, maplen);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainPinVcpuFlags:
- * @domain: pointer to domain object, or NULL for Domain0
- * @vcpu: virtual CPU number
- * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN)
- * Each bit set to 1 means that corresponding CPU is usable.
- * Bytes are stored in little-endian order: CPU0-7, 8-15...
- * In each byte, lowest CPU number is least significant bit.
- * @maplen: number of bytes in cpumap, from 1 up to size of CPU map in
- * underlying virtualization system (Xen...).
- * If maplen < size, missing bytes are set to zero.
- * If maplen > size, failure code is returned.
- * @flags: bitwise-OR of virDomainModificationImpact
- *
- * Dynamically change the real CPUs which can be allocated to a virtual CPU.
- * This function may require privileged access to the hypervisor.
- *
- * @flags may include VIR_DOMAIN_AFFECT_LIVE or VIR_DOMAIN_AFFECT_CONFIG.
- * Both flags may be set.
- * If VIR_DOMAIN_AFFECT_LIVE is set, the change affects a running domain
- * and may fail if domain is not alive.
- * If VIR_DOMAIN_AFFECT_CONFIG is set, the change affects persistent state,
- * and will fail for transient domains. If neither flag is specified (that is,
- * @flags is VIR_DOMAIN_AFFECT_CURRENT), then an inactive domain modifies
- * persistent setup, while an active domain is hypervisor-dependent on whether
- * just live or both live and persistent state is changed.
- * Not all hypervisors can support all flag combinations.
- *
- * See also virDomainGetVcpuPinInfo for querying this information.
- *
- * Returns 0 in case of success, -1 in case of failure.
- *
- */
-int
-virDomainPinVcpuFlags(virDomainPtr domain, unsigned int vcpu,
- unsigned char *cpumap, int maplen, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "vcpu=%u, cpumap=%p, maplen=%d, flags=%x",
- vcpu, cpumap, maplen, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(cpumap, error);
- virCheckPositiveArgGoto(maplen, error);
-
- if ((unsigned short) vcpu != vcpu) {
- virReportError(VIR_ERR_OVERFLOW, _("input too large: %u"), vcpu);
- goto error;
- }
-
- if (conn->driver->domainPinVcpuFlags) {
- int ret;
- ret = conn->driver->domainPinVcpuFlags(domain, vcpu, cpumap, maplen,
flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetVcpuPinInfo:
- * @domain: pointer to domain object, or NULL for Domain0
- * @ncpumaps: the number of cpumap (listed first to match virDomainGetVcpus)
- * @cpumaps: pointer to a bit map of real CPUs for all vcpus of this
- * domain (in 8-bit bytes) (OUT)
- * It's assumed there is <ncpumaps> cpumap in cpumaps array.
- * The memory allocated to cpumaps must be (ncpumaps * maplen) bytes
- * (ie: calloc(ncpumaps, maplen)).
- * One cpumap inside cpumaps has the format described in
- * virDomainPinVcpu() API.
- * Must not be NULL.
- * @maplen: the number of bytes in one cpumap, from 1 up to size of CPU map.
- * Must be positive.
- * @flags: bitwise-OR of virDomainModificationImpact
- * Must not be VIR_DOMAIN_AFFECT_LIVE and
- * VIR_DOMAIN_AFFECT_CONFIG concurrently.
- *
- * Query the CPU affinity setting of all virtual CPUs of domain, store it
- * in cpumaps.
- *
- * Returns the number of virtual CPUs in case of success,
- * -1 in case of failure.
- */
-int
-virDomainGetVcpuPinInfo(virDomainPtr domain, int ncpumaps,
- unsigned char *cpumaps, int maplen, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "ncpumaps=%d, cpumaps=%p, maplen=%d, flags=%x",
- ncpumaps, cpumaps, maplen, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckNonNullArgGoto(cpumaps, error);
- virCheckPositiveArgGoto(ncpumaps, error);
- virCheckPositiveArgGoto(maplen, error);
-
- if (INT_MULTIPLY_OVERFLOW(ncpumaps, maplen)) {
- virReportError(VIR_ERR_OVERFLOW, _("input too large: %d * %d"),
- ncpumaps, maplen);
- goto error;
- }
-
- /* At most one of these two flags should be set. */
- if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
- (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
- virReportInvalidArg(flags,
- _("flags 'affect live' and 'affect
config' in %s "
- "are mutually exclusive"),
- __FUNCTION__);
- goto error;
- }
-
- if (conn->driver->domainGetVcpuPinInfo) {
- int ret;
- ret = conn->driver->domainGetVcpuPinInfo(domain, ncpumaps,
- cpumaps, maplen, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainPinEmulator:
- * @domain: pointer to domain object, or NULL for Domain0
- * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN)
- * Each bit set to 1 means that corresponding CPU is usable.
- * Bytes are stored in little-endian order: CPU0-7, 8-15...
- * In each byte, lowest CPU number is least significant bit.
- * @maplen: number of bytes in cpumap, from 1 up to size of CPU map in
- * underlying virtualization system (Xen...).
- * If maplen < size, missing bytes are set to zero.
- * If maplen > size, failure code is returned.
- * @flags: bitwise-OR of virDomainModificationImpact
- *
- * Dynamically change the real CPUs which can be allocated to all emulator
- * threads. This function may require privileged access to the hypervisor.
- *
- * @flags may include VIR_DOMAIN_AFFECT_LIVE or VIR_DOMAIN_AFFECT_CONFIG.
- * Both flags may be set.
- * If VIR_DOMAIN_AFFECT_LIVE is set, the change affects a running domain
- * and may fail if domain is not alive.
- * If VIR_DOMAIN_AFFECT_CONFIG is set, the change affects persistent state,
- * and will fail for transient domains. If neither flag is specified (that is,
- * @flags is VIR_DOMAIN_AFFECT_CURRENT), then an inactive domain modifies
- * persistent setup, while an active domain is hypervisor-dependent on whether
- * just live or both live and persistent state is changed.
- * Not all hypervisors can support all flag combinations.
- *
- * See also virDomainGetEmulatorPinInfo for querying this information.
- *
- * Returns 0 in case of success, -1 in case of failure.
- *
- */
-int
-virDomainPinEmulator(virDomainPtr domain, unsigned char *cpumap,
- int maplen, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "cpumap=%p, maplen=%d, flags=%x",
- cpumap, maplen, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- virCheckNonNullArgGoto(cpumap, error);
- virCheckPositiveArgGoto(maplen, error);
-
- if (conn->driver->domainPinEmulator) {
- int ret;
- ret = conn->driver->domainPinEmulator(domain, cpumap, maplen, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetEmulatorPinInfo:
- * @domain: pointer to domain object, or NULL for Domain0
- * @cpumap: pointer to a bit map of real CPUs for all emulator threads of
- * this domain (in 8-bit bytes) (OUT)
- * There is only one cpumap for all emulator threads.
- * Must not be NULL.
- * @maplen: the number of bytes in one cpumap, from 1 up to size of CPU map.
- * Must be positive.
- * @flags: bitwise-OR of virDomainModificationImpact
- * Must not be VIR_DOMAIN_AFFECT_LIVE and
- * VIR_DOMAIN_AFFECT_CONFIG concurrently.
- *
- * Query the CPU affinity setting of all emulator threads of domain, store
- * it in cpumap.
- *
- * Returns 1 in case of success,
- * 0 in case of no emulator threads are pined to pcpus,
- * -1 in case of failure.
- */
-int
-virDomainGetEmulatorPinInfo(virDomainPtr domain, unsigned char *cpumap,
- int maplen, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "cpumap=%p, maplen=%d, flags=%x",
- cpumap, maplen, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
-
- virCheckNonNullArgGoto(cpumap, error);
- virCheckPositiveArgGoto(maplen, error);
-
- /* At most one of these two flags should be set. */
- if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
- (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
- virReportInvalidArg(flags,
- _("flags 'affect live' and 'affect
config' in %s "
- "are mutually exclusive"),
- __FUNCTION__);
- goto error;
- }
- conn = domain->conn;
-
- if (conn->driver->domainGetEmulatorPinInfo) {
- int ret;
- ret = conn->driver->domainGetEmulatorPinInfo(domain, cpumap,
- maplen, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetVcpus:
- * @domain: pointer to domain object, or NULL for Domain0
- * @info: pointer to an array of virVcpuInfo structures (OUT)
- * @maxinfo: number of structures in info array
- * @cpumaps: pointer to a bit map of real CPUs for all vcpus of this
- * domain (in 8-bit bytes) (OUT)
- * If cpumaps is NULL, then no cpumap information is returned by the API.
- * It's assumed there is <maxinfo> cpumap in cpumaps array.
- * The memory allocated to cpumaps must be (maxinfo * maplen) bytes
- * (ie: calloc(maxinfo, maplen)).
- * One cpumap inside cpumaps has the format described in
- * virDomainPinVcpu() API.
- * @maplen: number of bytes in one cpumap, from 1 up to size of CPU map in
- * underlying virtualization system (Xen...).
- * Must be zero when cpumaps is NULL and positive when it is non-NULL.
- *
- * Extract information about virtual CPUs of domain, store it in info array
- * and also in cpumaps if this pointer isn't NULL. This call may fail
- * on an inactive domain.
- *
- * See also virDomainGetVcpuPinInfo for querying just cpumaps, including on
- * an inactive domain.
- *
- * Returns the number of info filled in case of success, -1 in case of failure.
- */
-int
-virDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo,
- unsigned char *cpumaps, int maplen)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "info=%p, maxinfo=%d, cpumaps=%p, maplen=%d",
- info, maxinfo, cpumaps, maplen);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- virCheckNonNullArgGoto(info, error);
- virCheckPositiveArgGoto(maxinfo, error);
-
- /* Ensure that domainGetVcpus (aka remoteDomainGetVcpus) does not
- try to memcpy anything into a NULL pointer. */
- if (cpumaps)
- virCheckPositiveArgGoto(maplen, error);
- else
- virCheckZeroArgGoto(maplen, error);
-
- if (cpumaps && INT_MULTIPLY_OVERFLOW(maxinfo, maplen)) {
- virReportError(VIR_ERR_OVERFLOW, _("input too large: %d * %d"),
- maxinfo, maplen);
- goto error;
- }
-
- conn = domain->conn;
-
- if (conn->driver->domainGetVcpus) {
- int ret;
- ret = conn->driver->domainGetVcpus(domain, info, maxinfo,
- cpumaps, maplen);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetMaxVcpus:
- * @domain: pointer to domain object
- *
- * Provides the maximum number of virtual CPUs supported for
- * the guest VM. If the guest is inactive, this is basically
- * the same as virConnectGetMaxVcpus(). If the guest is running
- * this will reflect the maximum number of virtual CPUs the
- * guest was booted with. For more details, see virDomainGetVcpusFlags().
- *
- * Returns the maximum of virtual CPU or -1 in case of error.
- */
-int
-virDomainGetMaxVcpus(virDomainPtr domain)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- if (conn->driver->domainGetMaxVcpus) {
- int ret;
- ret = conn->driver->domainGetMaxVcpus(domain);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetSecurityLabel:
- * @domain: a domain object
- * @seclabel: pointer to a virSecurityLabel structure
- *
- * Extract security label of an active domain. The 'label' field
- * in the @seclabel argument will be initialized to the empty
- * string if the domain is not running under a security model.
- *
- * Returns 0 in case of success, -1 in case of failure
- */
-int
-virDomainGetSecurityLabel(virDomainPtr domain, virSecurityLabelPtr seclabel)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "seclabel=%p", seclabel);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckNonNullArgGoto(seclabel, error);
-
- if (conn->driver->domainGetSecurityLabel) {
- int ret;
- ret = conn->driver->domainGetSecurityLabel(domain, seclabel);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetSecurityLabelList:
- * @domain: a domain object
- * @seclabels: will be auto-allocated and filled with domains' security labels.
- * Caller must free memory on return.
- *
- * Extract the security labels of an active domain. The 'label' field
- * in the @seclabels argument will be initialized to the empty
- * string if the domain is not running under a security model.
- *
- * Returns number of elemnets in @seclabels on success, -1 in case of failure.
- */
-int
-virDomainGetSecurityLabelList(virDomainPtr domain,
- virSecurityLabelPtr* seclabels)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "seclabels=%p", seclabels);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
-
- virCheckNonNullArgGoto(seclabels, error);
-
- conn = domain->conn;
-
- if (conn->driver->domainGetSecurityLabelList) {
- int ret;
- ret = conn->driver->domainGetSecurityLabelList(domain, seclabels);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-/**
- * virDomainSetMetadata:
- * @domain: a domain object
- * @type: type of metadata, from virDomainMetadataType
- * @metadata: new metadata text
- * @key: XML namespace key, or NULL
- * @uri: XML namespace URI, or NULL
- * @flags: bitwise-OR of virDomainModificationImpact
- *
- * Sets the appropriate domain element given by @type to the
- * value of @metadata. A @type of VIR_DOMAIN_METADATA_DESCRIPTION
- * is free-form text; VIR_DOMAIN_METADATA_TITLE is free-form, but no
- * newlines are permitted, and should be short (although the length is
- * not enforced). For these two options @key and @uri are irrelevant and
- * must be set to NULL.
- *
- * For type VIR_DOMAIN_METADATA_ELEMENT @metadata must be well-formed
- * XML belonging to namespace defined by @uri with local name @key.
- *
- * Passing NULL for @metadata says to remove that element from the
- * domain XML (passing the empty string leaves the element present).
- *
- * The resulting metadata will be present in virDomainGetXMLDesc(),
- * as well as quick access through virDomainGetMetadata().
- *
- * @flags controls whether the live domain, persistent configuration,
- * or both will be modified.
- *
- * Returns 0 on success, -1 in case of failure.
- */
-int
-virDomainSetMetadata(virDomainPtr domain,
- int type,
- const char *metadata,
- const char *key,
- const char *uri,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain,
- "type=%d, metadata='%s', key='%s',
uri='%s', flags=%x",
- type, NULLSTR(metadata), NULLSTR(key), NULLSTR(uri),
- flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- switch (type) {
- case VIR_DOMAIN_METADATA_TITLE:
- if (metadata && strchr(metadata, '\n')) {
- virReportInvalidArg(metadata,
- _("metadata title in %s can't contain "
- "newlines"),
- __FUNCTION__);
- goto error;
- }
- /* fallthrough */
- case VIR_DOMAIN_METADATA_DESCRIPTION:
- virCheckNullArgGoto(uri, error);
- virCheckNullArgGoto(key, error);
- break;
- case VIR_DOMAIN_METADATA_ELEMENT:
- virCheckNonNullArgGoto(uri, error);
- if (metadata)
- virCheckNonNullArgGoto(key, error);
- break;
- default:
- /* For future expansion */
- break;
- }
-
- if (conn->driver->domainSetMetadata) {
- int ret;
- ret = conn->driver->domainSetMetadata(domain, type, metadata, key, uri,
- flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetMetadata:
- * @domain: a domain object
- * @type: type of metadata, from virDomainMetadataType
- * @uri: XML namespace identifier
- * @flags: bitwise-OR of virDomainModificationImpact
- *
- * Retrieves the appropriate domain element given by @type.
- * If VIR_DOMAIN_METADATA_ELEMENT is requested parameter @uri
- * must be set to the name of the namespace the requested elements
- * belong to, otherwise must be NULL.
- *
- * If an element of the domain XML is not present, the resulting
- * error will be VIR_ERR_NO_DOMAIN_METADATA. This method forms
- * a shortcut for seeing information from virDomainSetMetadata()
- * without having to go through virDomainGetXMLDesc().
- *
- * @flags controls whether the live domain or persistent
- * configuration will be queried.
- *
- * Returns the metadata string on success (caller must free),
- * or NULL in case of failure.
- */
-char *
-virDomainGetMetadata(virDomainPtr domain,
- int type,
- const char *uri,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "type=%d, uri='%s', flags=%x",
- type, NULLSTR(uri), flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, NULL);
-
- if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
- (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
- virReportInvalidArg(flags,
- _("flags 'affect live' and 'affect
config' in %s "
- "are mutually exclusive"),
- __FUNCTION__);
- goto error;
- }
-
- switch (type) {
- case VIR_DOMAIN_METADATA_TITLE:
- case VIR_DOMAIN_METADATA_DESCRIPTION:
- virCheckNullArgGoto(uri, error);
- break;
- case VIR_DOMAIN_METADATA_ELEMENT:
- virCheckNonNullArgGoto(uri, error);
- break;
- default:
- /* For future expansion */
- break;
- }
-
- conn = domain->conn;
-
- if (conn->driver->domainGetMetadata) {
- char *ret;
- if (!(ret = conn->driver->domainGetMetadata(domain, type, uri, flags)))
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return NULL;
-}
-
-
-/**
- * virNodeGetSecurityModel:
- * @conn: a connection object
- * @secmodel: pointer to a virSecurityModel structure
- *
- * Extract the security model of a hypervisor. The 'model' field
- * in the @secmodel argument may be initialized to the empty
- * string if the driver has not activated a security model.
- *
- * Returns 0 in case of success, -1 in case of failure
- */
-int
-virNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr secmodel)
-{
- VIR_DEBUG("conn=%p secmodel=%p", conn, secmodel);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckNonNullArgGoto(secmodel, error);
-
- if (conn->driver->nodeGetSecurityModel) {
- int ret;
- ret = conn->driver->nodeGetSecurityModel(conn, secmodel);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainAttachDevice:
- * @domain: pointer to domain object
- * @xml: pointer to XML description of one device
- *
- * Create a virtual device attachment to backend. This function,
- * having hotplug semantics, is only allowed on an active domain.
- *
- * For compatibility, this method can also be used to change the media
- * in an existing CDROM/Floppy device, however, applications are
- * recommended to use the virDomainUpdateDeviceFlag method instead.
- *
- * Be aware that hotplug changes might not persist across a domain going
- * into S4 state (also known as hibernation) unless you also modify the
- * persistent domain definition.
- *
- * Returns 0 in case of success, -1 in case of failure.
- */
-int
-virDomainAttachDevice(virDomainPtr domain, const char *xml)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "xml=%s", xml);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckNonNullArgGoto(xml, error);
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainAttachDevice) {
- int ret;
- ret = conn->driver->domainAttachDevice(domain, xml);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainAttachDeviceFlags:
- * @domain: pointer to domain object
- * @xml: pointer to XML description of one device
- * @flags: bitwise-OR of virDomainDeviceModifyFlags
- *
- * Attach a virtual device to a domain, using the flags parameter
- * to control how the device is attached. VIR_DOMAIN_AFFECT_CURRENT
- * specifies that the device allocation is made based on current domain
- * state. VIR_DOMAIN_AFFECT_LIVE specifies that the device shall be
- * allocated to the active domain instance only and is not added to the
- * persisted domain configuration. VIR_DOMAIN_AFFECT_CONFIG
- * specifies that the device shall be allocated to the persisted domain
- * configuration only. Note that the target hypervisor must return an
- * error if unable to satisfy flags. E.g. the hypervisor driver will
- * return failure if LIVE is specified but it only supports modifying the
- * persisted device allocation.
- *
- * For compatibility, this method can also be used to change the media
- * in an existing CDROM/Floppy device, however, applications are
- * recommended to use the virDomainUpdateDeviceFlag method instead.
- *
- * Be aware that hotplug changes might not persist across a domain going
- * into S4 state (also known as hibernation) unless you also modify the
- * persistent domain definition.
- *
- * Returns 0 in case of success, -1 in case of failure.
- */
-int
-virDomainAttachDeviceFlags(virDomainPtr domain,
- const char *xml, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "xml=%s, flags=%x", xml, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckNonNullArgGoto(xml, error);
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainAttachDeviceFlags) {
- int ret;
- ret = conn->driver->domainAttachDeviceFlags(domain, xml, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainDetachDevice:
- * @domain: pointer to domain object
- * @xml: pointer to XML description of one device
- *
- * Destroy a virtual device attachment to backend. This function,
- * having hot-unplug semantics, is only allowed on an active domain.
- *
- * Be aware that hotplug changes might not persist across a domain going
- * into S4 state (also known as hibernation) unless you also modify the
- * persistent domain definition.
- *
- * Returns 0 in case of success, -1 in case of failure.
- */
-int
-virDomainDetachDevice(virDomainPtr domain, const char *xml)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "xml=%s", xml);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckNonNullArgGoto(xml, error);
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainDetachDevice) {
- int ret;
- ret = conn->driver->domainDetachDevice(domain, xml);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainDetachDeviceFlags:
- * @domain: pointer to domain object
- * @xml: pointer to XML description of one device
- * @flags: bitwise-OR of virDomainDeviceModifyFlags
- *
- * Detach a virtual device from a domain, using the flags parameter
- * to control how the device is detached. VIR_DOMAIN_AFFECT_CURRENT
- * specifies that the device allocation is removed based on current domain
- * state. VIR_DOMAIN_AFFECT_LIVE specifies that the device shall be
- * deallocated from the active domain instance only and is not from the
- * persisted domain configuration. VIR_DOMAIN_AFFECT_CONFIG
- * specifies that the device shall be deallocated from the persisted domain
- * configuration only. Note that the target hypervisor must return an
- * error if unable to satisfy flags. E.g. the hypervisor driver will
- * return failure if LIVE is specified but it only supports removing the
- * persisted device allocation.
- *
- * Some hypervisors may prevent this operation if there is a current
- * block copy operation on the device being detached; in that case,
- * use virDomainBlockJobAbort() to stop the block copy first.
- *
- * Beware that depending on the hypervisor and device type, detaching a device
- * from a running domain may be asynchronous. That is, calling
- * virDomainDetachDeviceFlags may just request device removal while the device
- * is actually removed later (in cooperation with a guest OS). Previously,
- * this fact was ignored and the device could have been removed from domain
- * configuration before it was actually removed by the hypervisor causing
- * various failures on subsequent operations. To check whether the device was
- * successfully removed, either recheck domain configuration using
- * virDomainGetXMLDesc() or add handler for VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED
- * event. In case the device is already gone when virDomainDetachDeviceFlags
- * returns, the event is delivered before this API call ends. To help existing
- * clients work better in most cases, this API will try to transform an
- * asynchronous device removal that finishes shortly after the request into
- * a synchronous removal. In other words, this API may wait a bit for the
- * removal to complete in case it was not synchronous.
- *
- * Be aware that hotplug changes might not persist across a domain going
- * into S4 state (also known as hibernation) unless you also modify the
- * persistent domain definition.
- *
- * Returns 0 in case of success, -1 in case of failure.
- */
-int
-virDomainDetachDeviceFlags(virDomainPtr domain,
- const char *xml, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "xml=%s, flags=%x", xml, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckNonNullArgGoto(xml, error);
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainDetachDeviceFlags) {
- int ret;
- ret = conn->driver->domainDetachDeviceFlags(domain, xml, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainUpdateDeviceFlags:
- * @domain: pointer to domain object
- * @xml: pointer to XML description of one device
- * @flags: bitwise-OR of virDomainDeviceModifyFlags
- *
- * Change a virtual device on a domain, using the flags parameter
- * to control how the device is changed. VIR_DOMAIN_AFFECT_CURRENT
- * specifies that the device change is made based on current domain
- * state. VIR_DOMAIN_AFFECT_LIVE specifies that the device shall be
- * changed on the active domain instance only and is not added to the
- * persisted domain configuration. VIR_DOMAIN_AFFECT_CONFIG
- * specifies that the device shall be changed on the persisted domain
- * configuration only. Note that the target hypervisor must return an
- * error if unable to satisfy flags. E.g. the hypervisor driver will
- * return failure if LIVE is specified but it only supports modifying the
- * persisted device allocation.
- *
- * This method is used for actions such changing CDROM/Floppy device
- * media, altering the graphics configuration such as password,
- * reconfiguring the NIC device backend connectivity, etc.
- *
- * Returns 0 in case of success, -1 in case of failure.
- */
-int
-virDomainUpdateDeviceFlags(virDomainPtr domain,
- const char *xml, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "xml=%s, flags=%x", xml, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckNonNullArgGoto(xml, error);
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainUpdateDeviceFlags) {
- int ret;
- ret = conn->driver->domainUpdateDeviceFlags(domain, xml, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virNodeGetCellsFreeMemory:
- * @conn: pointer to the hypervisor connection
- * @freeMems: pointer to the array of unsigned long long
- * @startCell: index of first cell to return freeMems info on.
- * @maxCells: Maximum number of cells for which freeMems information can
- * be returned.
- *
- * This call returns the amount of free memory in one or more NUMA cells.
- * The @freeMems array must be allocated by the caller and will be filled
- * with the amount of free memory in bytes for each cell requested,
- * starting with startCell (in freeMems[0]), up to either
- * (startCell + maxCells), or the number of additional cells in the node,
- * whichever is smaller.
- *
- * Returns the number of entries filled in freeMems, or -1 in case of error.
- */
-int
-virNodeGetCellsFreeMemory(virConnectPtr conn, unsigned long long *freeMems,
- int startCell, int maxCells)
-{
- VIR_DEBUG("conn=%p, freeMems=%p, startCell=%d, maxCells=%d",
- conn, freeMems, startCell, maxCells);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckNonNullArgGoto(freeMems, error);
- virCheckPositiveArgGoto(maxCells, error);
- virCheckNonNegativeArgGoto(startCell, error);
-
- if (conn->driver->nodeGetCellsFreeMemory) {
- int ret;
- ret = conn->driver->nodeGetCellsFreeMemory(conn, freeMems, startCell,
maxCells);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/*
- * Domain Event Notification
- */
-
-/**
- * virConnectDomainEventRegister:
- * @conn: pointer to the connection
- * @cb: callback to the function handling domain events
- * @opaque: opaque data to pass on to the callback
- * @freecb: optional function to deallocate opaque when not used anymore
- *
- * Adds a callback to receive notifications of domain lifecycle events
- * occurring on a connection. This function requires that an event loop
- * has been previously registered with virEventRegisterImpl() or
- * virEventRegisterDefaultImpl().
- *
- * Use of this method is no longer recommended. Instead applications
- * should try virConnectDomainEventRegisterAny() which has a more flexible
- * API contract.
- *
- * The virDomainPtr object handle passed into the callback upon delivery
- * of an event is only valid for the duration of execution of the callback.
- * If the callback wishes to keep the domain object after the callback returns,
- * it shall take a reference to it, by calling virDomainRef.
- * The reference can be released once the object is no longer required
- * by calling virDomainFree.
- *
- * Returns 0 on success, -1 on failure. Older versions of some hypervisors
- * sometimes returned a positive number on success, but without any reliable
- * semantics on what that number represents.
- */
-int
-virConnectDomainEventRegister(virConnectPtr conn,
- virConnectDomainEventCallback cb,
- void *opaque,
- virFreeCallback freecb)
-{
- VIR_DEBUG("conn=%p, cb=%p, opaque=%p, freecb=%p", conn, cb, opaque,
freecb);
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckNonNullArgGoto(cb, error);
-
- if (conn->driver && conn->driver->connectDomainEventRegister) {
- int ret;
- ret = conn->driver->connectDomainEventRegister(conn, cb, opaque, freecb);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virConnectDomainEventDeregister:
- * @conn: pointer to the connection
- * @cb: callback to the function handling domain events
- *
- * Removes a callback previously registered with the
- * virConnectDomainEventRegister() function.
- *
- * Use of this method is no longer recommended. Instead applications
- * should try virConnectDomainEventDeregisterAny() which has a more flexible
- * API contract
- *
- * Returns 0 on success, -1 on failure. Older versions of some hypervisors
- * sometimes returned a positive number on success, but without any reliable
- * semantics on what that number represents.
- */
-int
-virConnectDomainEventDeregister(virConnectPtr conn,
- virConnectDomainEventCallback cb)
-{
- VIR_DEBUG("conn=%p, cb=%p", conn, cb);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckNonNullArgGoto(cb, error);
-
- if (conn->driver && conn->driver->connectDomainEventDeregister) {
- int ret;
- ret = conn->driver->connectDomainEventDeregister(conn, cb);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainIsActive:
- * @dom: pointer to the domain object
- *
- * Determine if the domain is currently running
- *
- * Returns 1 if running, 0 if inactive, -1 on error
- */
-int
-virDomainIsActive(virDomainPtr dom)
-{
- VIR_DEBUG("dom=%p", dom);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
-
- if (dom->conn->driver->domainIsActive) {
- int ret;
- ret = dom->conn->driver->domainIsActive(dom);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainIsPersistent:
- * @dom: pointer to the domain object
- *
- * Determine if the domain has a persistent configuration
- * which means it will still exist after shutting down
- *
- * Returns 1 if persistent, 0 if transient, -1 on error
- */
-int
-virDomainIsPersistent(virDomainPtr dom)
-{
- VIR_DOMAIN_DEBUG(dom);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
-
- if (dom->conn->driver->domainIsPersistent) {
- int ret;
- ret = dom->conn->driver->domainIsPersistent(dom);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainIsUpdated:
- * @dom: pointer to the domain object
- *
- * Determine if the domain has been updated.
- *
- * Returns 1 if updated, 0 if not, -1 on error
- */
-int
-virDomainIsUpdated(virDomainPtr dom)
-{
- VIR_DOMAIN_DEBUG(dom);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
-
- if (dom->conn->driver->domainIsUpdated) {
- int ret;
- ret = dom->conn->driver->domainIsUpdated(dom);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virConnectIsEncrypted:
- * @conn: pointer to the connection object
- *
- * Determine if the connection to the hypervisor is encrypted
- *
- * Returns 1 if encrypted, 0 if not encrypted, -1 on error
- */
-int
-virConnectIsEncrypted(virConnectPtr conn)
-{
- VIR_DEBUG("conn=%p", conn);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- if (conn->driver->connectIsEncrypted) {
- int ret;
- ret = conn->driver->connectIsEncrypted(conn);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virConnectIsSecure:
- * @conn: pointer to the connection object
- *
- * Determine if the connection to the hypervisor is secure
- *
- * A connection will be classed as secure if it is either
- * encrypted, or running over a channel which is not exposed
- * to eavesdropping (eg a UNIX domain socket, or pipe)
- *
- * Returns 1 if secure, 0 if not secure, -1 on error
- */
-int
-virConnectIsSecure(virConnectPtr conn)
-{
- VIR_DEBUG("conn=%p", conn);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- if (conn->driver->connectIsSecure) {
- int ret;
- ret = conn->driver->connectIsSecure(conn);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virConnectCompareCPU:
- * @conn: virConnect connection
- * @xmlDesc: XML describing the CPU to compare with host CPU
- * @flags: bitwise-OR of virConnectCompareCPUFlags
- *
- * Compares the given CPU description with the host CPU
- *
- * Returns comparison result according to enum virCPUCompareResult. If
- * VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE is used and @xmlDesc CPU is
- * incompatible with host CPU, this function will return VIR_CPU_COMPARE_ERROR
- * (instead of VIR_CPU_COMPARE_INCOMPATIBLE) and the error will use the
- * VIR_ERR_CPU_INCOMPATIBLE code with a message providing more details about
- * the incompatibility.
- */
-int
-virConnectCompareCPU(virConnectPtr conn,
- const char *xmlDesc,
- unsigned int flags)
-{
- VIR_DEBUG("conn=%p, xmlDesc=%s, flags=%x", conn, xmlDesc, flags);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, VIR_CPU_COMPARE_ERROR);
- virCheckNonNullArgGoto(xmlDesc, error);
-
- if (conn->driver->connectCompareCPU) {
- int ret;
-
- ret = conn->driver->connectCompareCPU(conn, xmlDesc, flags);
- if (ret == VIR_CPU_COMPARE_ERROR)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return VIR_CPU_COMPARE_ERROR;
-}
-
-
-/**
- * virConnectGetCPUModelNames:
- *
- * @conn: virConnect connection
- * @arch: Architecture
- * @models: Pointer to a variable to store the NULL-terminated array of the
- * CPU models supported for the specified architecture. Each element
- * and the array itself must be freed by the caller with free. Pass
- * NULL if only the list length is needed.
- * @flags: extra flags; not used yet, so callers should always pass 0.
- *
- * Get the list of supported CPU models for a specific architecture.
- *
- * Returns -1 on error, number of elements in @models on success.
- */
-int
-virConnectGetCPUModelNames(virConnectPtr conn, const char *arch, char ***models,
- unsigned int flags)
-{
- VIR_DEBUG("conn=%p, arch=%s, models=%p, flags=%x",
- conn, arch, models, flags);
- virResetLastError();
-
- if (models)
- *models = NULL;
-
- virCheckConnectReturn(conn, -1);
- virCheckNonNullArgGoto(arch, error);
-
- if (conn->driver->connectGetCPUModelNames) {
- int ret;
-
- ret = conn->driver->connectGetCPUModelNames(conn, arch, models, flags);
- if (ret < 0)
- goto error;
-
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virConnectBaselineCPU:
- *
- * @conn: virConnect connection
- * @xmlCPUs: array of XML descriptions of host CPUs
- * @ncpus: number of CPUs in xmlCPUs
- * @flags: bitwise-OR of virConnectBaselineCPUFlags
- *
- * Computes the most feature-rich CPU which is compatible with all given
- * host CPUs.
- *
- * If @flags includes VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES then libvirt
- * will explicitly list all CPU features that are part of the host CPU,
- * without this flag features that are part of the CPU model will not be
- * listed.
- *
- * Returns XML description of the computed CPU (caller frees) or NULL on error.
- */
-char *
-virConnectBaselineCPU(virConnectPtr conn,
- const char **xmlCPUs,
- unsigned int ncpus,
- unsigned int flags)
-{
- size_t i;
-
- VIR_DEBUG("conn=%p, xmlCPUs=%p, ncpus=%u, flags=%x",
- conn, xmlCPUs, ncpus, flags);
- if (xmlCPUs) {
- for (i = 0; i < ncpus; i++)
- VIR_DEBUG("xmlCPUs[%zu]=%s", i, NULLSTR(xmlCPUs[i]));
- }
-
- virResetLastError();
-
- virCheckConnectReturn(conn, NULL);
- virCheckNonNullArgGoto(xmlCPUs, error);
-
- if (conn->driver->connectBaselineCPU) {
- char *cpu;
-
- cpu = conn->driver->connectBaselineCPU(conn, xmlCPUs, ncpus, flags);
- if (!cpu)
- goto error;
- return cpu;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return NULL;
-}
-
-
-/**
- * virDomainGetJobInfo:
- * @domain: a domain object
- * @info: pointer to a virDomainJobInfo structure allocated by the user
- *
- * Extract information about progress of a background job on a domain.
- * Will return an error if the domain is not active.
- *
- * This function returns a limited amount of information in comparison
- * to virDomainGetJobStats().
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainGetJobInfo(virDomainPtr domain, virDomainJobInfoPtr info)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "info=%p", info);
-
- virResetLastError();
-
- if (info)
- memset(info, 0, sizeof(*info));
-
- virCheckDomainReturn(domain, -1);
- virCheckNonNullArgGoto(info, error);
-
- conn = domain->conn;
-
- if (conn->driver->domainGetJobInfo) {
- int ret;
- ret = conn->driver->domainGetJobInfo(domain, info);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetJobStats:
- * @domain: a domain object
- * @type: where to store the job type (one of virDomainJobType)
- * @params: where to store job statistics
- * @nparams: number of items in @params
- * @flags: bitwise-OR of virDomainGetJobStatsFlags
- *
- * Extract information about progress of a background job on a domain.
- * Will return an error if the domain is not active. The function returns
- * a superset of progress information provided by virDomainGetJobInfo.
- * Possible fields returned in @params are defined by VIR_DOMAIN_JOB_*
- * macros and new fields will likely be introduced in the future so callers
- * may receive fields that they do not understand in case they talk to a
- * newer server.
- *
- * When @flags contains VIR_DOMAIN_JOB_STATS_COMPLETED, the function will
- * return statistics about a recently completed job. Specifically, this
- * flag may be used to query statistics of a completed incoming migration.
- * Statistics of a completed job are automatically destroyed once read or
- * when libvirtd is restarted. Note that time information returned for
- * completed migrations may be completely irrelevant unless both source and
- * destination hosts have synchronized time (i.e., NTP daemon is running on
- * both of them).
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainGetJobStats(virDomainPtr domain,
- int *type,
- virTypedParameterPtr *params,
- int *nparams,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "type=%p, params=%p, nparams=%p, flags=%x",
- type, params, nparams, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- virCheckNonNullArgGoto(type, error);
- virCheckNonNullArgGoto(params, error);
- virCheckNonNullArgGoto(nparams, error);
-
- conn = domain->conn;
-
- if (conn->driver->domainGetJobStats) {
- int ret;
- ret = conn->driver->domainGetJobStats(domain, type, params,
- nparams, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainAbortJob:
- * @domain: a domain object
- *
- * Requests that the current background job be aborted at the
- * soonest opportunity.
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainAbortJob(virDomainPtr domain)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainAbortJob) {
- int ret;
- ret = conn->driver->domainAbortJob(domain);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainMigrateSetMaxDowntime:
- * @domain: a domain object
- * @downtime: maximum tolerable downtime for live migration, in milliseconds
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Sets maximum tolerable time for which the domain is allowed to be paused
- * at the end of live migration. It's supposed to be called while the domain is
- * being live-migrated as a reaction to migration progress.
- *
- * Returns 0 in case of success, -1 otherwise.
- */
-int
-virDomainMigrateSetMaxDowntime(virDomainPtr domain,
- unsigned long long downtime,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "downtime=%llu, flags=%x", downtime, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainMigrateSetMaxDowntime) {
- if (conn->driver->domainMigrateSetMaxDowntime(domain, downtime, flags) <
0)
- goto error;
- return 0;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainMigrateGetCompressionCache:
- * @domain: a domain object
- * @cacheSize: return value of current size of the cache (in bytes)
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Gets current size of the cache (in bytes) used for compressing repeatedly
- * transferred memory pages during live migration.
- *
- * Returns 0 in case of success, -1 otherwise.
- */
-int
-virDomainMigrateGetCompressionCache(virDomainPtr domain,
- unsigned long long *cacheSize,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "cacheSize=%p, flags=%x", cacheSize, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckNonNullArgGoto(cacheSize, error);
-
- if (conn->driver->domainMigrateGetCompressionCache) {
- if (conn->driver->domainMigrateGetCompressionCache(domain, cacheSize,
- flags) < 0)
- goto error;
- return 0;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainMigrateSetCompressionCache:
- * @domain: a domain object
- * @cacheSize: size of the cache (in bytes) used for compression
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Sets size of the cache (in bytes) used for compressing repeatedly
- * transferred memory pages during live migration. It's supposed to be called
- * while the domain is being live-migrated as a reaction to migration progress
- * and increasing number of compression cache misses obtained from
- * virDomainGetJobStats.
- *
- * Returns 0 in case of success, -1 otherwise.
- */
-int
-virDomainMigrateSetCompressionCache(virDomainPtr domain,
- unsigned long long cacheSize,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "cacheSize=%llu, flags=%x", cacheSize, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainMigrateSetCompressionCache) {
- if (conn->driver->domainMigrateSetCompressionCache(domain, cacheSize,
- flags) < 0)
- goto error;
- return 0;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainMigrateSetMaxSpeed:
- * @domain: a domain object
- * @bandwidth: migration bandwidth limit in MiB/s
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * The maximum bandwidth (in MiB/s) that will be used to do migration
- * can be specified with the bandwidth parameter. Not all hypervisors
- * will support a bandwidth cap
- *
- * Returns 0 in case of success, -1 otherwise.
- */
-int
-virDomainMigrateSetMaxSpeed(virDomainPtr domain,
- unsigned long bandwidth,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "bandwidth=%lu, flags=%x", bandwidth, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainMigrateSetMaxSpeed) {
- if (conn->driver->domainMigrateSetMaxSpeed(domain, bandwidth, flags) <
0)
- goto error;
- return 0;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainMigrateGetMaxSpeed:
- * @domain: a domain object
- * @bandwidth: return value of current migration bandwidth limit in MiB/s
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Get the current maximum bandwidth (in MiB/s) that will be used if the
- * domain is migrated. Not all hypervisors will support a bandwidth limit.
- *
- * Returns 0 in case of success, -1 otherwise.
- */
-int
-virDomainMigrateGetMaxSpeed(virDomainPtr domain,
- unsigned long *bandwidth,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "bandwidth = %p, flags=%x", bandwidth, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckNonNullArgGoto(bandwidth, error);
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainMigrateGetMaxSpeed) {
- if (conn->driver->domainMigrateGetMaxSpeed(domain, bandwidth, flags) <
0)
- goto error;
- return 0;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virConnectDomainEventRegisterAny:
- * @conn: pointer to the connection
- * @dom: pointer to the domain
- * @eventID: the event type to receive
- * @cb: callback to the function handling domain events
- * @opaque: opaque data to pass on to the callback
- * @freecb: optional function to deallocate opaque when not used anymore
- *
- * Adds a callback to receive notifications of arbitrary domain events
- * occurring on a domain. This function requires that an event loop
- * has been previously registered with virEventRegisterImpl() or
- * virEventRegisterDefaultImpl().
- *
- * If @dom is NULL, then events will be monitored for any domain. If @dom
- * is non-NULL, then only the specific domain will be monitored.
- *
- * Most types of event have a callback providing a custom set of parameters
- * for the event. When registering an event, it is thus necessary to use
- * the VIR_DOMAIN_EVENT_CALLBACK() macro to cast the supplied function pointer
- * to match the signature of this method.
- *
- * The virDomainPtr object handle passed into the callback upon delivery
- * of an event is only valid for the duration of execution of the callback.
- * If the callback wishes to keep the domain object after the callback returns,
- * it shall take a reference to it, by calling virDomainRef().
- * The reference can be released once the object is no longer required
- * by calling virDomainFree().
- *
- * The return value from this method is a positive integer identifier
- * for the callback. To unregister a callback, this callback ID should
- * be passed to the virConnectDomainEventDeregisterAny() method.
- *
- * Returns a callback identifier on success, -1 on failure.
- */
-int
-virConnectDomainEventRegisterAny(virConnectPtr conn,
- virDomainPtr dom,
- int eventID,
- virConnectDomainEventGenericCallback cb,
- void *opaque,
- virFreeCallback freecb)
-{
- VIR_DOMAIN_DEBUG(dom, "conn=%p, eventID=%d, cb=%p, opaque=%p, freecb=%p",
- conn, eventID, cb, opaque, freecb);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- if (dom) {
- virCheckDomainGoto(dom, error);
- if (dom->conn != conn) {
- virReportInvalidArg(dom,
- _("domain '%s' in %s must match
connection"),
- dom->name, __FUNCTION__);
- goto error;
- }
- }
- virCheckNonNullArgGoto(cb, error);
- virCheckNonNegativeArgGoto(eventID, error);
- if (eventID >= VIR_DOMAIN_EVENT_ID_LAST) {
- virReportInvalidArg(eventID,
- _("eventID in %s must be less than %d"),
- __FUNCTION__, VIR_DOMAIN_EVENT_ID_LAST);
- goto error;
- }
-
- if (conn->driver && conn->driver->connectDomainEventRegisterAny) {
- int ret;
- ret = conn->driver->connectDomainEventRegisterAny(conn, dom, eventID, cb,
opaque, freecb);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virConnectDomainEventDeregisterAny:
- * @conn: pointer to the connection
- * @callbackID: the callback identifier
- *
- * Removes an event callback. The callbackID parameter should be the
- * value obtained from a previous virConnectDomainEventRegisterAny() method.
- *
- * Returns 0 on success, -1 on failure. Older versions of some hypervisors
- * sometimes returned a positive number on success, but without any reliable
- * semantics on what that number represents. */
-int
-virConnectDomainEventDeregisterAny(virConnectPtr conn,
- int callbackID)
-{
- VIR_DEBUG("conn=%p, callbackID=%d", conn, callbackID);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckNonNegativeArgGoto(callbackID, error);
-
- if (conn->driver && conn->driver->connectDomainEventDeregisterAny)
{
- int ret;
- ret = conn->driver->connectDomainEventDeregisterAny(conn, callbackID);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainManagedSave:
- * @dom: pointer to the domain
- * @flags: bitwise-OR of virDomainSaveRestoreFlags
- *
- * This method will suspend a domain and save its memory contents to
- * a file on disk. After the call, if successful, the domain is not
- * listed as running anymore.
- * The difference from virDomainSave() is that libvirt is keeping track of
- * the saved state itself, and will reuse it once the domain is being
- * restarted (automatically or via an explicit libvirt call).
- * As a result any running domain is sure to not have a managed saved image.
- * This also implies that managed save only works on persistent domains,
- * since the domain must still exist in order to use virDomainCreate() to
- * restart it.
- *
- * If @flags includes VIR_DOMAIN_SAVE_BYPASS_CACHE, then libvirt will
- * attempt to bypass the file system cache while creating 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 saves to NFS.
- *
- * Normally, the managed saved state will remember whether the domain
- * was running or paused, and start will resume to the same state.
- * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in
- * @flags will override the default saved into the file. These two
- * flags are mutually exclusive.
- *
- * Returns 0 in case of success or -1 in case of failure
- */
-int
-virDomainManagedSave(virDomainPtr dom, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "flags=%x", flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if ((flags & VIR_DOMAIN_SAVE_RUNNING) && (flags &
VIR_DOMAIN_SAVE_PAUSED)) {
- virReportInvalidArg(flags,
- _("running and paused flags in %s are mutually "
- "exclusive"),
- __FUNCTION__);
- goto error;
- }
-
- if (conn->driver->domainManagedSave) {
- int ret;
-
- ret = conn->driver->domainManagedSave(dom, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainHasManagedSaveImage:
- * @dom: pointer to the domain
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Check if a domain has a managed save image as created by
- * virDomainManagedSave(). Note that any running domain should not have
- * such an image, as it should have been removed on restart.
- *
- * Returns 0 if no image is present, 1 if an image is present, and
- * -1 in case of error
- */
-int
-virDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "flags=%x", flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- if (conn->driver->domainHasManagedSaveImage) {
- int ret;
-
- ret = conn->driver->domainHasManagedSaveImage(dom, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainManagedSaveRemove:
- * @dom: pointer to the domain
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Remove any managed save image for this domain.
- *
- * Returns 0 in case of success, and -1 in case of error
- */
-int
-virDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "flags=%x", flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn->driver->domainManagedSaveRemove) {
- int ret;
-
- ret = conn->driver->domainManagedSaveRemove(dom, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-
-/**
- * virDomainOpenConsole:
- * @dom: a domain object
- * @dev_name: the console, serial or parallel port device alias, or NULL
- * @st: a stream to associate with the console
- * @flags: bitwise-OR of virDomainConsoleFlags
- *
- * This opens the backend associated with a console, serial or
- * parallel port device on a guest, if the backend is supported.
- * If the @dev_name is omitted, then the first console or serial
- * device is opened. The console is associated with the passed
- * in @st stream, which should have been opened in non-blocking
- * mode for bi-directional I/O.
- *
- * By default, when @flags is 0, the open will fail if libvirt
- * detects that the console is already in use by another client;
- * passing VIR_DOMAIN_CONSOLE_FORCE will cause libvirt to forcefully
- * remove the other client prior to opening this console.
- *
- * If flag VIR_DOMAIN_CONSOLE_SAFE the console is opened only in the
- * case where the hypervisor driver supports safe (mutually exclusive)
- * console handling.
- *
- * Older servers did not support either flag, and also did not forbid
- * simultaneous clients on a console, with potentially confusing results.
- * When passing @flags of 0 in order to support a wider range of server
- * versions, it is up to the client to ensure mutual exclusion.
- *
- * Returns 0 if the console was opened, -1 on error
- */
-int
-virDomainOpenConsole(virDomainPtr dom,
- const char *dev_name,
- virStreamPtr st,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "dev_name=%s, st=%p, flags=%x",
- NULLSTR(dev_name), st, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckStreamGoto(st, error);
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn != st->conn) {
- virReportInvalidArg(st,
- _("stream in %s must match connection of domain
'%s'"),
- __FUNCTION__, dom->name);
- goto error;
- }
-
- if (conn->driver->domainOpenConsole) {
- int ret;
- ret = conn->driver->domainOpenConsole(dom, dev_name, st, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainOpenChannel:
- * @dom: a domain object
- * @name: the channel name, or NULL
- * @st: a stream to associate with the channel
- * @flags: bitwise-OR of virDomainChannelFlags
- *
- * This opens the host interface associated with a channel device on a
- * guest, if the host interface is supported. If @name is given, it
- * can match either the device alias (e.g. "channel0"), or the virtio
- * target name (e.g. "org.qemu.guest_agent.0"). If @name is omitted,
- * then the first channel is opened. The channel is associated with
- * the passed in @st stream, which should have been opened in
- * non-blocking mode for bi-directional I/O.
- *
- * By default, when @flags is 0, the open will fail if libvirt detects
- * that the channel is already in use by another client; passing
- * VIR_DOMAIN_CHANNEL_FORCE will cause libvirt to forcefully remove the
- * other client prior to opening this channel.
- *
- * Returns 0 if the channel was opened, -1 on error
- */
-int
-virDomainOpenChannel(virDomainPtr dom,
- const char *name,
- virStreamPtr st,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "name=%s, st=%p, flags=%x",
- NULLSTR(name), st, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckStreamGoto(st, error);
- virCheckReadOnlyGoto(conn->flags, error);
-
- if (conn != st->conn) {
- virReportInvalidArg(st,
- _("stream in %s must match connection of domain
'%s'"),
- __FUNCTION__, dom->name);
- goto error;
- }
-
- if (conn->driver->domainOpenChannel) {
- int ret;
- ret = conn->driver->domainOpenChannel(dom, name, st, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainBlockJobAbort:
- * @dom: pointer to domain object
- * @disk: path to the block device, or device shorthand
- * @flags: bitwise-OR of virDomainBlockJobAbortFlags
- *
- * Cancel the active block job on the given disk.
- *
- * The @disk parameter is either an unambiguous source name of the
- * block device (the <source file='...'/> sub-element, such as
- * "/path/to/image"), or (since 0.9.5) the device target shorthand
- * (the <target dev='...'/> sub-element, such as "vda"). Valid
names
- * can be found by calling virDomainGetXMLDesc() and inspecting
- * elements within //domain/devices/disk.
- *
- * If the current block job for @disk is VIR_DOMAIN_BLOCK_JOB_TYPE_PULL, then
- * by default, this function performs a synchronous operation and the caller
- * may assume that the operation has completed when 0 is returned. However,
- * BlockJob operations may take a long time to cancel, and during this time
- * further domain interactions may be unresponsive. To avoid this problem,
- * pass VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC in the @flags argument to enable
- * asynchronous behavior, returning as soon as possible. When the job has
- * been canceled, a BlockJob event will be emitted, with status
- * VIR_DOMAIN_BLOCK_JOB_CANCELED (even if the ABORT_ASYNC flag was not
- * used); it is also possible to poll virDomainBlockJobInfo() to see if
- * the job cancellation is still pending. This type of job can be restarted
- * to pick up from where it left off.
- *
- * If the current block job for @disk is VIR_DOMAIN_BLOCK_JOB_TYPE_COPY, then
- * the default is to abort the mirroring and revert to the source disk;
- * likewise, if the current job is VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT,
- * the default is to abort without changing the active layer of @disk.
- * Adding @flags of VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT causes this call to
- * fail with VIR_ERR_BLOCK_COPY_ACTIVE if the copy or commit is not yet
- * ready; otherwise it will swap the disk over to the new active image
- * to end the mirroring or active commit. An event will be issued when the
- * job is ended, and it is possible to use VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC
- * to control whether this command waits for the completion of the job.
- * Restarting a copy or active commit job requires starting over from the
- * beginning of the first phase.
- *
- * Returns -1 in case of failure, 0 when successful.
- */
-int
-virDomainBlockJobAbort(virDomainPtr dom, const char *disk,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "disk=%s, flags=%x", disk, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(disk, error);
-
- if (conn->driver->domainBlockJobAbort) {
- int ret;
- ret = conn->driver->domainBlockJobAbort(dom, disk, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetBlockJobInfo:
- * @dom: pointer to domain object
- * @disk: path to the block device, or device shorthand
- * @info: pointer to a virDomainBlockJobInfo structure
- * @flags: bitwise-OR of virDomainBlockJobInfoFlags
- *
- * Request block job information for the given disk. If an operation is active
- * @info will be updated with the current progress. The units used for the
- * bandwidth field of @info depends on @flags. If @flags includes
- * VIR_DOMAIN_BLOCK_JOB_INFO_BANDWIDTH_BYTES, bandwidth is in bytes/second
- * (although this mode can risk failure due to overflow, depending on both
- * client and server word size); otherwise, the value is rounded up to MiB/s.
- *
- * The @disk parameter is either an unambiguous source name of the
- * block device (the <source file='...'/> sub-element, such as
- * "/path/to/image"), or (since 0.9.5) the device target shorthand
- * (the <target dev='...'/> sub-element, such as "vda"). Valid
names
- * can be found by calling virDomainGetXMLDesc() and inspecting
- * elements within //domain/devices/disk.
- *
- * Returns -1 in case of failure, 0 when nothing found, 1 when info was found.
- */
-int
-virDomainGetBlockJobInfo(virDomainPtr dom, const char *disk,
- virDomainBlockJobInfoPtr info, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "disk=%s, info=%p, flags=%x", disk, info, flags);
-
- virResetLastError();
-
- if (info)
- memset(info, 0, sizeof(*info));
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckNonNullArgGoto(disk, error);
- virCheckNonNullArgGoto(info, error);
-
- if (conn->driver->domainGetBlockJobInfo) {
- int ret;
- ret = conn->driver->domainGetBlockJobInfo(dom, disk, info, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainBlockJobSetSpeed:
- * @dom: pointer to domain object
- * @disk: path to the block device, or device shorthand
- * @bandwidth: specify bandwidth limit; flags determine the unit
- * @flags: bitwise-OR of virDomainBlockJobSetSpeedFlags
- *
- * Set the maximimum allowable bandwidth that a block job may consume. If
- * bandwidth is 0, the limit will revert to the hypervisor default of
- * unlimited.
- *
- * If @flags contains VIR_DOMAIN_BLOCK_JOB_SPEED_BANDWIDTH_BYTES, @bandwidth
- * is in bytes/second; otherwise, it is in MiB/second. Values larger than
- * 2^52 bytes/sec may be rejected due to overflow considerations based on
- * the word size of both client and server, and values larger than 2^31
- * bytes/sec may cause overflow problems if later queried by
- * virDomainGetBlockJobInfo() without scaling. Hypervisors may further
- * restrict the range of valid bandwidth values.
- *
- * The @disk parameter is either an unambiguous source name of the
- * block device (the <source file='...'/> sub-element, such as
- * "/path/to/image"), or (since 0.9.5) the device target shorthand
- * (the <target dev='...'/> sub-element, such as "vda"). Valid
names
- * can be found by calling virDomainGetXMLDesc() and inspecting
- * elements within //domain/devices/disk.
- *
- * Returns -1 in case of failure, 0 when successful.
- */
-int
-virDomainBlockJobSetSpeed(virDomainPtr dom, const char *disk,
- unsigned long bandwidth, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "disk=%s, bandwidth=%lu, flags=%x",
- disk, bandwidth, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(disk, error);
-
- if (conn->driver->domainBlockJobSetSpeed) {
- int ret;
- ret = conn->driver->domainBlockJobSetSpeed(dom, disk, bandwidth, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainBlockPull:
- * @dom: pointer to domain object
- * @disk: path to the block device, or device shorthand
- * @bandwidth: (optional) specify bandwidth limit; flags determine the unit
- * @flags: bitwise-OR of virDomainBlockPullFlags
- *
- * Populate a disk image with data from its backing image. Once all data from
- * its backing image has been pulled, the disk no longer depends on a backing
- * image. This function pulls data for the entire device in the background.
- * Progress of the operation can be checked with virDomainGetBlockJobInfo() and
- * the operation can be aborted with virDomainBlockJobAbort(). When finished,
- * an asynchronous event is raised to indicate the final status. To move
- * data in the opposite direction, see virDomainBlockCommit().
- *
- * The @disk parameter is either an unambiguous source name of the
- * block device (the <source file='...'/> sub-element, such as
- * "/path/to/image"), or (since 0.9.5) the device target shorthand
- * (the <target dev='...'/> sub-element, such as "vda"). Valid
names
- * can be found by calling virDomainGetXMLDesc() and inspecting
- * elements within //domain/devices/disk.
- *
- * The maximum bandwidth that will be used to do the copy can be
- * specified with the @bandwidth parameter. If set to 0, there is no
- * limit. If @flags includes VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES,
- * @bandwidth is in bytes/second; otherwise, it is in MiB/second.
- * Values larger than 2^52 bytes/sec may be rejected due to overflow
- * considerations based on the word size of both client and server,
- * and values larger than 2^31 bytes/sec may cause overflow problems
- * if later queried by virDomainGetBlockJobInfo() without scaling.
- * Hypervisors may further restrict the range of valid bandwidth
- * values. Some hypervisors do not support this feature and will
- * return an error if bandwidth is not 0; in this case, it might still
- * be possible for a later call to virDomainBlockJobSetSpeed() to
- * succeed. The actual speed can be determined with
- * virDomainGetBlockJobInfo().
- *
- * This is shorthand for virDomainBlockRebase() with a NULL base.
- *
- * Returns 0 if the operation has started, -1 on failure.
- */
-int
-virDomainBlockPull(virDomainPtr dom, const char *disk,
- unsigned long bandwidth, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "disk=%s, bandwidth=%lu, flags=%x",
- disk, bandwidth, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(disk, error);
-
- if (conn->driver->domainBlockPull) {
- int ret;
- ret = conn->driver->domainBlockPull(dom, disk, bandwidth, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainBlockRebase:
- * @dom: pointer to domain object
- * @disk: path to the block device, or device shorthand
- * @base: path to backing file to keep, or device shorthand,
- * or NULL for no backing file
- * @bandwidth: (optional) specify bandwidth limit; flags determine the unit
- * @flags: bitwise-OR of virDomainBlockRebaseFlags
- *
- * Populate a disk image with data from its backing image chain, and
- * setting the backing image to @base, or alternatively copy an entire
- * backing chain to a new file @base.
- *
- * When @flags is 0, this starts a pull, where @base must be the absolute
- * path of one of the backing images further up the chain, or NULL to
- * convert the disk image so that it has no backing image. Once all
- * data from its backing image chain has been pulled, the disk no
- * longer depends on those intermediate backing images. This function
- * pulls data for the entire device in the background. Progress of
- * the operation can be checked with virDomainGetBlockJobInfo() with a
- * job type of VIR_DOMAIN_BLOCK_JOB_TYPE_PULL, and the operation can be
- * aborted with virDomainBlockJobAbort(). When finished, an asynchronous
- * event is raised to indicate the final status, and the job no longer
- * exists. If the job is aborted, a new one can be started later to
- * resume from the same point.
- *
- * If @flags contains VIR_DOMAIN_BLOCK_REBASE_RELATIVE, the name recorded
- * into the active disk as the location for @base will be kept relative.
- * The operation will fail if libvirt can't infer the name.
- *
- * When @flags includes VIR_DOMAIN_BLOCK_REBASE_COPY, this starts a copy,
- * where @base must be the name of a new file to copy the chain to. By
- * default, the copy will pull the entire source chain into the destination
- * file, but if @flags also contains VIR_DOMAIN_BLOCK_REBASE_SHALLOW, then
- * only the top of the source chain will be copied (the source and
- * destination have a common backing file). By default, @base will be
- * created with the same file format as the source, but this can be altered
- * by adding VIR_DOMAIN_BLOCK_REBASE_COPY_RAW to force the copy to be raw
- * (does not make sense with the shallow flag unless the source is also raw),
- * or by using VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT to reuse an existing file
- * which was pre-created with the correct format and metadata and sufficient
- * size to hold the copy. In case the VIR_DOMAIN_BLOCK_REBASE_SHALLOW flag
- * is used the pre-created file has to exhibit the same guest visible contents
- * as the backing file of the original image. This allows a management app to
- * pre-create files with relative backing file names, rather than the default
- * of absolute backing file names; as a security precaution, you should
- * generally only use reuse_ext with the shallow flag and a non-raw
- * destination file. By default, the copy destination will be treated as
- * type='file', but using VIR_DOMAIN_BLOCK_REBASE_COPY_DEV treats the
- * destination as type='block' (affecting how virDomainGetBlockInfo() will
- * report allocation after pivoting).
- *
- * A copy job has two parts; in the first phase, the @bandwidth parameter
- * affects how fast the source is pulled into the destination, and the job
- * can only be canceled by reverting to the source file; progress in this
- * phase can be tracked via the virDomainBlockJobInfo() command, with a
- * job type of VIR_DOMAIN_BLOCK_JOB_TYPE_COPY. The job transitions to the
- * second phase when the job info states cur == end, and remains alive to
- * mirror all further changes to both source and destination. The user
- * must call virDomainBlockJobAbort() to end the mirroring while choosing
- * whether to revert to source or pivot to the destination. An event is
- * issued when the job ends, and depending on the hypervisor, an event may
- * also be issued when the job transitions from pulling to mirroring. If
- * the job is aborted, a new job will have to start over from the beginning
- * of the first phase.
- *
- * Some hypervisors will restrict certain actions, such as virDomainSave()
- * or virDomainDetachDevice(), while a copy job is active; they may
- * also restrict a copy job to transient domains.
- *
- * The @disk parameter is either an unambiguous source name of the
- * block device (the <source file='...'/> sub-element, such as
- * "/path/to/image"), or the device target shorthand (the
- * <target dev='...'/> sub-element, such as "vda"). Valid names
- * can be found by calling virDomainGetXMLDesc() and inspecting
- * elements within //domain/devices/disk.
- *
- * The @base parameter can be either a path to a file within the backing
- * chain, or the device target shorthand (the <target dev='...'/>
- * sub-element, such as "vda") followed by an index to the backing chain
- * enclosed in square brackets. Backing chain indexes can be found by
- * inspecting //disk//backingStore/@index in the domain XML. Thus, for
- * example, "vda[3]" refers to the backing store with index equal to
"3"
- * in the chain of disk "vda".
- *
- * The maximum bandwidth that will be used to do the copy can be
- * specified with the @bandwidth parameter. If set to 0, there is no
- * limit. If @flags includes VIR_DOMAIN_BLOCK_REBASE_BANDWIDTH_BYTES,
- * @bandwidth is in bytes/second; otherwise, it is in MiB/second.
- * Values larger than 2^52 bytes/sec may be rejected due to overflow
- * considerations based on the word size of both client and server,
- * and values larger than 2^31 bytes/sec may cause overflow problems
- * if later queried by virDomainGetBlockJobInfo() without scaling.
- * Hypervisors may further restrict the range of valid bandwidth
- * values. Some hypervisors do not support this feature and will
- * return an error if bandwidth is not 0; in this case, it might still
- * be possible for a later call to virDomainBlockJobSetSpeed() to
- * succeed. The actual speed can be determined with
- * virDomainGetBlockJobInfo().
- *
- * When @base is NULL and @flags is 0, this is identical to
- * virDomainBlockPull(). When @flags contains VIR_DOMAIN_BLOCK_REBASE_COPY,
- * this command is shorthand for virDomainBlockCopy() where the destination
- * XML encodes @base as a <disk type='file'>, @bandwidth is properly
scaled
- * and passed as a typed parameter, the shallow and reuse external flags
- * are preserved, and remaining flags control whether the XML encodes a
- * destination format of raw instead of leaving the destination identical
- * to the source format or probed from the reused file.
- *
- * Returns 0 if the operation has started, -1 on failure.
- */
-int
-virDomainBlockRebase(virDomainPtr dom, const char *disk,
- const char *base, unsigned long bandwidth,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "disk=%s, base=%s, bandwidth=%lu, flags=%x",
- disk, NULLSTR(base), bandwidth, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(disk, error);
-
- if (flags & VIR_DOMAIN_BLOCK_REBASE_COPY) {
- virCheckNonNullArgGoto(base, error);
- } else if (flags & (VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
- VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT |
- VIR_DOMAIN_BLOCK_REBASE_COPY_RAW |
- VIR_DOMAIN_BLOCK_REBASE_COPY_DEV)) {
- virReportInvalidArg(flags,
- _("use of flags in %s requires a copy job"),
- __FUNCTION__);
- goto error;
- }
-
- if (conn->driver->domainBlockRebase) {
- int ret;
- ret = conn->driver->domainBlockRebase(dom, disk, base, bandwidth,
- flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainBlockCopy:
- * @dom: pointer to domain object
- * @disk: path to the block device, or device shorthand
- * @destxml: XML description of the copy destination
- * @params: Pointer to block copy parameter objects, or NULL
- * @nparams: Number of block copy parameters (this value can be the same or
- * less than the number of parameters supported)
- * @flags: bitwise-OR of virDomainBlockCopyFlags
- *
- * Copy the guest-visible contents of a disk image to a new file described
- * by @destxml. The destination XML has a top-level element of <disk>, and
- * resembles what is used when hot-plugging a disk via virDomainAttachDevice(),
- * except that only sub-elements related to describing the new host resource
- * are necessary (sub-elements related to the guest view, such as <target>,
- * are ignored). It is strongly recommended to include a <driver
type='...'/>
- * format designation for the destination, to avoid the potential of any
- * security problem that might be caused by probing a file for its format.
- *
- * This command starts a long-running copy. By default, the copy will pull
- * the entire source chain into the destination file, but if @flags also
- * contains VIR_DOMAIN_BLOCK_COPY_SHALLOW, then only the top of the source
- * chain will be copied (the source and destination have a common backing
- * file). The format of the destination file is controlled by the <driver>
- * sub-element of the XML. The destination will be created unless the
- * VIR_DOMAIN_BLOCK_COPY_REUSE_EXT flag is present stating that the file
- * was pre-created with the correct format and metadata and sufficient
- * size to hold the copy. In case the VIR_DOMAIN_BLOCK_COPY_SHALLOW flag
- * is used the pre-created file has to exhibit the same guest visible contents
- * as the backing file of the original image. This allows a management app to
- * pre-create files with relative backing file names, rather than the default
- * of absolute backing file names.
- *
- * A copy job has two parts; in the first phase, the source is copied into
- * the destination, and the job can only be canceled by reverting to the
- * source file; progress in this phase can be tracked via the
- * virDomainBlockJobInfo() command, with a job type of
- * VIR_DOMAIN_BLOCK_JOB_TYPE_COPY. The job transitions to the second
- * phase when the job info states cur == end, and remains alive to mirror
- * all further changes to both source and destination. The user must
- * call virDomainBlockJobAbort() to end the mirroring while choosing
- * whether to revert to source or pivot to the destination. An event is
- * issued when the job ends, and depending on the hypervisor, an event may
- * also be issued when the job transitions from pulling to mirroring. If
- * the job is aborted, a new job will have to start over from the beginning
- * of the first phase.
- *
- * Some hypervisors will restrict certain actions, such as virDomainSave()
- * or virDomainDetachDevice(), while a copy job is active; they may
- * also restrict a copy job to transient domains.
- *
- * The @disk parameter is either an unambiguous source name of the
- * block device (the <source file='...'/> sub-element, such as
- * "/path/to/image"), or the device target shorthand (the
- * <target dev='...'/> sub-element, such as "vda"). Valid names
- * can be found by calling virDomainGetXMLDesc() and inspecting
- * elements within //domain/devices/disk.
- *
- * The @params and @nparams arguments can be used to set hypervisor-specific
- * tuning parameters, such as maximum bandwidth or granularity. For a
- * parameter that the hypervisor understands, explicitly specifying 0
- * behaves the same as omitting the parameter, to use the hypervisor
- * default; however, omitting a parameter is less likely to fail.
- *
- * This command is a superset of the older virDomainBlockRebase() when used
- * with the VIR_DOMAIN_BLOCK_REBASE_COPY flag, and offers better control
- * over the destination format, the ability to copy to a destination that
- * is not a local file, and the possibility of additional tuning parameters.
- *
- * Returns 0 if the operation has started, -1 on failure.
- */
-int
-virDomainBlockCopy(virDomainPtr dom, const char *disk,
- const char *destxml,
- virTypedParameterPtr params,
- int nparams,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom,
- "disk=%s, destxml=%s, params=%p, nparams=%d, flags=%x",
- disk, destxml, params, nparams, flags);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(disk, error);
- virCheckNonNullArgGoto(destxml, error);
- virCheckNonNegativeArgGoto(nparams, error);
- if (nparams)
- virCheckNonNullArgGoto(params, error);
-
- if (conn->driver->domainBlockCopy) {
- int ret;
- ret = conn->driver->domainBlockCopy(dom, disk, destxml,
- params, nparams, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainBlockCommit:
- * @dom: pointer to domain object
- * @disk: path to the block device, or device shorthand
- * @base: path to backing file to merge into, or device shorthand,
- * or NULL for default
- * @top: path to file within backing chain that contains data to be merged,
- * or device shorthand, or NULL to merge all possible data
- * @bandwidth: (optional) specify bandwidth limit; flags determine the unit
- * @flags: bitwise-OR of virDomainBlockCommitFlags
- *
- * Commit changes that were made to temporary top-level files within a disk
- * image backing file chain into a lower-level base file. In other words,
- * take all the difference between @base and @top, and update @base to contain
- * that difference; after the commit, any portion of the chain that previously
- * depended on @top will now depend on @base, and all files after @base up
- * to and including @top will now be invalidated. A typical use of this
- * command is to reduce the length of a backing file chain after taking an
- * external disk snapshot. To move data in the opposite direction, see
- * virDomainBlockPull().
- *
- * This command starts a long-running commit block job, whose status may
- * be tracked by virDomainBlockJobInfo() with a job type of
- * VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT, and the operation can be aborted with
- * virDomainBlockJobAbort(). When finished, an asynchronous event is
- * raised to indicate the final status, and the job no longer exists. If
- * the job is aborted, it is up to the hypervisor whether starting a new
- * job will resume from the same point, or start over.
- *
- * As a special case, if @top is the active image (or NULL), and @flags
- * includes VIR_DOMAIN_BLOCK_COMMIT_ACTIVE, the block job will have a type
- * of VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT, and operates in two phases.
- * In the first phase, the contents are being committed into @base, and the
- * job can only be canceled. The job transitions to the second phase when
- * the job info states cur == end, and remains alive to keep all further
- * changes to @top synchronized into @base; an event with status
- * VIR_DOMAIN_BLOCK_JOB_READY is also issued to mark the job transition.
- * Once in the second phase, the user must choose whether to cancel the job
- * (keeping @top as the active image, but now containing only the changes
- * since the time the job ended) or to pivot the job (adjusting to @base as
- * the active image, and invalidating @top).
- *
- * Be aware that this command may invalidate files even if it is aborted;
- * the user is cautioned against relying on the contents of invalidated
- * intermediate files such as @top (when @top is not the active image)
- * without manually rebasing those files to use a backing file of a
- * read-only copy of @base prior to the point where the commit operation
- * was started (and such a rebase cannot be safely done until the commit
- * has successfully completed). However, the domain itself will not have
- * any issues; the active layer remains valid throughout the entire commit
- * operation.
- *
- * Some hypervisors may support a shortcut where if @flags contains
- * VIR_DOMAIN_BLOCK_COMMIT_DELETE, then this command will unlink all files
- * that were invalidated, after the commit successfully completes.
- *
- * If @flags contains VIR_DOMAIN_BLOCK_COMMIT_RELATIVE, the name recorded
- * into the overlay of the @top image (if there is such image) as the
- * path to the new backing file will be kept relative to other images.
- * The operation will fail if libvirt can't infer the name.
- *
- * By default, if @base is NULL, the commit target will be the bottom of
- * the backing chain; if @flags contains VIR_DOMAIN_BLOCK_COMMIT_SHALLOW,
- * then the immediate backing file of @top will be used instead. If @top
- * is NULL, the active image at the top of the chain will be used. Some
- * hypervisors place restrictions on how much can be committed, and might
- * fail if @base is not the immediate backing file of @top, or if @top is
- * the active layer in use by a running domain but @flags did not include
- * VIR_DOMAIN_BLOCK_COMMIT_ACTIVE, or if @top is not the top-most file;
- * restrictions may differ for online vs. offline domains.
- *
- * The @disk parameter is either an unambiguous source name of the
- * block device (the <source file='...'/> sub-element, such as
- * "/path/to/image"), or the device target shorthand (the
- * <target dev='...'/> sub-element, such as "vda"). Valid names
- * can be found by calling virDomainGetXMLDesc() and inspecting
- * elements within //domain/devices/disk.
- *
- * The @base and @top parameters can be either paths to files within the
- * backing chain, or the device target shorthand (the <target dev='...'/>
- * sub-element, such as "vda") followed by an index to the backing chain
- * enclosed in square brackets. Backing chain indexes can be found by
- * inspecting //disk//backingStore/@index in the domain XML. Thus, for
- * example, "vda[3]" refers to the backing store with index equal to
"3"
- * in the chain of disk "vda".
- *
- * The maximum bandwidth that will be used to do the commit can be
- * specified with the @bandwidth parameter. If set to 0, there is no
- * limit. If @flags includes VIR_DOMAIN_BLOCK_COMMIT_BANDWIDTH_BYTES,
- * @bandwidth is in bytes/second; otherwise, it is in MiB/second.
- * Values larger than 2^52 bytes/sec may be rejected due to overflow
- * considerations based on the word size of both client and server,
- * and values larger than 2^31 bytes/sec may cause overflow problems
- * if later queried by virDomainGetBlockJobInfo() without scaling.
- * Hypervisors may further restrict the range of valid bandwidth
- * values. Some hypervisors do not support this feature and will
- * return an error if bandwidth is not 0; in this case, it might still
- * be possible for a later call to virDomainBlockJobSetSpeed() to
- * succeed. The actual speed can be determined with
- * virDomainGetBlockJobInfo().
- *
- * Returns 0 if the operation has started, -1 on failure.
- */
-int
-virDomainBlockCommit(virDomainPtr dom, const char *disk,
- const char *base, const char *top,
- unsigned long bandwidth, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "disk=%s, base=%s, top=%s, bandwidth=%lu, flags=%x",
- disk, NULLSTR(base), NULLSTR(top), bandwidth, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(disk, error);
-
- if (conn->driver->domainBlockCommit) {
- int ret;
- ret = conn->driver->domainBlockCommit(dom, disk, base, top, bandwidth,
- flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainOpenGraphics:
- * @dom: pointer to domain object
- * @idx: index of graphics config to open
- * @fd: file descriptor to attach graphics to
- * @flags: bitwise-OR of virDomainOpenGraphicsFlags
- *
- * This will attempt to connect the file descriptor @fd, to
- * the graphics backend of @dom. If @dom has multiple graphics
- * backends configured, then @idx will determine which one is
- * opened, starting from @idx 0.
- *
- * To disable any authentication, pass the VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH
- * constant for @flags.
- *
- * The caller should use an anonymous socketpair to open
- * @fd before invocation.
- *
- * This method can only be used when connected to a local
- * libvirt hypervisor, over a UNIX domain socket. Attempts
- * to use this method over a TCP connection will always fail
- *
- * Returns 0 on success, -1 on failure
- */
-int
-virDomainOpenGraphics(virDomainPtr dom,
- unsigned int idx,
- int fd,
- unsigned int flags)
-{
- struct stat sb;
- VIR_DOMAIN_DEBUG(dom, "idx=%u, fd=%d, flags=%x",
- idx, fd, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- virCheckNonNegativeArgGoto(fd, error);
-
- if (fstat(fd, &sb) < 0) {
- virReportSystemError(errno,
- _("Unable to access file descriptor %d"), fd);
- goto error;
- }
-
- if (!S_ISSOCK(sb.st_mode)) {
- virReportInvalidArg(fd,
- _("fd %d in %s must be a socket"),
- fd, __FUNCTION__);
- goto error;
- }
-
- virCheckReadOnlyGoto(dom->conn->flags, error);
-
- if (!VIR_DRV_SUPPORTS_FEATURE(dom->conn->driver, dom->conn,
- VIR_DRV_FEATURE_FD_PASSING)) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("fd passing is not supported by this connection"));
- goto error;
- }
-
- if (dom->conn->driver->domainOpenGraphics) {
- int ret;
- ret = dom->conn->driver->domainOpenGraphics(dom, idx, fd, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainOpenGraphicsFD:
- * @dom: pointer to domain object
- * @idx: index of graphics config to open
- * @flags: bitwise-OR of virDomainOpenGraphicsFlags
- *
- * This will create a socket pair connected to the graphics backend of @dom.
- * One end of the socket will be returned on success, and the other end is
- * handed to the hypervisor.
- * If @dom has multiple graphics backends configured, then @idx will determine
- * which one is opened, starting from @idx 0.
- *
- * To disable any authentication, pass the VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH
- * constant for @flags.
- *
- * This method can only be used when connected to a local
- * libvirt hypervisor, over a UNIX domain socket. Attempts
- * to use this method over a TCP connection will always fail.
- *
- * Returns an fd on success, -1 on failure
- */
-int
-virDomainOpenGraphicsFD(virDomainPtr dom,
- unsigned int idx,
- unsigned int flags)
-{
- VIR_DOMAIN_DEBUG(dom, "idx=%u, flags=%x", idx, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
-
- virCheckReadOnlyGoto(dom->conn->flags, error);
-
- if (!VIR_DRV_SUPPORTS_FEATURE(dom->conn->driver, dom->conn,
- VIR_DRV_FEATURE_FD_PASSING)) {
- virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
- _("fd passing is not supported by this connection"));
- goto error;
- }
-
- if (dom->conn->driver->domainOpenGraphicsFD) {
- int ret;
- ret = dom->conn->driver->domainOpenGraphicsFD(dom, idx, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virConnectSetKeepAlive:
- * @conn: pointer to a hypervisor connection
- * @interval: number of seconds of inactivity before a keepalive message is sent
- * @count: number of messages that can be sent in a row
- *
- * Start sending keepalive messages after @interval seconds of inactivity and
- * consider the connection to be broken when no response is received after
- * @count keepalive messages sent in a row. In other words, sending count + 1
- * keepalive message results in closing the connection. When @interval is
- * <= 0, no keepalive messages will be sent. When @count is 0, the connection
- * will be automatically closed after @interval seconds of inactivity without
- * sending any keepalive messages.
- *
- * Note: The client has to implement and run an event loop with
- * virEventRegisterImpl() or virEventRegisterDefaultImpl() to be able to
- * use keepalive messages. Failure to do so may result in connections
- * being closed unexpectedly.
- *
- * Note: This API function controls only keepalive messages sent by the client.
- * If the server is configured to use keepalive you still need to run the event
- * loop to respond to them, even if you disable keepalives by this function.
- *
- * Returns -1 on error, 0 on success, 1 when remote party doesn't support
- * keepalive messages.
- */
-int
-virConnectSetKeepAlive(virConnectPtr conn,
- int interval,
- unsigned int count)
-{
- int ret = -1;
-
- VIR_DEBUG("conn=%p, interval=%d, count=%u", conn, interval, count);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
-
- if (conn->driver->connectSetKeepAlive) {
- ret = conn->driver->connectSetKeepAlive(conn, interval, count);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virConnectIsAlive:
- * @conn: pointer to the connection object
- *
- * Determine if the connection to the hypervisor is still alive
- *
- * A connection will be classed as alive if it is either local, or running
- * over a channel (TCP or UNIX socket) which is not closed.
- *
- * Returns 1 if alive, 0 if dead, -1 on error
- */
-int
-virConnectIsAlive(virConnectPtr conn)
-{
- VIR_DEBUG("conn=%p", conn);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- if (conn->driver->connectIsAlive) {
- int ret;
- ret = conn->driver->connectIsAlive(conn);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virConnectRegisterCloseCallback:
- * @conn: pointer to connection object
- * @cb: callback to invoke upon close
- * @opaque: user data to pass to @cb
- * @freecb: callback to free @opaque
- *
- * Registers a callback to be invoked when the connection
- * is closed. This callback is invoked when there is any
- * condition that causes the socket connection to the
- * hypervisor to be closed.
- *
- * This function is only applicable to hypervisor drivers
- * which maintain a persistent open connection. Drivers
- * which open a new connection for every operation will
- * not invoke this.
- *
- * The @freecb must not invoke any other libvirt public
- * APIs, since it is not called from a re-entrant safe
- * context.
- *
- * Returns 0 on success, -1 on error
- */
-int
-virConnectRegisterCloseCallback(virConnectPtr conn,
- virConnectCloseFunc cb,
- void *opaque,
- virFreeCallback freecb)
-{
- VIR_DEBUG("conn=%p", conn);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
-
- virObjectRef(conn);
-
- virMutexLock(&conn->lock);
- virObjectLock(conn->closeCallback);
-
- virCheckNonNullArgGoto(cb, error);
-
- if (conn->closeCallback->callback) {
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("A close callback is already registered"));
- goto error;
- }
-
- conn->closeCallback->conn = conn;
- conn->closeCallback->callback = cb;
- conn->closeCallback->opaque = opaque;
- conn->closeCallback->freeCallback = freecb;
-
- virObjectUnlock(conn->closeCallback);
- virMutexUnlock(&conn->lock);
-
- return 0;
-
- error:
- virObjectUnlock(conn->closeCallback);
- virMutexUnlock(&conn->lock);
- virDispatchError(conn);
- virObjectUnref(conn);
- return -1;
-}
-
-
-/**
- * virConnectUnregisterCloseCallback:
- * @conn: pointer to connection object
- * @cb: pointer to the current registered callback
- *
- * Unregisters the callback previously set with the
- * virConnectRegisterCloseCallback method. The callback
- * will no longer receive notifications when the connection
- * closes. If a virFreeCallback was provided at time of
- * registration, it will be invoked
- *
- * Returns 0 on success, -1 on error
- */
-int
-virConnectUnregisterCloseCallback(virConnectPtr conn,
- virConnectCloseFunc cb)
-{
- VIR_DEBUG("conn=%p", conn);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
-
- virMutexLock(&conn->lock);
- virObjectLock(conn->closeCallback);
-
- virCheckNonNullArgGoto(cb, error);
-
- if (conn->closeCallback->callback != cb) {
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("A different callback was requested"));
- goto error;
- }
-
- conn->closeCallback->callback = NULL;
- if (conn->closeCallback->freeCallback)
- conn->closeCallback->freeCallback(conn->closeCallback->opaque);
- conn->closeCallback->freeCallback = NULL;
-
- virObjectUnref(conn);
- virObjectUnlock(conn->closeCallback);
- virMutexUnlock(&conn->lock);
-
- return 0;
-
- error:
- virObjectUnlock(conn->closeCallback);
- virMutexUnlock(&conn->lock);
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainSetBlockIoTune:
- * @dom: pointer to domain object
- * @disk: path to the block device, or device shorthand
- * @params: Pointer to blkio parameter objects
- * @nparams: Number of blkio parameters (this value can be the same or
- * less than the number of parameters supported)
- * @flags: bitwise-OR of virDomainModificationImpact
- *
- * Change all or a subset of the per-device block IO tunables.
- *
- * The @disk parameter is either an unambiguous source name of the
- * block device (the <source file='...'/> sub-element, such as
- * "/path/to/image"), or the device target shorthand (the <target
- * dev='...'/> sub-element, such as "xvda"). Valid names can be
found
- * by calling virDomainGetXMLDesc() and inspecting elements
- * within //domain/devices/disk.
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virDomainSetBlockIoTune(virDomainPtr dom,
- const char *disk,
- virTypedParameterPtr params,
- int nparams,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "disk=%s, params=%p, nparams=%d, flags=%x",
- disk, params, nparams, flags);
- VIR_TYPED_PARAMS_DEBUG(params, nparams);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
- conn = dom->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
- virCheckNonNullArgGoto(disk, error);
- virCheckPositiveArgGoto(nparams, error);
- virCheckNonNullArgGoto(params, error);
-
- if (virTypedParameterValidateSet(dom->conn, params, nparams) < 0)
- goto error;
-
- if (conn->driver->domainSetBlockIoTune) {
- int ret;
- ret = conn->driver->domainSetBlockIoTune(dom, disk, params, nparams,
flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetBlockIoTune:
- * @dom: pointer to domain object
- * @disk: path to the block device, or device shorthand
- * @params: Pointer to blkio parameter object
- * (return value, allocated by the caller)
- * @nparams: Pointer to number of blkio parameters
- * @flags: bitwise-OR of virDomainModificationImpact and virTypedParameterFlags
- *
- * Get all block IO tunable parameters for a given device. On input,
- * @nparams gives the size of the @params array; on output, @nparams
- * gives how many slots were filled with parameter information, which
- * might be less but will not exceed the input value.
- *
- * As a special case, calling with @params as NULL and @nparams as 0
- * on input will cause @nparams on output to contain the number of
- * parameters supported by the hypervisor, either for the given @disk
- * (note that block devices of different types might support different
- * parameters), or if @disk is NULL, for all possible disks. The
- * caller should then allocate @params array,
- * i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
- * again. See virDomainGetMemoryParameters() for more details.
- *
- * The @disk parameter is either an unambiguous source name of the
- * block device (the <source file='...'/> sub-element, such as
- * "/path/to/image"), or the device target shorthand (the <target
- * dev='...'/> sub-element, such as "xvda"). Valid names can be
found
- * by calling virDomainGetXMLDesc() and inspecting elements
- * within //domain/devices/disk. This parameter cannot be NULL
- * unless @nparams is 0 on input.
- *
- * Returns -1 in case of error, 0 in case of success.
- */
-int
-virDomainGetBlockIoTune(virDomainPtr dom,
- const char *disk,
- virTypedParameterPtr params,
- int *nparams,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(dom, "disk=%s, params=%p, nparams=%d, flags=%x",
- NULLSTR(disk), params, (nparams) ? *nparams : -1, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
-
- virCheckNonNullArgGoto(nparams, error);
- virCheckNonNegativeArgGoto(*nparams, error);
- if (*nparams != 0) {
- virCheckNonNullArgGoto(params, error);
- virCheckNonNullArgGoto(disk, error);
- }
-
- if (VIR_DRV_SUPPORTS_FEATURE(dom->conn->driver, dom->conn,
- VIR_DRV_FEATURE_TYPED_PARAM_STRING))
- flags |= VIR_TYPED_PARAM_STRING_OKAY;
-
- /* At most one of these two flags should be set. */
- if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
- (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
- virReportInvalidArg(flags,
- _("flags 'affect live' and 'affect
config' in %s "
- "are mutually exclusive"),
- __FUNCTION__);
- goto error;
- }
- conn = dom->conn;
-
- if (conn->driver->domainGetBlockIoTune) {
- int ret;
- ret = conn->driver->domainGetBlockIoTune(dom, disk, params, nparams,
flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetCPUStats:
- * @domain: domain to query
- * @params: array to populate on output
- * @nparams: number of parameters per cpu
- * @start_cpu: which cpu to start with, or -1 for summary
- * @ncpus: how many cpus to query
- * @flags: bitwise-OR of virTypedParameterFlags
- *
- * Get statistics relating to CPU usage attributable to a single
- * domain (in contrast to the statistics returned by
- * virNodeGetCPUStats() for all processes on the host). @dom
- * must be running (an inactive domain has no attributable cpu
- * usage). On input, @params must contain at least @nparams * @ncpus
- * entries, allocated by the caller.
- *
- * If @start_cpu is -1, then @ncpus must be 1, and the returned
- * results reflect the statistics attributable to the entire
- * domain (such as user and system time for the process as a
- * whole). Otherwise, @start_cpu represents which cpu to start
- * with, and @ncpus represents how many consecutive processors to
- * query, with statistics attributable per processor (such as
- * per-cpu usage). If @ncpus is larger than the number of cpus
- * available to query, then the trailing part of the array will
- * be unpopulated.
- *
- * The remote driver imposes a limit of 128 @ncpus and 16 @nparams;
- * the number of parameters per cpu should not exceed 16, but if you
- * have a host with more than 128 CPUs, your program should split
- * the request into multiple calls.
- *
- * As special cases, if @params is NULL and @nparams is 0 and
- * @ncpus is 1, and the return value will be how many
- * statistics are available for the given @start_cpu. This number
- * may be different for @start_cpu of -1 than for any non-negative
- * value, but will be the same for all non-negative @start_cpu.
- * Likewise, if @params is NULL and @nparams is 0 and @ncpus is 0,
- * the number of cpus available to query is returned. From the
- * host perspective, this would typically match the cpus member
- * of virNodeGetInfo(), but might be less due to host cpu hotplug.
- *
- * For now, @flags is unused, and the statistics all relate to the
- * usage from the host perspective. It is possible that a future
- * version will support a flag that queries the cpu usage from the
- * guest's perspective, where the maximum cpu to query would be
- * related to virDomainGetVcpusFlags() rather than virNodeGetInfo().
- * An individual guest vcpu cannot be reliably mapped back to a
- * specific host cpu unless a single-processor vcpu pinning was used,
- * but when @start_cpu is -1, any difference in usage between a host
- * and guest perspective would serve as a measure of hypervisor overhead.
- *
- * Typical use sequence is below.
- *
- * getting total stats: set start_cpu as -1, ncpus 1
- * virDomainGetCPUStats(dom, NULL, 0, -1, 1, 0) => nparams
- * params = calloc(nparams, sizeof(virTypedParameter))
- * virDomainGetCPUStats(dom, params, nparams, -1, 1, 0) => total stats.
- *
- * getting per-cpu stats:
- * virDomainGetCPUStats(dom, NULL, 0, 0, 0, 0) => ncpus
- * virDomainGetCPUStats(dom, NULL, 0, 0, 1, 0) => nparams
- * params = calloc(ncpus * nparams, sizeof(virTypedParameter))
- * virDomainGetCPUStats(dom, params, nparams, 0, ncpus, 0) => per-cpu stats
- *
- * Returns -1 on failure, or the number of statistics that were
- * populated per cpu on success (this will be less than the total
- * number of populated @params, unless @ncpus was 1; and may be
- * less than @nparams). The populated parameters start at each
- * stride of @nparams, which means the results may be discontiguous;
- * any unpopulated parameters will be zeroed on success (this includes
- * skipped elements if @nparams is too large, and tail elements if
- * @ncpus is too large). The caller is responsible for freeing any
- * returned string parameters.
- */
-int
-virDomainGetCPUStats(virDomainPtr domain,
- virTypedParameterPtr params,
- unsigned int nparams,
- int start_cpu,
- unsigned int ncpus,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain,
- "params=%p, nparams=%d, start_cpu=%d, ncpus=%u,
flags=%x",
- params, nparams, start_cpu, ncpus, flags);
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- /* Special cases:
- * start_cpu must be non-negative, or else -1
- * if start_cpu is -1, ncpus must be 1
- * params == NULL must match nparams == 0
- * ncpus must be non-zero unless params == NULL
- * nparams * ncpus must not overflow (RPC may restrict it even more)
- */
- if (start_cpu == -1) {
- if (ncpus != 1) {
- virReportInvalidArg(start_cpu,
- _("ncpus in %s must be 1 when start_cpu is
-1"),
- __FUNCTION__);
- goto error;
- }
- } else {
- virCheckNonNegativeArgGoto(start_cpu, error);
- }
- if (nparams)
- virCheckNonNullArgGoto(params, error);
- else
- virCheckNullArgGoto(params, error);
- if (ncpus == 0)
- virCheckNullArgGoto(params, error);
-
- if (nparams && ncpus > UINT_MAX / nparams) {
- virReportError(VIR_ERR_OVERFLOW, _("input too large: %u * %u"),
- nparams, ncpus);
- goto error;
- }
- if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
- VIR_DRV_FEATURE_TYPED_PARAM_STRING))
- flags |= VIR_TYPED_PARAM_STRING_OKAY;
-
- if (conn->driver->domainGetCPUStats) {
- int ret;
-
- ret = conn->driver->domainGetCPUStats(domain, params, nparams,
- start_cpu, ncpus, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetDiskErrors:
- * @dom: a domain object
- * @errors: array to populate on output
- * @maxerrors: size of @errors array
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * The function populates @errors array with all disks that encountered an
- * I/O error. Disks with no error will not be returned in the @errors array.
- * Each disk is identified by its target (the dev attribute of target
- * subelement in domain XML), such as "vda", and accompanied with the error
- * that was seen on it. The caller is also responsible for calling free()
- * on each disk name returned.
- *
- * In a special case when @errors is NULL and @maxerrors is 0, the function
- * returns preferred size of @errors that the caller should use to get all
- * disk errors.
- *
- * Since calling virDomainGetDiskErrors(dom, NULL, 0, 0) to get preferred size
- * of @errors array and getting the errors are two separate operations, new
- * disks may be hotplugged to the domain and new errors may be encountered
- * between the two calls. Thus, this function may not return all disk errors
- * because the supplied array is not large enough. Such errors may, however,
- * be detected by listening to domain events.
- *
- * Returns number of disks with errors filled in the @errors array or -1 on
- * error.
- */
-int
-virDomainGetDiskErrors(virDomainPtr dom,
- virDomainDiskErrorPtr errors,
- unsigned int maxerrors,
- unsigned int flags)
-{
- VIR_DOMAIN_DEBUG(dom, "errors=%p, maxerrors=%u, flags=%x",
- errors, maxerrors, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(dom, -1);
-
- if (maxerrors)
- virCheckNonNullArgGoto(errors, error);
- else
- virCheckNullArgGoto(errors, error);
-
- if (dom->conn->driver->domainGetDiskErrors) {
- int ret = dom->conn->driver->domainGetDiskErrors(dom, errors,
- maxerrors, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(dom->conn);
- return -1;
-}
-
-
-/**
- * virDomainGetHostname:
- * @domain: a domain object
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Get the hostname for that domain.
- *
- * Dependent on hypervisor used, this may require a guest agent to be
- * available.
- *
- * Returns the hostname which must be freed by the caller, or
- * NULL if there was an error.
- */
-char *
-virDomainGetHostname(virDomainPtr domain, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, NULL);
- conn = domain->conn;
-
- if (conn->driver->domainGetHostname) {
- char *ret;
- ret = conn->driver->domainGetHostname(domain, flags);
- if (!ret)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(domain->conn);
- return NULL;
-}
-
-
-/**
- * virNodeGetCPUMap:
- * @conn: pointer to the hypervisor connection
- * @cpumap: optional pointer to a bit map of real CPUs on the host node
- * (in 8-bit bytes) (OUT)
- * In case of success each bit set to 1 means that corresponding
- * CPU is online.
- * Bytes are stored in little-endian order: CPU0-7, 8-15...
- * In each byte, lowest CPU number is least significant bit.
- * The bit map is allocated by virNodeGetCPUMap and needs
- * to be released using free() by the caller.
- * @online: optional number of online CPUs in cpumap (OUT)
- * Contains the number of online CPUs if the call was successful.
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Get CPU map of host node CPUs.
- *
- * Returns number of CPUs present on the host node,
- * or -1 if there was an error.
- */
-int
-virNodeGetCPUMap(virConnectPtr conn,
- unsigned char **cpumap,
- unsigned int *online,
- unsigned int flags)
-{
- VIR_DEBUG("conn=%p, cpumap=%p, online=%p, flags=%x",
- conn, cpumap, online, flags);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
-
- if (conn->driver->nodeGetCPUMap) {
- int ret = conn->driver->nodeGetCPUMap(conn, cpumap, online, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainFSTrim:
- * @dom: a domain object
- * @mountPoint: which mount point to trim
- * @minimum: Minimum contiguous free range to discard in bytes
- * @flags: extra flags, not used yet, so callers should always pass 0
- *
- * Calls FITRIM within the guest (hence guest agent may be
- * required depending on hypervisor used). Either call it on each
- * mounted filesystem (@mountPoint is NULL) or just on specified
- * @mountPoint. @minimum hints that free ranges smaller than this
- * may be ignored (this is a hint and the guest may not respect
- * it). By increasing this value, the fstrim operation will
- * complete more quickly for filesystems with badly fragmented
- * free space, although not all blocks will be discarded.
- * If @minimum is not zero, the command may fail.
- *
- * Returns 0 on success, -1 otherwise.
+ * Returns -1 on error, 0 on success, 1 when remote party doesn't support
+ * keepalive messages.
*/
int
-virDomainFSTrim(virDomainPtr dom,
- const char *mountPoint,
- unsigned long long minimum,
- unsigned int flags)
+virConnectSetKeepAlive(virConnectPtr conn,
+ int interval,
+ unsigned int count)
{
- VIR_DOMAIN_DEBUG(dom, "mountPoint=%s, minimum=%llu, flags=%x",
- mountPoint, minimum, flags);
+ int ret = -1;
+
+ VIR_DEBUG("conn=%p, interval=%d, count=%u", conn, interval, count);
virResetLastError();
- virCheckDomainReturn(dom, -1);
- virCheckReadOnlyGoto(dom->conn->flags, error);
+ virCheckConnectReturn(conn, -1);
- if (dom->conn->driver->domainFSTrim) {
- int ret = dom->conn->driver->domainFSTrim(dom, mountPoint,
- minimum, flags);
+ if (conn->driver->connectSetKeepAlive) {
+ ret = conn->driver->connectSetKeepAlive(conn, interval, count);
if (ret < 0)
goto error;
return ret;
@@ -13362,185 +2594,200 @@ virDomainFSTrim(virDomainPtr dom,
virReportUnsupportedError();
error:
- virDispatchError(dom->conn);
+ virDispatchError(conn);
return -1;
}
+
/**
- * virDomainFSFreeze:
- * @dom: a domain object
- * @mountpoints: list of mount points to be frozen
- * @nmountpoints: the number of mount points specified in @mountpoints
- * @flags: extra flags; not used yet, so callers should always pass 0
+ * virConnectIsAlive:
+ * @conn: pointer to the connection object
*
- * Freeze specified filesystems within the guest (hence guest agent
- * may be required depending on hypervisor used). If @mountpoints is NULL and
- * @nmountpoints is 0, every mounted filesystem on the guest is frozen.
- * In some environments (e.g. QEMU guest with guest agent which doesn't
- * support mountpoints argument), @mountpoints may need to be NULL.
+ * Determine if the connection to the hypervisor is still alive
+ *
+ * A connection will be classed as alive if it is either local, or running
+ * over a channel (TCP or UNIX socket) which is not closed.
*
- * Returns the number of frozen filesystems on success, -1 otherwise.
+ * Returns 1 if alive, 0 if dead, -1 on error
*/
int
-virDomainFSFreeze(virDomainPtr dom,
- const char **mountpoints,
- unsigned int nmountpoints,
- unsigned int flags)
+virConnectIsAlive(virConnectPtr conn)
{
- VIR_DOMAIN_DEBUG(dom, "mountpoints=%p, nmountpoints=%d, flags=%x",
- mountpoints, nmountpoints, flags);
+ VIR_DEBUG("conn=%p", conn);
virResetLastError();
- virCheckDomainReturn(dom, -1);
- virCheckReadOnlyGoto(dom->conn->flags, error);
- if (nmountpoints)
- virCheckNonNullArgGoto(mountpoints, error);
- else
- virCheckNullArgGoto(mountpoints, error);
-
- if (dom->conn->driver->domainFSFreeze) {
- int ret = dom->conn->driver->domainFSFreeze(
- dom, mountpoints, nmountpoints, flags);
+ virCheckConnectReturn(conn, -1);
+ if (conn->driver->connectIsAlive) {
+ int ret;
+ ret = conn->driver->connectIsAlive(conn);
if (ret < 0)
goto error;
return ret;
}
virReportUnsupportedError();
-
error:
- virDispatchError(dom->conn);
+ virDispatchError(conn);
return -1;
}
+
/**
- * virDomainFSThaw:
- * @dom: a domain object
- * @mountpoints: list of mount points to be thawed
- * @nmountpoints: the number of mount points specified in @mountpoints
- * @flags: extra flags; not used yet, so callers should always pass 0
+ * virConnectRegisterCloseCallback:
+ * @conn: pointer to connection object
+ * @cb: callback to invoke upon close
+ * @opaque: user data to pass to @cb
+ * @freecb: callback to free @opaque
+ *
+ * Registers a callback to be invoked when the connection
+ * is closed. This callback is invoked when there is any
+ * condition that causes the socket connection to the
+ * hypervisor to be closed.
+ *
+ * This function is only applicable to hypervisor drivers
+ * which maintain a persistent open connection. Drivers
+ * which open a new connection for every operation will
+ * not invoke this.
*
- * Thaw specified filesystems within the guest. If @mountpoints is NULL and
- * @nmountpoints is 0, every mounted filesystem on the guest is thawed.
- * In some drivers (e.g. QEMU driver), @mountpoints may need to be NULL.
+ * The @freecb must not invoke any other libvirt public
+ * APIs, since it is not called from a re-entrant safe
+ * context.
*
- * Returns the number of thawed filesystems on success, -1 otherwise.
+ * Returns 0 on success, -1 on error
*/
int
-virDomainFSThaw(virDomainPtr dom,
- const char **mountpoints,
- unsigned int nmountpoints,
- unsigned int flags)
+virConnectRegisterCloseCallback(virConnectPtr conn,
+ virConnectCloseFunc cb,
+ void *opaque,
+ virFreeCallback freecb)
{
- VIR_DOMAIN_DEBUG(dom, "flags=%x", flags);
+ VIR_DEBUG("conn=%p", conn);
virResetLastError();
- virCheckDomainReturn(dom, -1);
- virCheckReadOnlyGoto(dom->conn->flags, error);
- if (nmountpoints)
- virCheckNonNullArgGoto(mountpoints, error);
- else
- virCheckNullArgGoto(mountpoints, error);
+ virCheckConnectReturn(conn, -1);
- if (dom->conn->driver->domainFSThaw) {
- int ret = dom->conn->driver->domainFSThaw(
- dom, mountpoints, nmountpoints, flags);
- if (ret < 0)
- goto error;
- return ret;
+ virObjectRef(conn);
+
+ virMutexLock(&conn->lock);
+ virObjectLock(conn->closeCallback);
+
+ virCheckNonNullArgGoto(cb, error);
+
+ if (conn->closeCallback->callback) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("A close callback is already registered"));
+ goto error;
}
- virReportUnsupportedError();
+ conn->closeCallback->conn = conn;
+ conn->closeCallback->callback = cb;
+ conn->closeCallback->opaque = opaque;
+ conn->closeCallback->freeCallback = freecb;
+
+ virObjectUnlock(conn->closeCallback);
+ virMutexUnlock(&conn->lock);
+
+ return 0;
error:
- virDispatchError(dom->conn);
+ virObjectUnlock(conn->closeCallback);
+ virMutexUnlock(&conn->lock);
+ virDispatchError(conn);
+ virObjectUnref(conn);
return -1;
}
+
/**
- * virDomainGetTime:
- * @dom: a domain object
- * @seconds: domain's time in seconds
- * @nseconds: the nanoscond part of @seconds
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Extract information about guest time and store it into
- * @seconds and @nseconds. The @seconds represents the number of
- * seconds since the UNIX Epoch of 1970-01-01 00:00:00 in UTC.
+ * virConnectUnregisterCloseCallback:
+ * @conn: pointer to connection object
+ * @cb: pointer to the current registered callback
*
- * Please note that some hypervisors may require guest agent to
- * be configured and running in order to run this API.
+ * Unregisters the callback previously set with the
+ * virConnectRegisterCloseCallback method. The callback
+ * will no longer receive notifications when the connection
+ * closes. If a virFreeCallback was provided at time of
+ * registration, it will be invoked
*
- * Returns 0 on success, -1 otherwise.
+ * Returns 0 on success, -1 on error
*/
int
-virDomainGetTime(virDomainPtr dom,
- long long *seconds,
- unsigned int *nseconds,
- unsigned int flags)
+virConnectUnregisterCloseCallback(virConnectPtr conn,
+ virConnectCloseFunc cb)
{
- VIR_DOMAIN_DEBUG(dom, "seconds=%p, nseconds=%p, flags=%x",
- seconds, nseconds, flags);
+ VIR_DEBUG("conn=%p", conn);
virResetLastError();
- virCheckDomainReturn(dom, -1);
+ virCheckConnectReturn(conn, -1);
- if (dom->conn->driver->domainGetTime) {
- int ret = dom->conn->driver->domainGetTime(dom, seconds,
- nseconds, flags);
- if (ret < 0)
- goto error;
- return ret;
+ virMutexLock(&conn->lock);
+ virObjectLock(conn->closeCallback);
+
+ virCheckNonNullArgGoto(cb, error);
+
+ if (conn->closeCallback->callback != cb) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("A different callback was requested"));
+ goto error;
}
- virReportUnsupportedError();
+ conn->closeCallback->callback = NULL;
+ if (conn->closeCallback->freeCallback)
+ conn->closeCallback->freeCallback(conn->closeCallback->opaque);
+ conn->closeCallback->freeCallback = NULL;
+
+ virObjectUnref(conn);
+ virObjectUnlock(conn->closeCallback);
+ virMutexUnlock(&conn->lock);
+
+ return 0;
error:
- virDispatchError(dom->conn);
+ virObjectUnlock(conn->closeCallback);
+ virMutexUnlock(&conn->lock);
+ virDispatchError(conn);
return -1;
}
+
/**
- * virDomainSetTime:
- * @dom: a domain object
- * @seconds: time to set
- * @nseconds: the nanosecond part of @seconds
- * @flags: bitwise-OR of virDomainSetTimeFlags
- *
- * When a domain is suspended or restored from a file the
- * domain's OS has no idea that there was a big gap in the time.
- * Depending on how long the gap was, NTP might not be able to
- * resynchronize the guest.
- *
- * This API tries to set guest time to the given value. The time
- * to set (@seconds and @nseconds) should be in seconds relative
- * to the Epoch of 1970-01-01 00:00:00 in UTC.
+ * virNodeGetCPUMap:
+ * @conn: pointer to the hypervisor connection
+ * @cpumap: optional pointer to a bit map of real CPUs on the host node
+ * (in 8-bit bytes) (OUT)
+ * In case of success each bit set to 1 means that corresponding
+ * CPU is online.
+ * Bytes are stored in little-endian order: CPU0-7, 8-15...
+ * In each byte, lowest CPU number is least significant bit.
+ * The bit map is allocated by virNodeGetCPUMap and needs
+ * to be released using free() by the caller.
+ * @online: optional number of online CPUs in cpumap (OUT)
+ * Contains the number of online CPUs if the call was successful.
+ * @flags: extra flags; not used yet, so callers should always pass 0
*
- * Please note that some hypervisors may require guest agent to
- * be configured and running in order to be able to run this API.
+ * Get CPU map of host node CPUs.
*
- * Returns 0 on success, -1 otherwise.
+ * Returns number of CPUs present on the host node,
+ * or -1 if there was an error.
*/
int
-virDomainSetTime(virDomainPtr dom,
- long long seconds,
- unsigned int nseconds,
+virNodeGetCPUMap(virConnectPtr conn,
+ unsigned char **cpumap,
+ unsigned int *online,
unsigned int flags)
{
- VIR_DOMAIN_DEBUG(dom, "seconds=%lld, nseconds=%u, flags=%x",
- seconds, nseconds, flags);
+ VIR_DEBUG("conn=%p, cpumap=%p, online=%p, flags=%x",
+ conn, cpumap, online, flags);
virResetLastError();
- virCheckDomainReturn(dom, -1);
- virCheckReadOnlyGoto(dom->conn->flags, error);
+ virCheckConnectReturn(conn, -1);
- if (dom->conn->driver->domainSetTime) {
- int ret = dom->conn->driver->domainSetTime(dom, seconds,
- nseconds, flags);
+ if (conn->driver->nodeGetCPUMap) {
+ int ret = conn->driver->nodeGetCPUMap(conn, cpumap, online, flags);
if (ret < 0)
goto error;
return ret;
@@ -13549,7 +2796,7 @@ virDomainSetTime(virDomainPtr dom,
virReportUnsupportedError();
error:
- virDispatchError(dom->conn);
+ virDispatchError(conn);
return -1;
}
@@ -13650,339 +2897,6 @@ virNodeGetFreePages(virConnectPtr conn,
/**
- * virConnectGetDomainCapabilities:
- * @conn: pointer to the hypervisor connection
- * @emulatorbin: path to emulator
- * @arch: domain architecture
- * @machine: machine type
- * @virttype: virtualization type
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Prior creating a domain (for instance via virDomainCreateXML
- * or virDomainDefineXML) it may be suitable to know what the
- * underlying emulator and/or libvirt is capable of. For
- * instance, if host, libvirt and qemu is capable of VFIO
- * passthrough and so on.
- *
- * Returns NULL in case of error or an XML string
- * defining the capabilities.
- */
-char *
-virConnectGetDomainCapabilities(virConnectPtr conn,
- const char *emulatorbin,
- const char *arch,
- const char *machine,
- const char *virttype,
- unsigned int flags)
-{
- VIR_DEBUG("conn=%p, emulatorbin=%s, arch=%s, "
- "machine=%s, virttype=%s, flags=%x",
- conn, NULLSTR(emulatorbin), NULLSTR(arch),
- NULLSTR(machine), NULLSTR(virttype), flags);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, NULL);
-
- if (conn->driver->connectGetDomainCapabilities) {
- char *ret;
- ret = conn->driver->connectGetDomainCapabilities(conn, emulatorbin,
- arch, machine,
- virttype, flags);
- if (!ret)
- goto error;
- VIR_DEBUG("conn=%p, ret=%s", conn, ret);
- return ret;
- }
-
- virReportUnsupportedError();
-
- error:
- virDispatchError(conn);
- return NULL;
-}
-
-
-/**
- * virConnectGetAllDomainStats:
- * @conn: pointer to the hypervisor connection
- * @stats: stats to return, binary-OR of virDomainStatsTypes
- * @retStats: Pointer that will be filled with the array of returned stats
- * @flags: extra flags; binary-OR of virConnectGetAllDomainStatsFlags
- *
- * Query statistics for all domains on a given connection.
- *
- * Report statistics of various parameters for a running VM according to @stats
- * field. The statistics are returned as an array of structures for each queried
- * domain. The structure contains an array of typed parameters containing the
- * individual statistics. The typed parameter name for each statistic field
- * consists of a dot-separated string containing name of the requested group
- * followed by a group specific description of the statistic value.
- *
- * The statistic groups are enabled using the @stats parameter which is a
- * binary-OR of enum virDomainStatsTypes. The following groups are available
- * (although not necessarily implemented for each hypervisor):
- *
- * VIR_DOMAIN_STATS_STATE: Return domain state and reason for entering that
- * state. The typed parameter keys are in this format:
- * "state.state" - state of the VM, returned as int from virDomainState enum
- * "state.reason" - reason for entering given state, returned as int from
- * virDomain*Reason enum corresponding to given state.
- *
- * VIR_DOMAIN_STATS_CPU_TOTAL: Return CPU statistics and usage information.
- * The typed parameter keys are in this format:
- * "cpu.time" - total cpu time spent for this domain in nanoseconds
- * as unsigned long long.
- * "cpu.user" - user cpu time spent in nanoseconds as unsigned long long.
- * "cpu.system" - system cpu time spent in nanoseconds as unsigned long long.
- *
- * VIR_DOMAIN_STATS_BALLOON: Return memory balloon device information.
- * The typed parameter keys are in this format:
- * "balloon.current" - the memory in kiB currently used
- * as unsigned long long.
- * "balloon.maximum" - the maximum memory in kiB allowed
- * as unsigned long long.
- *
- * VIR_DOMAIN_STATS_VCPU: Return virtual CPU statistics.
- * Due to VCPU hotplug, the vcpu.<num>.* array could be sparse.
- * The actual size of the array corresponds to "vcpu.current".
- * The array size will never exceed "vcpu.maximum".
- * The typed parameter keys are in this format:
- * "vcpu.current" - current number of online virtual CPUs as unsigned int.
- * "vcpu.maximum" - maximum number of online virtual CPUs as unsigned int.
- * "vcpu.<num>.state" - state of the virtual CPU <num>, as int
- * from virVcpuState enum.
- * "vcpu.<num>.time" - virtual cpu time spent by virtual CPU <num>
- * as unsigned long long.
- *
- * VIR_DOMAIN_STATS_INTERFACE: Return network interface statistics.
- * The typed parameter keys are in this format:
- * "net.count" - number of network interfaces on this domain
- * as unsigned int.
- * "net.<num>.name" - name of the interface <num> as string.
- * "net.<num>.rx.bytes" - bytes received as unsigned long long.
- * "net.<num>.rx.pkts" - packets received as unsigned long long.
- * "net.<num>.rx.errs" - receive errors as unsigned long long.
- * "net.<num>.rx.drop" - receive packets dropped as unsigned long long.
- * "net.<num>.tx.bytes" - bytes transmitted as unsigned long long.
- * "net.<num>.tx.pkts" - packets transmitted as unsigned long long.
- * "net.<num>.tx.errs" - transmission errors as unsigned long long.
- * "net.<num>.tx.drop" - transmit packets dropped as unsigned long long.
- *
- * VIR_DOMAIN_STATS_BLOCK: Return block devices statistics.
- * The typed parameter keys are in this format:
- * "block.count" - number of block devices on this domain
- * as unsigned int.
- * "block.<num>.name" - name of the block device <num> as string.
- * matches the target name (vda/sda/hda) of the
- * block device.
- * "block.<num>.rd.reqs" - number of read requests as unsigned long
long.
- * "block.<num>.rd.bytes" - number of read bytes as unsigned long long.
- * "block.<num>.rd.times" - total time (ns) spent on reads as
- * unsigned long long.
- * "block.<num>.wr.reqs" - number of write requests as unsigned long
long.
- * "block.<num>.wr.bytes" - number of written bytes as unsigned long
long.
- * "block.<num>.wr.times" - total time (ns) spent on writes as
- * unsigned long long.
- * "block.<num>.fl.reqs" - total flush requests as unsigned long long.
- * "block.<num>.fl.times" - total time (ns) spent on cache flushing as
- * unsigned long long.
- * "block.<num>.errors" - Xen only: the 'oo_req' value as
- * unsigned long long.
- * "block.<num>.allocation" - offset of the highest written sector
- * as unsigned long long.
- * "block.<num>.capacity" - logical size in bytes of the block device
backing
- * image as unsigned long long.
- * "block.<num>.physical" - physical size in bytes of the container of
the
- * backing image as unsigned long long.
- *
- * Note that entire stats groups or individual stat fields may be missing from
- * the output in case they are not supported by the given hypervisor, are not
- * applicable for the current state of the guest domain, or their retrieval
- * was not successful.
- *
- * Using 0 for @stats returns all stats groups supported by the given
- * hypervisor.
- *
- * Specifying VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS as @flags makes
- * the function return error in case some of the stat types in @stats were
- * not recognized by the daemon.
- *
- * Similarly to virConnectListAllDomains, @flags can contain various flags to
- * filter the list of domains to provide stats for.
- *
- * VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE selects online domains while
- * VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE selects offline ones.
- *
- * VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT and
- * VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT allow to filter the list
- * according to their persistence.
- *
- * To filter the list of VMs by domain state @flags can contain
- * VIR_CONNECT_GET_ALL_DOMAINS_STATS_RUNNING,
- * VIR_CONNECT_GET_ALL_DOMAINS_STATS_PAUSED,
- * VIR_CONNECT_GET_ALL_DOMAINS_STATS_SHUTOFF and/or
- * VIR_CONNECT_GET_ALL_DOMAINS_STATS_OTHER for all other states.
- *
- * Returns the count of returned statistics structures on success, -1 on error.
- * The requested data are returned in the @retStats parameter. The returned
- * array should be freed by the caller. See virDomainStatsRecordListFree.
- */
-int
-virConnectGetAllDomainStats(virConnectPtr conn,
- unsigned int stats,
- virDomainStatsRecordPtr **retStats,
- unsigned int flags)
-{
- int ret = -1;
-
- VIR_DEBUG("conn=%p, stats=0x%x, retStats=%p, flags=0x%x",
- conn, stats, retStats, flags);
-
- virResetLastError();
-
- virCheckConnectReturn(conn, -1);
- virCheckNonNullArgGoto(retStats, cleanup);
-
- if (!conn->driver->connectGetAllDomainStats) {
- virReportUnsupportedError();
- goto cleanup;
- }
-
- ret = conn->driver->connectGetAllDomainStats(conn, NULL, 0, stats,
- retStats, flags);
-
- cleanup:
- if (ret < 0)
- virDispatchError(conn);
-
- return ret;
-}
-
-
-/**
- * virDomainListGetStats:
- * @doms: NULL terminated array of domains
- * @stats: stats to return, binary-OR of virDomainStatsTypes
- * @retStats: Pointer that will be filled with the array of returned stats
- * @flags: extra flags; binary-OR of virConnectGetAllDomainStatsFlags
- *
- * Query statistics for domains provided by @doms. Note that all domains in
- * @doms must share the same connection.
- *
- * Report statistics of various parameters for a running VM according to @stats
- * field. The statistics are returned as an array of structures for each queried
- * domain. The structure contains an array of typed parameters containing the
- * individual statistics. The typed parameter name for each statistic field
- * consists of a dot-separated string containing name of the requested group
- * followed by a group specific description of the statistic value.
- *
- * The statistic groups are enabled using the @stats parameter which is a
- * binary-OR of enum virDomainStatsTypes. The stats groups are documented
- * in virConnectGetAllDomainStats.
- *
- * Using 0 for @stats returns all stats groups supported by the given
- * hypervisor.
- *
- * Specifying VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS as @flags makes
- * the function return error in case some of the stat types in @stats were
- * not recognized by the daemon.
- *
- * Note that any of the domain list filtering flags in @flags will be rejected
- * by this function.
- *
- * Returns the count of returned statistics structures on success, -1 on error.
- * The requested data are returned in the @retStats parameter. The returned
- * array should be freed by the caller. See virDomainStatsRecordListFree.
- * Note that the count of returned stats may be less than the domain count
- * provided via @doms.
- */
-int
-virDomainListGetStats(virDomainPtr *doms,
- unsigned int stats,
- virDomainStatsRecordPtr **retStats,
- unsigned int flags)
-{
- virConnectPtr conn = NULL;
- virDomainPtr *nextdom = doms;
- unsigned int ndoms = 0;
- int ret = -1;
-
- VIR_DEBUG("doms=%p, stats=0x%x, retStats=%p, flags=0x%x",
- doms, stats, retStats, flags);
-
- virResetLastError();
-
- virCheckNonNullArgGoto(doms, cleanup);
- virCheckNonNullArgGoto(retStats, cleanup);
-
- if (!*doms) {
- virReportError(VIR_ERR_INVALID_ARG,
- _("doms array in %s must contain at least one domain"),
- __FUNCTION__);
- goto cleanup;
- }
-
- conn = doms[0]->conn;
- virCheckConnectReturn(conn, -1);
-
- if (!conn->driver->connectGetAllDomainStats) {
- virReportUnsupportedError();
- goto cleanup;
- }
-
- while (*nextdom) {
- virDomainPtr dom = *nextdom;
-
- virCheckDomainGoto(dom, cleanup);
-
- if (dom->conn != conn) {
- virReportError(VIR_ERR_INVALID_ARG,
- _("domains in 'doms' array must belong to a
"
- "single connection in %s"), __FUNCTION__);
- goto cleanup;
- }
-
- ndoms++;
- nextdom++;
- }
-
- ret = conn->driver->connectGetAllDomainStats(conn, doms, ndoms,
- stats, retStats, flags);
-
- cleanup:
- if (ret < 0)
- virDispatchError(conn);
- return ret;
-}
-
-
-/**
- * virDomainStatsRecordListFree:
- * @stats: NULL terminated array of virDomainStatsRecords to free
- *
- * Convenience function to free a list of domain stats returned by
- * virDomainListGetStats and virConnectGetAllDomainStats.
- */
-void
-virDomainStatsRecordListFree(virDomainStatsRecordPtr *stats)
-{
- virDomainStatsRecordPtr *next;
-
- if (!stats)
- return;
-
- for (next = stats; *next; next++) {
- virTypedParamsFree((*next)->params, (*next)->nparams);
- virDomainFree((*next)->dom);
- VIR_FREE(*next);
- }
-
- VIR_FREE(stats);
-}
-
-
-/**
* virNodeAllocPages:
* @conn: pointer to the hypervisor connection
* @npages: number of items in the @pageSizes and
diff --git a/src/libvirt_internal.h b/src/libvirt_internal.h
index ebf2acf..304d90f 100644
--- a/src/libvirt_internal.h
+++ b/src/libvirt_internal.h
@@ -285,4 +285,10 @@ int virDomainMigrateConfirm3Params(virDomainPtr domain,
int cookieinlen,
unsigned int flags,
int cancelled);
+
+int
+virTypedParameterValidateSet(virConnectPtr conn,
+ virTypedParameterPtr params,
+ int nparams);
+
#endif
--
2.1.0