mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
save: new public API to bypass file system cache on save/restore
In order to choose whether to use O_DIRECT when saving a domain image to a file, we need a new flag. But virDomainSave was implemented before our policy of all new APIs having a flag argument. Likewise for virDomainRestore when restoring from a file. The new flag name is chosen as CACHE_BYPASS so as not to preclude a future solution that uses posix_fadvise once the Linux kernel has a smarter implementation of that interface. * include/libvirt/libvirt.h.in (virDomainCreateFlags) (virDomainCoreDumpFlags): Add a flag. (virDomainSaveFlags, virDomainRestoreFlags): New prototypes. * src/libvirt.c (virDomainSaveFlags, virDomainRestoreFlags): New API. * src/libvirt_public.syms: Export them. * src/driver.h (virDrvDomainSaveFlags, virDrvDomainRestoreFlags): New driver callbacks.
This commit is contained in:
parent
360e5ea144
commit
ad0b912384
@ -232,9 +232,10 @@ typedef virDomainInfo *virDomainInfoPtr;
|
|||||||
* Domain.
|
* Domain.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VIR_DOMAIN_NONE = 0, /* Default behavior */
|
VIR_DOMAIN_NONE = 0, /* Default behavior */
|
||||||
VIR_DOMAIN_START_PAUSED = 1 << 0, /* Launch guest in paused state */
|
VIR_DOMAIN_START_PAUSED = 1 << 0, /* Launch guest in paused state */
|
||||||
VIR_DOMAIN_START_AUTODESTROY = 1 << 1, /* Automatically kill guest when virConnectPtr is closed */
|
VIR_DOMAIN_START_AUTODESTROY = 1 << 1, /* Automatically kill guest when virConnectPtr is closed */
|
||||||
|
VIR_DOMAIN_START_BYPASS_CACHE = 1 << 2, /* Avoid file system cache pollution */
|
||||||
} virDomainCreateFlags;
|
} virDomainCreateFlags;
|
||||||
|
|
||||||
|
|
||||||
@ -657,8 +658,9 @@ typedef virDomainMemoryStatStruct *virDomainMemoryStatPtr;
|
|||||||
|
|
||||||
/* Domain core dump flags. */
|
/* Domain core dump flags. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VIR_DUMP_CRASH = (1 << 0), /* crash after dump */
|
VIR_DUMP_CRASH = (1 << 0), /* crash after dump */
|
||||||
VIR_DUMP_LIVE = (1 << 1), /* live dump */
|
VIR_DUMP_LIVE = (1 << 1), /* live dump */
|
||||||
|
VIR_DUMP_BYPASS_CACHE = (1 << 2), /* avoid file system cache pollution */
|
||||||
} virDomainCoreDumpFlags;
|
} virDomainCoreDumpFlags;
|
||||||
|
|
||||||
/* Domain migration flags. */
|
/* Domain migration flags. */
|
||||||
@ -941,10 +943,28 @@ int virDomainResume (virDomainPtr domain);
|
|||||||
/*
|
/*
|
||||||
* Domain save/restore
|
* Domain save/restore
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virDomainSaveRestoreFlags:
|
||||||
|
* Flags for use in virDomainSaveFlags(), virDomainManagedSave(), and
|
||||||
|
* virDomainRestoreFlags().
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
VIR_DOMAIN_SAVE_BYPASS_CACHE = 1 << 0, /* Avoid file system cache pollution */
|
||||||
|
} virDomainSaveRestoreFlags;
|
||||||
|
|
||||||
int virDomainSave (virDomainPtr domain,
|
int virDomainSave (virDomainPtr domain,
|
||||||
const char *to);
|
const char *to);
|
||||||
|
int virDomainSaveFlags (virDomainPtr domain,
|
||||||
|
const char *to,
|
||||||
|
const char *dxml,
|
||||||
|
unsigned int flags);
|
||||||
int virDomainRestore (virConnectPtr conn,
|
int virDomainRestore (virConnectPtr conn,
|
||||||
const char *from);
|
const char *from);
|
||||||
|
int virDomainRestoreFlags (virConnectPtr conn,
|
||||||
|
const char *from,
|
||||||
|
const char *dxml,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Managed domain save
|
* Managed domain save
|
||||||
|
12
src/driver.h
12
src/driver.h
@ -177,9 +177,19 @@ typedef int
|
|||||||
typedef int
|
typedef int
|
||||||
(*virDrvDomainSave) (virDomainPtr domain,
|
(*virDrvDomainSave) (virDomainPtr domain,
|
||||||
const char *to);
|
const char *to);
|
||||||
|
typedef int
|
||||||
|
(*virDrvDomainSaveFlags) (virDomainPtr domain,
|
||||||
|
const char *to,
|
||||||
|
const char *dxml,
|
||||||
|
unsigned int flags);
|
||||||
typedef int
|
typedef int
|
||||||
(*virDrvDomainRestore) (virConnectPtr conn,
|
(*virDrvDomainRestore) (virConnectPtr conn,
|
||||||
const char *from);
|
const char *from);
|
||||||
|
typedef int
|
||||||
|
(*virDrvDomainRestoreFlags) (virConnectPtr conn,
|
||||||
|
const char *from,
|
||||||
|
const char *dxml,
|
||||||
|
unsigned int flags);
|
||||||
typedef int
|
typedef int
|
||||||
(*virDrvDomainCoreDump) (virDomainPtr domain,
|
(*virDrvDomainCoreDump) (virDomainPtr domain,
|
||||||
const char *to,
|
const char *to,
|
||||||
@ -714,7 +724,9 @@ struct _virDriver {
|
|||||||
virDrvDomainGetState domainGetState;
|
virDrvDomainGetState domainGetState;
|
||||||
virDrvDomainGetControlInfo domainGetControlInfo;
|
virDrvDomainGetControlInfo domainGetControlInfo;
|
||||||
virDrvDomainSave domainSave;
|
virDrvDomainSave domainSave;
|
||||||
|
virDrvDomainSaveFlags domainSaveFlags;
|
||||||
virDrvDomainRestore domainRestore;
|
virDrvDomainRestore domainRestore;
|
||||||
|
virDrvDomainRestoreFlags domainRestoreFlags;
|
||||||
virDrvDomainCoreDump domainCoreDump;
|
virDrvDomainCoreDump domainCoreDump;
|
||||||
virDrvDomainScreenshot domainScreenshot;
|
virDrvDomainScreenshot domainScreenshot;
|
||||||
virDrvDomainSetVcpus domainSetVcpus;
|
virDrvDomainSetVcpus domainSetVcpus;
|
||||||
|
181
src/libvirt.c
181
src/libvirt.c
@ -2242,6 +2242,8 @@ error:
|
|||||||
* listed as running anymore (this may be a problem).
|
* listed as running anymore (this may be a problem).
|
||||||
* Use virDomainRestore() to restore a domain after saving.
|
* Use virDomainRestore() to restore a domain after saving.
|
||||||
*
|
*
|
||||||
|
* See virDomainSaveFlags() for more control.
|
||||||
|
*
|
||||||
* Returns 0 in case of success and -1 in case of failure.
|
* Returns 0 in case of success and -1 in case of failure.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
@ -2295,6 +2297,85 @@ error:
|
|||||||
return -1;
|
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 may be a problem).
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* 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();
|
||||||
|
|
||||||
|
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
|
||||||
|
virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
|
||||||
|
virDispatchError(NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (domain->conn->flags & VIR_CONNECT_RO) {
|
||||||
|
virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
conn = domain->conn;
|
||||||
|
if (to == NULL) {
|
||||||
|
virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||||
|
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) {
|
||||||
|
virLibConnError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("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;
|
||||||
|
}
|
||||||
|
|
||||||
|
virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDispatchError(domain->conn);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virDomainRestore:
|
* virDomainRestore:
|
||||||
* @conn: pointer to the hypervisor connection
|
* @conn: pointer to the hypervisor connection
|
||||||
@ -2302,6 +2383,8 @@ error:
|
|||||||
*
|
*
|
||||||
* This method will restore a domain saved to disk by virDomainSave().
|
* 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.
|
* Returns 0 in case of success and -1 in case of failure.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
@ -2352,6 +2435,80 @@ error:
|
|||||||
return -1;
|
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 saves to NFS.
|
||||||
|
*
|
||||||
|
* 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();
|
||||||
|
|
||||||
|
if (!VIR_IS_CONNECT(conn)) {
|
||||||
|
virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
|
||||||
|
virDispatchError(NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (conn->flags & VIR_CONNECT_RO) {
|
||||||
|
virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (from == NULL) {
|
||||||
|
virLibConnError(VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||||
|
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) {
|
||||||
|
virLibConnError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("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;
|
||||||
|
}
|
||||||
|
|
||||||
|
virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
|
||||||
|
|
||||||
|
error:
|
||||||
|
virDispatchError(conn);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virDomainCoreDump:
|
* virDomainCoreDump:
|
||||||
* @domain: a domain object
|
* @domain: a domain object
|
||||||
@ -2362,6 +2519,17 @@ error:
|
|||||||
* Note that for remote Xen Daemon the file path will be interpreted in
|
* Note that for remote Xen Daemon the file path will be interpreted in
|
||||||
* the remote host.
|
* the remote host.
|
||||||
*
|
*
|
||||||
|
* 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.
|
||||||
|
* The above two 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.
|
* Returns 0 in case of success and -1 in case of failure.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
@ -6612,6 +6780,12 @@ error:
|
|||||||
* libvirtd daemon. Any domains marked for auto destroy will
|
* libvirtd daemon. Any domains marked for auto destroy will
|
||||||
* block attempts at migration or save-to-file
|
* block attempts at migration or save-to-file
|
||||||
*
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
* Returns 0 in case of success, -1 in case of error
|
* Returns 0 in case of success, -1 in case of error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
@ -14837,7 +15011,7 @@ error:
|
|||||||
/**
|
/**
|
||||||
* virDomainManagedSave:
|
* virDomainManagedSave:
|
||||||
* @dom: pointer to the domain
|
* @dom: pointer to the domain
|
||||||
* @flags: optional flags currently unused
|
* @flags: bitwise-OR of virDomainSaveRestoreFlags
|
||||||
*
|
*
|
||||||
* This method will suspend a domain and save its memory contents to
|
* 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
|
* a file on disk. After the call, if successful, the domain is not
|
||||||
@ -14847,6 +15021,11 @@ error:
|
|||||||
* restarted (automatically or via an explicit libvirt call).
|
* restarted (automatically or via an explicit libvirt call).
|
||||||
* As a result any running domain is sure to not have a managed saved image.
|
* As a result any running domain is sure to not have a managed saved image.
|
||||||
*
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
* Returns 0 in case of success or -1 in case of failure
|
* Returns 0 in case of success or -1 in case of failure
|
||||||
*/
|
*/
|
||||||
int virDomainManagedSave(virDomainPtr dom, unsigned int flags)
|
int virDomainManagedSave(virDomainPtr dom, unsigned int flags)
|
||||||
|
@ -468,6 +468,8 @@ LIBVIRT_0.9.3 {
|
|||||||
|
|
||||||
LIBVIRT_0.9.4 {
|
LIBVIRT_0.9.4 {
|
||||||
global:
|
global:
|
||||||
|
virDomainRestoreFlags;
|
||||||
|
virDomainSaveFlags;
|
||||||
virDomainUndefineFlags;
|
virDomainUndefineFlags;
|
||||||
} LIBVIRT_0.9.3;
|
} LIBVIRT_0.9.3;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user