mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
add new virDomainCoreDumpWithFormat API
--memory-only option is introduced without compression supported. Now qemu has support for dumping domain's memory in kdump-compressed format. This patch adds a new virDomainCoreDumpWithFormat API, so that the format in which qemu dumps domain's memory can be specified. Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com> Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
ccef7d7876
commit
9fbaff008c
@ -1180,6 +1180,29 @@ typedef enum {
|
|||||||
VIR_DUMP_MEMORY_ONLY = (1 << 4), /* use dump-guest-memory */
|
VIR_DUMP_MEMORY_ONLY = (1 << 4), /* use dump-guest-memory */
|
||||||
} virDomainCoreDumpFlags;
|
} virDomainCoreDumpFlags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virDomainCoreDumpFormat:
|
||||||
|
*
|
||||||
|
* Values for specifying different formats of domain core dumps.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
VIR_DOMAIN_CORE_DUMP_FORMAT_RAW, /* dump guest memory in raw format */
|
||||||
|
VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_ZLIB, /* kdump-compressed format, with
|
||||||
|
* zlib compression */
|
||||||
|
VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_LZO, /* kdump-compressed format, with
|
||||||
|
* lzo compression */
|
||||||
|
VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_SNAPPY, /* kdump-compressed format, with
|
||||||
|
* snappy compression */
|
||||||
|
#ifdef VIR_ENUM_SENTINELS
|
||||||
|
VIR_DOMAIN_CORE_DUMP_FORMAT_LAST
|
||||||
|
/*
|
||||||
|
* NB: this enum value will increase over time as new events are
|
||||||
|
* added to the libvirt API. It reflects the last state supported
|
||||||
|
* by this version of the libvirt API.
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
} virDomainCoreDumpFormat;
|
||||||
|
|
||||||
/* Domain migration flags. */
|
/* Domain migration flags. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VIR_MIGRATE_LIVE = (1 << 0), /* live migration */
|
VIR_MIGRATE_LIVE = (1 << 0), /* live migration */
|
||||||
@ -1731,6 +1754,14 @@ int virDomainCoreDump (virDomainPtr domain,
|
|||||||
const char *to,
|
const char *to,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Domain core dump with format specified
|
||||||
|
*/
|
||||||
|
int virDomainCoreDumpWithFormat (virDomainPtr domain,
|
||||||
|
const char *to,
|
||||||
|
unsigned int dumpformat,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Screenshot of current domain console
|
* Screenshot of current domain console
|
||||||
*/
|
*/
|
||||||
|
@ -306,6 +306,12 @@ typedef int
|
|||||||
const char *to,
|
const char *to,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
|
||||||
|
typedef int
|
||||||
|
(*virDrvDomainCoreDumpWithFormat)(virDomainPtr domain,
|
||||||
|
const char *to,
|
||||||
|
unsigned int dumpformat,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
typedef char *
|
typedef char *
|
||||||
(*virDrvDomainScreenshot)(virDomainPtr domain,
|
(*virDrvDomainScreenshot)(virDomainPtr domain,
|
||||||
virStreamPtr stream,
|
virStreamPtr stream,
|
||||||
@ -1213,6 +1219,7 @@ struct _virDriver {
|
|||||||
virDrvDomainSaveImageGetXMLDesc domainSaveImageGetXMLDesc;
|
virDrvDomainSaveImageGetXMLDesc domainSaveImageGetXMLDesc;
|
||||||
virDrvDomainSaveImageDefineXML domainSaveImageDefineXML;
|
virDrvDomainSaveImageDefineXML domainSaveImageDefineXML;
|
||||||
virDrvDomainCoreDump domainCoreDump;
|
virDrvDomainCoreDump domainCoreDump;
|
||||||
|
virDrvDomainCoreDumpWithFormat domainCoreDumpWithFormat;
|
||||||
virDrvDomainScreenshot domainScreenshot;
|
virDrvDomainScreenshot domainScreenshot;
|
||||||
virDrvDomainSetVcpus domainSetVcpus;
|
virDrvDomainSetVcpus domainSetVcpus;
|
||||||
virDrvDomainSetVcpusFlags domainSetVcpusFlags;
|
virDrvDomainSetVcpusFlags domainSetVcpusFlags;
|
||||||
|
101
src/libvirt.c
101
src/libvirt.c
@ -2937,6 +2937,8 @@ error:
|
|||||||
* or fail if it cannot do so for the given system; this can allow less
|
* 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.
|
* 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.
|
* Returns 0 in case of success and -1 in case of failure.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
@ -2999,6 +3001,105 @@ error:
|
|||||||
return -1;
|
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 quest 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:
|
* virDomainScreenshot:
|
||||||
|
@ -645,5 +645,10 @@ LIBVIRT_1.2.1 {
|
|||||||
virConnectNetworkEventDeregisterAny;
|
virConnectNetworkEventDeregisterAny;
|
||||||
} LIBVIRT_1.1.3;
|
} LIBVIRT_1.1.3;
|
||||||
|
|
||||||
|
LIBVIRT_1.2.3 {
|
||||||
|
global:
|
||||||
|
virDomainCoreDumpWithFormat;
|
||||||
|
} LIBVIRT_1.2.1;
|
||||||
|
|
||||||
|
|
||||||
# .... define new API here using predicted next version number ....
|
# .... define new API here using predicted next version number ....
|
||||||
|
@ -7653,6 +7653,7 @@ static virDriver remote_driver = {
|
|||||||
.domainSaveImageGetXMLDesc = remoteDomainSaveImageGetXMLDesc, /* 0.9.4 */
|
.domainSaveImageGetXMLDesc = remoteDomainSaveImageGetXMLDesc, /* 0.9.4 */
|
||||||
.domainSaveImageDefineXML = remoteDomainSaveImageDefineXML, /* 0.9.4 */
|
.domainSaveImageDefineXML = remoteDomainSaveImageDefineXML, /* 0.9.4 */
|
||||||
.domainCoreDump = remoteDomainCoreDump, /* 0.3.0 */
|
.domainCoreDump = remoteDomainCoreDump, /* 0.3.0 */
|
||||||
|
.domainCoreDumpWithFormat = remoteDomainCoreDumpWithFormat, /* 1.2.3 */
|
||||||
.domainScreenshot = remoteDomainScreenshot, /* 0.9.2 */
|
.domainScreenshot = remoteDomainScreenshot, /* 0.9.2 */
|
||||||
.domainSetVcpus = remoteDomainSetVcpus, /* 0.3.0 */
|
.domainSetVcpus = remoteDomainSetVcpus, /* 0.3.0 */
|
||||||
.domainSetVcpusFlags = remoteDomainSetVcpusFlags, /* 0.8.5 */
|
.domainSetVcpusFlags = remoteDomainSetVcpusFlags, /* 0.8.5 */
|
||||||
|
@ -904,6 +904,13 @@ struct remote_domain_core_dump_args {
|
|||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct remote_domain_core_dump_with_format_args {
|
||||||
|
remote_nonnull_domain dom;
|
||||||
|
remote_nonnull_string to;
|
||||||
|
unsigned int dumpformat;
|
||||||
|
unsigned int flags;
|
||||||
|
};
|
||||||
|
|
||||||
struct remote_domain_screenshot_args {
|
struct remote_domain_screenshot_args {
|
||||||
remote_nonnull_domain dom;
|
remote_nonnull_domain dom;
|
||||||
unsigned int screen;
|
unsigned int screen;
|
||||||
@ -5262,5 +5269,11 @@ enum remote_procedure {
|
|||||||
* @generate: both
|
* @generate: both
|
||||||
* @acl: none
|
* @acl: none
|
||||||
*/
|
*/
|
||||||
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVED = 333
|
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVED = 333,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generate: both
|
||||||
|
* @acl: domain:core_dump
|
||||||
|
*/
|
||||||
|
REMOTE_PROC_DOMAIN_CORE_DUMP_WITH_FORMAT = 334
|
||||||
};
|
};
|
||||||
|
@ -557,6 +557,12 @@ struct remote_domain_core_dump_args {
|
|||||||
remote_nonnull_string to;
|
remote_nonnull_string to;
|
||||||
u_int flags;
|
u_int flags;
|
||||||
};
|
};
|
||||||
|
struct remote_domain_core_dump_with_format_args {
|
||||||
|
remote_nonnull_domain dom;
|
||||||
|
remote_nonnull_string to;
|
||||||
|
u_int dumpformat;
|
||||||
|
u_int flags;
|
||||||
|
};
|
||||||
struct remote_domain_screenshot_args {
|
struct remote_domain_screenshot_args {
|
||||||
remote_nonnull_domain dom;
|
remote_nonnull_domain dom;
|
||||||
u_int screen;
|
u_int screen;
|
||||||
@ -2755,4 +2761,5 @@ enum remote_procedure {
|
|||||||
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_BALLOON_CHANGE = 331,
|
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_BALLOON_CHANGE = 331,
|
||||||
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_PMSUSPEND_DISK = 332,
|
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_PMSUSPEND_DISK = 332,
|
||||||
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVED = 333,
|
REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVED = 333,
|
||||||
|
REMOTE_PROC_DOMAIN_CORE_DUMP_WITH_FORMAT = 334,
|
||||||
};
|
};
|
||||||
|
@ -2428,9 +2428,10 @@ testDomainRestore(virConnectPtr conn,
|
|||||||
return testDomainRestoreFlags(conn, path, NULL, 0);
|
return testDomainRestoreFlags(conn, path, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int testDomainCoreDump(virDomainPtr domain,
|
static int testDomainCoreDumpWithFormat(virDomainPtr domain,
|
||||||
const char *to,
|
const char *to,
|
||||||
unsigned int flags)
|
unsigned int dumpformat,
|
||||||
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
testConnPtr privconn = domain->conn->privateData;
|
testConnPtr privconn = domain->conn->privateData;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
@ -2468,6 +2469,13 @@ static int testDomainCoreDump(virDomainPtr domain,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* we don't support non-raw formats in test driver */
|
||||||
|
if (dumpformat != VIR_DOMAIN_CORE_DUMP_FORMAT_RAW) {
|
||||||
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
||||||
|
_("kdump-compressed format is not supported here"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & VIR_DUMP_CRASH) {
|
if (flags & VIR_DUMP_CRASH) {
|
||||||
testDomainShutdownState(domain, privdom, VIR_DOMAIN_SHUTOFF_CRASHED);
|
testDomainShutdownState(domain, privdom, VIR_DOMAIN_SHUTOFF_CRASHED);
|
||||||
event = virDomainEventLifecycleNewFromObj(privdom,
|
event = virDomainEventLifecycleNewFromObj(privdom,
|
||||||
@ -2491,14 +2499,29 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *testDomainGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED) {
|
|
||||||
|
static int
|
||||||
|
testDomainCoreDump(virDomainPtr domain,
|
||||||
|
const char *to,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
return testDomainCoreDumpWithFormat(domain, to,
|
||||||
|
VIR_DOMAIN_CORE_DUMP_FORMAT_RAW, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
testDomainGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
char *ret;
|
char *ret;
|
||||||
|
|
||||||
ignore_value(VIR_STRDUP(ret, "linux"));
|
ignore_value(VIR_STRDUP(ret, "linux"));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long long testDomainGetMaxMemory(virDomainPtr domain)
|
|
||||||
|
static unsigned long long
|
||||||
|
testDomainGetMaxMemory(virDomainPtr domain)
|
||||||
{
|
{
|
||||||
testConnPtr privconn = domain->conn->privateData;
|
testConnPtr privconn = domain->conn->privateData;
|
||||||
virDomainObjPtr privdom;
|
virDomainObjPtr privdom;
|
||||||
@ -7383,6 +7406,7 @@ static virDriver testDriver = {
|
|||||||
.domainRestore = testDomainRestore, /* 0.3.2 */
|
.domainRestore = testDomainRestore, /* 0.3.2 */
|
||||||
.domainRestoreFlags = testDomainRestoreFlags, /* 0.9.4 */
|
.domainRestoreFlags = testDomainRestoreFlags, /* 0.9.4 */
|
||||||
.domainCoreDump = testDomainCoreDump, /* 0.3.2 */
|
.domainCoreDump = testDomainCoreDump, /* 0.3.2 */
|
||||||
|
.domainCoreDumpWithFormat = testDomainCoreDumpWithFormat, /* 1.2.3 */
|
||||||
.domainSetVcpus = testDomainSetVcpus, /* 0.1.4 */
|
.domainSetVcpus = testDomainSetVcpus, /* 0.1.4 */
|
||||||
.domainSetVcpusFlags = testDomainSetVcpusFlags, /* 0.8.5 */
|
.domainSetVcpusFlags = testDomainSetVcpusFlags, /* 0.8.5 */
|
||||||
.domainGetVcpusFlags = testDomainGetVcpusFlags, /* 0.8.5 */
|
.domainGetVcpusFlags = testDomainGetVcpusFlags, /* 0.8.5 */
|
||||||
|
Loading…
Reference in New Issue
Block a user