提交 fa1ce979 编写于 作者: D Daniel P. Berrange

qemu: add a max_core setting to qemu.conf for core dump size

Currently the QEMU processes inherit their core dump rlimit
from libvirtd, which is really suboptimal. This change allows
their limit to be directly controlled from qemu.conf instead.
上级 3de7da94
......@@ -1392,6 +1392,7 @@ virCommandSetErrorFD;
virCommandSetGID;
virCommandSetInputBuffer;
virCommandSetInputFD;
virCommandSetMaxCoreSize;
virCommandSetMaxFiles;
virCommandSetMaxMemLock;
virCommandSetMaxProcesses;
......@@ -2203,6 +2204,7 @@ virProcessRunInMountNamespace;
virProcessSchedPolicyTypeFromString;
virProcessSchedPolicyTypeToString;
virProcessSetAffinity;
virProcessSetMaxCoreSize;
virProcessSetMaxFiles;
virProcessSetMaxMemLock;
virProcessSetMaxProcesses;
......
......@@ -22,6 +22,9 @@ module Libvirtd_qemu =
let int_entry (kw:string) = [ key kw . value_sep . int_val ]
let str_array_entry (kw:string) = [ key kw . value_sep . str_array_val ]
let unlimited_val = del /\"/ "\"" . store /unlimited/ . del /\"/ "\""
let limits_entry (kw:string) = [ key kw . value_sep . unlimited_val ] | [ key kw . value_sep . int_val ]
(* Config entry grouped by function - same order as example config *)
let vnc_entry = str_entry "vnc_listen"
......@@ -72,6 +75,7 @@ module Libvirtd_qemu =
| bool_entry "set_process_name"
| int_entry "max_processes"
| int_entry "max_files"
| limits_entry "max_core"
| str_entry "stdio_handler"
let device_entry = bool_entry "mac_filter"
......
......@@ -401,7 +401,29 @@
#max_processes = 0
#max_files = 0
# If max_core is set to a non-zero integer, then QEMU will be
# permitted to create core dumps when it crashes, provided its
# RAM size is smaller than the limit set.
#
# Be warned that the core dump will include a full copy of the
# guest RAM, unless it has been disabled via the guest XML by
# setting:
#
# <memory dumpcore="off">...guest ram...</memory>
#
# If guest RAM is to be included, ensure the max_core limit
# is set to at least the size of the largest expected guest
# plus another 1GB for any QEMU host side memory mappings.
#
# As a special case it can be set to the string "unlimited" to
# to allow arbitrarily sized core dumps.
#
# By default the core dump size is set to 0 disabling all dumps
#
# Size is a positive integer specifying bytes or the
# string "unlimited"
#
#max_core = "unlimited"
# mac_filter enables MAC addressed based filtering on bridge ports.
# This currently requires ebtables to be installed.
......
......@@ -398,6 +398,7 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
char **controllers = NULL;
char **hugetlbfs = NULL;
char **nvram = NULL;
char *corestr = NULL;
/* Just check the file is readable before opening it, otherwise
* libvirt emits an error.
......@@ -638,6 +639,21 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
if (virConfGetValueUInt(conf, "max_files", &cfg->maxFiles) < 0)
goto cleanup;
if (virConfGetValueType(conf, "max_core") == VIR_CONF_STRING) {
if (virConfGetValueString(conf, "max_core", &corestr) < 0)
goto cleanup;
if (STREQ(corestr, "unlimited")) {
cfg->maxCore = ULLONG_MAX;
} else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Unknown core size '%s'"),
corestr);
goto cleanup;
}
} else if (virConfGetValueULLong(conf, "max_core", &cfg->maxCore) < 0) {
goto cleanup;
}
if (virConfGetValueString(conf, "lock_manager", &cfg->lockManagerName) < 0)
goto cleanup;
if (virConfGetValueString(conf, "stdio_handler", &stdioHandler) < 0)
......@@ -720,6 +736,7 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
virStringFreeList(controllers);
virStringFreeList(hugetlbfs);
virStringFreeList(nvram);
VIR_FREE(corestr);
VIR_FREE(user);
VIR_FREE(group);
virConfFree(conf);
......
......@@ -148,6 +148,7 @@ struct _virQEMUDriverConfig {
unsigned int maxProcesses;
unsigned int maxFiles;
unsigned long long maxCore;
unsigned int maxQueuedJobs;
......
......@@ -5269,6 +5269,7 @@ qemuProcessLaunch(virConnectPtr conn,
virCommandSetPreExecHook(cmd, qemuProcessHook, &hookData);
virCommandSetMaxProcesses(cmd, cfg->maxProcesses);
virCommandSetMaxFiles(cmd, cfg->maxFiles);
virCommandSetMaxCoreSize(cmd, cfg->maxCore);
virCommandSetUmask(cmd, 0x002);
VIR_DEBUG("Setting up security labelling");
......
......@@ -62,6 +62,7 @@ module Test_libvirtd_qemu =
{ "set_process_name" = "1" }
{ "max_processes" = "0" }
{ "max_files" = "0" }
{ "max_core" = "unlimited" }
{ "mac_filter" = "1" }
{ "relaxed_acs_check" = "1" }
{ "allow_disk_format_probing" = "1" }
......
......@@ -124,6 +124,8 @@ struct _virCommand {
unsigned long long maxMemLock;
unsigned int maxProcesses;
unsigned int maxFiles;
bool setMaxCore;
unsigned long long maxCore;
uid_t uid;
gid_t gid;
......@@ -687,6 +689,9 @@ virExec(virCommandPtr cmd)
goto fork_error;
if (virProcessSetMaxFiles(0, cmd->maxFiles) < 0)
goto fork_error;
if (cmd->setMaxCore &&
virProcessSetMaxCoreSize(0, cmd->maxCore) < 0)
goto fork_error;
if (cmd->hook) {
VIR_DEBUG("Run hook %p %p", cmd->hook, cmd->opaque);
......@@ -1105,6 +1110,15 @@ virCommandSetMaxFiles(virCommandPtr cmd, unsigned int files)
cmd->maxFiles = files;
}
void virCommandSetMaxCoreSize(virCommandPtr cmd, unsigned long long bytes)
{
if (!cmd || cmd->has_error)
return;
cmd->maxCore = bytes;
cmd->setMaxCore = true;
}
void virCommandSetUmask(virCommandPtr cmd, int mask)
{
if (!cmd || cmd->has_error)
......
......@@ -75,6 +75,7 @@ void virCommandSetUID(virCommandPtr cmd, uid_t uid);
void virCommandSetMaxMemLock(virCommandPtr cmd, unsigned long long bytes);
void virCommandSetMaxProcesses(virCommandPtr cmd, unsigned int procs);
void virCommandSetMaxFiles(virCommandPtr cmd, unsigned int files);
void virCommandSetMaxCoreSize(virCommandPtr cmd, unsigned long long bytes);
void virCommandSetUmask(virCommandPtr cmd, int umask);
void virCommandClearCaps(virCommandPtr cmd);
......
......@@ -914,6 +914,45 @@ virProcessSetMaxFiles(pid_t pid ATTRIBUTE_UNUSED, unsigned int files)
}
#endif /* ! (HAVE_SETRLIMIT && defined(RLIMIT_NOFILE)) */
#if HAVE_SETRLIMIT && defined(RLIMIT_CORE)
int
virProcessSetMaxCoreSize(pid_t pid, unsigned long long bytes)
{
struct rlimit rlim;
rlim.rlim_cur = rlim.rlim_max = bytes;
if (pid == 0) {
if (setrlimit(RLIMIT_CORE, &rlim) < 0) {
virReportSystemError(errno,
_("cannot limit core file size to %llu"),
bytes);
return -1;
}
} else {
if (virProcessPrLimit(pid, RLIMIT_CORE, &rlim, NULL) < 0) {
virReportSystemError(errno,
_("cannot limit core file size "
"of process %lld to %llu"),
(long long int)pid, bytes);
return -1;
}
}
return 0;
}
#else /* ! (HAVE_SETRLIMIT && defined(RLIMIT_CORE)) */
int
virProcessSetMaxCoreSize(pid_t pid ATTRIBUTE_UNUSED,
unsigned long long bytes)
{
if (bytes == 0)
return 0;
virReportSystemError(ENOSYS, "%s", _("Not supported on this platform"));
return -1;
}
#endif /* ! (HAVE_SETRLIMIT && defined(RLIMIT_CORE)) */
#ifdef __linux__
/*
* Port of code from polkitunixprocess.c under terms
......
......@@ -75,6 +75,7 @@ int virProcessSetNamespaces(size_t nfdlist,
int virProcessSetMaxMemLock(pid_t pid, unsigned long long bytes);
int virProcessSetMaxProcesses(pid_t pid, unsigned int procs);
int virProcessSetMaxFiles(pid_t pid, unsigned int files);
int virProcessSetMaxCoreSize(pid_t pid, unsigned long long bytes);
int virProcessGetMaxMemLock(pid_t pid, unsigned long long *bytes);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册