[lxc-devel] [PATCH v2 1/1] support shmmax/shmall KEY for lxc-execute
jian at linux.vnet.ibm.com
jian at linux.vnet.ibm.com
Sat Jul 7 20:50:24 UTC 2012
From: Jian Xiao <jian at linux.vnet.ibm.com>
Signed-off-by: Jian Xiao <jian at linux.vnet.ibm.com>
---
src/lxc/conf.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/lxc/conf.h | 2 +
src/lxc/confile.c | 32 ++++++++++++++++++++++
3 files changed, 111 insertions(+), 0 deletions(-)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index e8088bb..3988b2a 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -1285,6 +1285,78 @@ static int setup_caps(struct lxc_list *caps)
return 0;
}
+static int shm_write(const char *pathname, unsigned long val)
+{
+ int rc, fd;
+ char val_str[64];
+
+ fd = open(pathname, O_WRONLY);
+ if (fd < 0) {
+ SYSERROR("fail to open %s", pathname);
+ return -1;
+ }
+
+ snprintf(val_str, sizeof(val_str), "%lu", val);
+
+ rc = write(fd, val_str, strlen(val_str));
+ if (rc < 0) {
+ SYSERROR("fail to write %s to %s", val_str, pathname);
+ close(fd);
+ return -1;
+ }
+
+ close(fd);
+
+ DEBUG("%s has been set to %lu\n", pathname, val);
+
+ return 0;
+
+}
+
+static int setup_shm(struct lxc_conf *lxc_conf)
+{
+ int rc = 0;
+ uid_t euid = geteuid();
+
+ if ((!lxc_conf->shmmax) && (!lxc_conf->shmall))
+ return 0;
+
+ /* Process has all the capabilities set, but cannot open shm*
+ * to write. Temporarily set euid to root to get around this.
+ * This is only done for non-root uid.
+ */
+ if (euid && seteuid(0)) {
+ SYSERROR("failed to change euid to 0\n");
+ return -1;
+ }
+
+ if (lxc_conf->shmmax &&
+ shm_write("/proc/sys/kernel/shmmax", lxc_conf->shmmax))
+ rc = -1;
+
+ if (lxc_conf->shmall &&
+ shm_write("/proc/sys/kernel/shmall", lxc_conf->shmall))
+ rc = -1;
+
+ /* set euid back */
+ if (euid) {
+ if (seteuid(euid)) {
+ ERROR("failed to change euid to '%d': %m", euid);
+ return -1;
+ }
+
+ /* seteuid() to non-zero clears effective capabilities
+ * so we need to restore them
+ */
+ if (lxc_caps_up()) {
+ ERROR("failed to restore capabilities: %m");
+ return -1;
+ }
+ }
+
+ return rc;
+}
+
static int setup_hw_addr(char *hwaddr, const char *ifname)
{
struct sockaddr sockaddr;
@@ -2027,6 +2099,11 @@ int lxc_setup(const char *name, struct lxc_conf *lxc_conf)
return -1;
}
+ if (setup_shm(lxc_conf)) {
+ ERROR("failed to set shm");
+ return -1;
+ }
+
if (setup_pivot_root(&lxc_conf->rootfs)) {
ERROR("failed to set rootfs for '%s'", name);
return -1;
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 09f55cb..b443326 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -216,6 +216,8 @@ struct lxc_conf {
struct lxc_rootfs rootfs;
char *ttydir;
int close_all_fds;
+ unsigned long shmmax;
+ unsigned long shmall;
};
/*
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index b305aef..f71f4c7 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -71,6 +71,8 @@ static int config_network_ipv6(const char *, char *, struct lxc_conf *);
static int config_network_ipv6_gateway(const char *, char *, struct lxc_conf *);
static int config_cap_drop(const char *, char *, struct lxc_conf *);
static int config_console(const char *, char *, struct lxc_conf *);
+static int config_shmmax(const char *, char *, struct lxc_conf *);
+static int config_shmall(const char *, char *, struct lxc_conf *);
typedef int (*config_cb)(const char *, char *, struct lxc_conf *);
@@ -107,6 +109,8 @@ static struct config config[] = {
{ "lxc.network.ipv6", config_network_ipv6 },
{ "lxc.cap.drop", config_cap_drop },
{ "lxc.console", config_console },
+ { "lxc.shmmax", config_shmmax },
+ { "lxc.shmall", config_shmall },
};
static const size_t config_size = sizeof(config)/sizeof(struct config);
@@ -876,6 +880,34 @@ static int config_utsname(const char *key, char *value, struct lxc_conf *lxc_con
return 0;
}
+static int config_shmmax(const char *key, char *value, struct lxc_conf *lxc_conf)
+{
+ if (!strlen(value))
+ return -1;
+
+ errno = 0;
+ lxc_conf->shmmax = strtoul(value, NULL, 0);
+ if (errno) {
+ SYSERROR("failed to strtoul '%s'", value);
+ return -1;
+ }
+ return 0;
+}
+
+static int config_shmall(const char *key, char *value, struct lxc_conf *lxc_conf)
+{
+ if (!strlen(value))
+ return -1;
+
+ errno = 0;
+ lxc_conf->shmall = strtoul(value, NULL, 0);
+ if (errno) {
+ SYSERROR("failed to strtoul '%s'", value);
+ return -1;
+ }
+ return 0;
+}
+
static int parse_line(char *buffer, void *data)
{
struct config *config;
--
1.7.1
More information about the lxc-devel
mailing list