---
src/conf/domain_conf.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 12 +++++
src/lxc/lxc_controller.c | 12 +++++
src/util/virprocess.c | 4 +-
src/util/virprocess.h | 3 ++
5 files changed, 144 insertions(+), 2 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 2d81c37..a673dc2 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -26,6 +26,7 @@
#include <dirent.h>
#include <fcntl.h>
#include <strings.h>
+#include <sys/resource.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -1003,7 +1004,86 @@ virDomainBlkioDeviceParseXML(xmlNodePtr root,
return -1;
}
+static virDomainRLimitsPtr
+virDomainRLimitsNew(void)
+{
+ virDomainRLimitsPtr def = NULL;
+
+ if (VIR_ALLOC(def) < 0)
+ return NULL;
+
+ return def;
+}
+
+static virDomainRLimitsPtr
+virDomainRLimitParseXML(xmlNodePtr node)
+{
+ char *c = NULL;
+ long long val;
+ virDomainRLimitsPtr def;
+ if (!(def = virDomainRLimitsNew()))
+ return NULL;
+
+ if (node->type == XML_ELEMENT_NODE) {
+ c = (char *)xmlNodeGetContent(node);
+ if (virStrToLong_ll(c, NULL, 10, &val) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not parse rlimit value of %s"),
+ c);
+ goto error;
+ }
+ VIR_FREE(c);
+
+ def->limit = val;
+ if (VIR_STRDUP(def->name, (char *)node->name) < 0)
+ goto error;
+
+ if (xmlStrEqual(node->name, BAD_CAST "as")) {
+ def->resource = RLIMIT_AS;
+ } else if (xmlStrEqual(node->name, BAD_CAST "core")) {
+ def->resource = RLIMIT_CORE;
+ } else if (xmlStrEqual(node->name, BAD_CAST "cpu")) {
+ def->resource = RLIMIT_CPU;
+ } else if (xmlStrEqual(node->name, BAD_CAST "data")) {
+ def->resource = RLIMIT_DATA;
+ } else if (xmlStrEqual(node->name, BAD_CAST "fsize")) {
+ def->resource = RLIMIT_FSIZE;
+ } else if (xmlStrEqual(node->name, BAD_CAST "locks")) {
+ def->resource = RLIMIT_LOCKS;
+ } else if (xmlStrEqual(node->name, BAD_CAST "memlock")) {
+ def->resource = RLIMIT_MEMLOCK;
+ } else if (xmlStrEqual(node->name, BAD_CAST "msgqueue")) {
+ def->resource = RLIMIT_MSGQUEUE;
+ } else if (xmlStrEqual(node->name, BAD_CAST "nice")) {
+ def->resource = RLIMIT_NICE;
+ } else if (xmlStrEqual(node->name, BAD_CAST "nofile")) {
+ def->resource = RLIMIT_NOFILE;
+ } else if (xmlStrEqual(node->name, BAD_CAST "nproc")) {
+ def->resource = RLIMIT_NPROC;
+ } else if (xmlStrEqual(node->name, BAD_CAST "rss")) {
+ def->resource = RLIMIT_RSS;
+ } else if (xmlStrEqual(node->name, BAD_CAST "rtprio")) {
+ def->resource = RLIMIT_RTPRIO;
+ } else if (xmlStrEqual(node->name, BAD_CAST "sigpending")) {
+ def->resource = RLIMIT_SIGPENDING;
+ } else if (xmlStrEqual(node->name, BAD_CAST "stack")) {
+ def->resource = RLIMIT_STACK;
+ } else {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not determine resource type of
'%s'"),
+ node->name);
+ goto error;
+ }
+ }
+
+ return def;
+
+ error:
+ VIR_FREE(c);
+ VIR_FREE(def);
+ return NULL;
+}
static void
virDomainObjListDataFree(void *payload, const void *name ATTRIBUTE_UNUSED)
@@ -14180,6 +14260,28 @@ virDomainDefParseXML(xmlDocPtr xml,
virHashFree(bootHash);
+ if ((node = virXPathNode("./rlimits[1]", ctxt)) != NULL && (n =
virXMLChildElementCount(node)) > 0) {
+ xmlNodePtr cur = node->children;
+ if (n && VIR_ALLOC_N(def->rlimits, n) < 0)
+ goto error;
+
+ for (i = 0; i < n; i++) {
+ if (!(def->rlimits[i] = virDomainRLimitParseXML(cur)))
+ goto error;
+ def->nrlimits++;
+ for (j = 0; j < i; j++) {
+ if (def->rlimits[j]->resource == def->rlimits[i]->resource)
{
+ virReportError(VIR_ERR_XML_ERROR,
+ _("duplicate rlimit resources
'%s'"),
+ def->rlimits[j]->name);
+ goto error;
+ }
+ }
+ cur = cur->next;
+ }
+ }
+ VIR_FREE(node);
+
return def;
error:
@@ -19759,6 +19861,19 @@ virDomainDefFormatInternal(virDomainDefPtr def,
goto error;
}
+ if (def->nrlimits > 0) {
+ virBufferAddLit(buf, "<rlimits>\n");
+ virBufferAdjustIndent(buf, 2);
+ for (n = 0; n < def->nrlimits; n++) {
+ virBufferAsprintf(buf, "<%s>%lld</%s>\n",
+ def->rlimits[n]->name,
+ def->rlimits[n]->limit,
+ def->rlimits[n]->name);
+ }
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</rlimits>\n");
+ }
+
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</domain>\n");
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 439f3c0..abad30e 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2021,6 +2021,15 @@ struct _virDomainPowerManagement {
int s4;
};
+typedef struct _virDomainRLimits virDomainRLimits;
+typedef virDomainRLimits *virDomainRLimitsPtr;
+
+struct _virDomainRLimits {
+ char *name;
+ int resource;
+ long long limit;
+};
+
/*
* Guest VM main configuration
*
@@ -2138,6 +2147,9 @@ struct _virDomainDef {
size_t nshmems;
virDomainShmemDefPtr *shmems;
+ size_t nrlimits;
+ virDomainRLimitsPtr *rlimits;
+
/* Only 1 */
virDomainWatchdogDefPtr watchdog;
virDomainMemballoonDefPtr memballoon;
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 53a2c8d..ef5551e 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -2490,6 +2490,18 @@ int main(int argc, char *argv[])
}
}
+ VIR_INFO("nrlimits = %d", (int)ctrl->def->nrlimits);
+ if (ctrl->def->nrlimits > 0) {
+ struct rlimit rlim;
+ int n;
+ for (i = 0; i < ctrl->def->nrlimits; i++) {
+ rlim.rlim_max = rlim.rlim_cur = ctrl->def->rlimits[i]->limit;
+ n = virProcessPrLimit(0, ctrl->def->rlimits[i]->resource,
&rlim);
+ if (n < 0)
+ goto cleanup;
+ }
+ }
+
rc = virLXCControllerRun(ctrl);
cleanup:
diff --git a/src/util/virprocess.c b/src/util/virprocess.c
index 0c8a32f..9bb5370 100644
--- a/src/util/virprocess.c
+++ b/src/util/virprocess.c
@@ -675,13 +675,13 @@ int virProcessSetNamespaces(size_t nfdlist,
}
#if HAVE_PRLIMIT
-static int
+int
virProcessPrLimit(pid_t pid, int resource, struct rlimit *rlim)
{
return prlimit(pid, resource, rlim, NULL);
}
#elif HAVE_SETRLIMIT
-static int
+int
virProcessPrLimit(pid_t pid ATTRIBUTE_UNUSED,
int resource ATTRIBUTE_UNUSED,
struct rlimit *rlim ATTRIBUTE_UNUSED)
diff --git a/src/util/virprocess.h b/src/util/virprocess.h
index bcaede5..045f8d4 100644
--- a/src/util/virprocess.h
+++ b/src/util/virprocess.h
@@ -22,6 +22,7 @@
#ifndef __VIR_PROCESS_H__
# define __VIR_PROCESS_H__
+# include <sys/resource.h>
# include <sys/types.h>
# include "internal.h"
@@ -73,4 +74,6 @@ typedef int (*virProcessNamespaceCallback)(pid_t pid, void *opaque);
int virProcessRunInMountNamespace(pid_t pid,
virProcessNamespaceCallback cb,
void *opaque);
+
+int virProcessPrLimit(pid_t pid, int resource, struct rlimit *rlim);
#endif /* __VIR_PROCESS_H__ */
--
1.9.3 (Apple Git-50)