confile: rename lxc.limit to lxc.prlimit

Signed-off-by: 0x0916 <w@laoqinren.net>
This commit is contained in:
0x0916 2017-06-28 16:14:14 +08:00
parent 86ccab2e9b
commit 240d4b74ce
9 changed files with 214 additions and 38 deletions

View File

@ -1684,7 +1684,7 @@ by KATOH Yasufumi <karma at jazz.email.ne.jp>
<variablelist>
<varlistentry>
<term>
<option>lxc.limit.[limit name]</option>
<option>lxc.prlimit.[limit name]</option>
</term>
<listitem>
<para>

View File

@ -1201,7 +1201,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<variablelist>
<varlistentry>
<term>
<option>lxc.limit.[limit name]</option>
<option>lxc.prlimit.[limit name]</option>
</term>
<listitem>
<para>

View File

@ -4350,10 +4350,13 @@ int lxc_clear_limits(struct lxc_conf *c, const char *key)
bool all = false;
const char *k = NULL;
if (strcmp(key, "lxc.limit") == 0)
if (strcmp(key, "lxc.limit") == 0
|| strcmp(key, "lxc.prlimit"))
all = true;
else if (strncmp(key, "lxc.limit.", sizeof("lxc.limit.")-1) == 0)
k = key + sizeof("lxc.limit.")-1;
else if (strncmp(key, "lxc.prlimit.", sizeof("lxc.prlimit.")-1) == 0)
k = key + sizeof("lxc.prlimit.")-1;
else
return -1;
@ -4515,7 +4518,7 @@ void lxc_conf_free(struct lxc_conf *conf)
lxc_clear_includes(conf);
lxc_clear_aliens(conf);
lxc_clear_environment(conf);
lxc_clear_limits(conf, "lxc.limit");
lxc_clear_limits(conf, "lxc.prlimit");
free(conf);
}

View File

@ -131,7 +131,7 @@ lxc_config_define(init_gid);
lxc_config_define(ephemeral);
lxc_config_define(syslog);
lxc_config_define(no_new_privs);
lxc_config_define(limit);
lxc_config_define(prlimit);
static struct lxc_config_t config[] = {
{ "lxc.arch", set_config_personality, get_config_personality, clr_config_personality, },
@ -232,7 +232,13 @@ static struct lxc_config_t config[] = {
{ "lxc.ephemeral", set_config_ephemeral, get_config_ephemeral, clr_config_ephemeral, },
{ "lxc.syslog", set_config_syslog, get_config_syslog, clr_config_syslog, },
{ "lxc.no_new_privs", set_config_no_new_privs, get_config_no_new_privs, clr_config_no_new_privs, },
/* REMOVE IN LXC 3.0
legacy keys
*/
{ "lxc.limit", set_config_limit, get_config_limit, clr_config_limit, },
{ "lxc.prlimit", set_config_prlimit, get_config_prlimit, clr_config_prlimit, },
};
struct signame {
@ -1554,26 +1560,7 @@ out:
return -1;
}
static bool parse_limit_value(const char **value, unsigned long *res)
{
char *endptr = NULL;
if (strncmp(*value, "unlimited", sizeof("unlimited") - 1) == 0) {
*res = RLIM_INFINITY;
*value += sizeof("unlimited") - 1;
return true;
}
errno = 0;
*res = strtoul(*value, &endptr, 10);
if (errno || !endptr)
return false;
*value = endptr;
return true;
}
static int set_config_limit(const char *key, const char *value,
static int set_config_prlimit(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
struct lxc_list *iter;
@ -1585,10 +1572,10 @@ static int set_config_limit(const char *key, const char *value,
if (lxc_config_value_empty(value))
return lxc_clear_limits(lxc_conf, key);
if (strncmp(key, "lxc.limit.", sizeof("lxc.limit.") - 1) != 0)
if (strncmp(key, "lxc.prlimit.", sizeof("lxc.prlimit.") - 1) != 0)
return -1;
key += sizeof("lxc.limit.") - 1;
key += sizeof("lxc.prlimit.") - 1;
/* soft limit comes first in the value */
if (!parse_limit_value(&value, &limit_value))
@ -3275,11 +3262,11 @@ static int get_config_no_new_privs(const char *key, char *retv, int inlen,
}
/*
* If you ask for a specific value, i.e. lxc.limit.nofile, then just the value
* will be printed. If you ask for 'lxc.limit', then all limit entries will be
* printed, in 'lxc.limit.resource = value' format.
* If you ask for a specific value, i.e. lxc.prlimit.nofile, then just the value
* will be printed. If you ask for 'lxc.prlimit', then all limit entries will be
* printed, in 'lxc.prlimit.resource = value' format.
*/
static int get_config_limit(const char *key, char *retv, int inlen,
static int get_config_prlimit(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
int fulllen = 0, len;
@ -3291,10 +3278,10 @@ static int get_config_limit(const char *key, char *retv, int inlen,
else
memset(retv, 0, inlen);
if (!strcmp(key, "lxc.limit"))
if (!strcmp(key, "lxc.prlimit"))
get_all = true;
else if (strncmp(key, "lxc.limit.", 10) == 0)
key += 10;
else if (strncmp(key, "lxc.prlimit.", 12) == 0)
key += 12;
else
return -1;
@ -3323,7 +3310,7 @@ static int get_config_limit(const char *key, char *retv, int inlen,
}
if (get_all) {
strprint(retv, inlen, "lxc.limit.%s = %s\n",
strprint(retv, inlen, "lxc.prlimit.%s = %s\n",
lim->resource, buf);
} else if (strcmp(lim->resource, key) == 0) {
strprint(retv, inlen, "%s", buf);
@ -3628,7 +3615,7 @@ static inline int clr_config_no_new_privs(const char *key, struct lxc_conf *c,
return 0;
}
static inline int clr_config_limit(const char *key, struct lxc_conf *c,
static inline int clr_config_prlimit(const char *key, struct lxc_conf *c,
void *data)
{
return lxc_clear_limits(c, key);

View File

@ -1079,3 +1079,159 @@ inline int clr_config_lsm_se_context(const char *key, struct lxc_conf *c,
c->lsm_se_context = NULL;
return 0;
}
extern int set_config_limit(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
struct lxc_list *iter;
struct rlimit limit;
unsigned long limit_value;
struct lxc_list *limlist = NULL;
struct lxc_limit *limelem = NULL;
if (lxc_config_value_empty(value))
return lxc_clear_limits(lxc_conf, key);
if (strncmp(key, "lxc.limit.", sizeof("lxc.limit.") - 1) != 0)
return -1;
key += sizeof("lxc.limit.") - 1;
/* soft limit comes first in the value */
if (!parse_limit_value(&value, &limit_value))
return -1;
limit.rlim_cur = limit_value;
/* skip spaces and a colon */
while (isspace(*value))
++value;
if (*value == ':')
++value;
else if (*value) /* any other character is an error here */
return -1;
while (isspace(*value))
++value;
/* optional hard limit */
if (*value) {
if (!parse_limit_value(&value, &limit_value))
return -1;
limit.rlim_max = limit_value;
/* check for trailing garbage */
while (isspace(*value))
++value;
if (*value)
return -1;
} else {
/* a single value sets both hard and soft limit */
limit.rlim_max = limit.rlim_cur;
}
/* find existing list element */
lxc_list_for_each(iter, &lxc_conf->limits)
{
limelem = iter->elem;
if (!strcmp(key, limelem->resource)) {
limelem->limit = limit;
return 0;
}
}
/* allocate list element */
limlist = malloc(sizeof(*limlist));
if (!limlist)
goto out;
limelem = malloc(sizeof(*limelem));
if (!limelem)
goto out;
memset(limelem, 0, sizeof(*limelem));
limelem->resource = strdup(key);
if (!limelem->resource)
goto out;
limelem->limit = limit;
limlist->elem = limelem;
lxc_list_add_tail(&lxc_conf->limits, limlist);
return 0;
out:
free(limlist);
if (limelem) {
free(limelem->resource);
free(limelem);
}
return -1;
}
/*
* If you ask for a specific value, i.e. lxc.limit.nofile, then just the value
* will be printed. If you ask for 'lxc.limit', then all limit entries will be
* printed, in 'lxc.limit.resource = value' format.
*/
extern int get_config_limit(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
int fulllen = 0, len;
bool get_all = false;
struct lxc_list *it;
if (!retv)
inlen = 0;
else
memset(retv, 0, inlen);
if (!strcmp(key, "lxc.limit"))
get_all = true;
else if (strncmp(key, "lxc.limit.", 10) == 0)
key += 10;
else
return -1;
lxc_list_for_each(it, &c->limits) {
char buf[LXC_NUMSTRLEN64 * 2 + 2]; /* 2 colon separated 64 bit
integers or the word
'unlimited' */
int partlen;
struct lxc_limit *lim = it->elem;
if (lim->limit.rlim_cur == RLIM_INFINITY) {
memcpy(buf, "unlimited", sizeof("unlimited"));
partlen = sizeof("unlimited") - 1;
} else {
partlen = sprintf(buf, "%" PRIu64,
(uint64_t)lim->limit.rlim_cur);
}
if (lim->limit.rlim_cur != lim->limit.rlim_max) {
if (lim->limit.rlim_max == RLIM_INFINITY) {
memcpy(buf + partlen, ":unlimited",
sizeof(":unlimited"));
} else {
sprintf(buf + partlen, ":%" PRIu64,
(uint64_t)lim->limit.rlim_max);
}
}
if (get_all) {
strprint(retv, inlen, "lxc.limit.%s = %s\n",
lim->resource, buf);
} else if (strcmp(lim->resource, key) == 0) {
strprint(retv, inlen, "%s", buf);
}
}
return fulllen;
}
extern int clr_config_limit(const char *key, struct lxc_conf *c,
void *data)
{
return lxc_clear_limits(c, key);
}

View File

@ -86,5 +86,6 @@ lxc_config_legacy_define(network_legacy);
lxc_config_legacy_define(lsm_aa_profile);
lxc_config_legacy_define(lsm_aa_incomplete);
lxc_config_legacy_define(lsm_se_context);
lxc_config_legacy_define(limit);
#endif /* __LXC_CONFILE_LEGACY_H */

View File

@ -661,3 +661,23 @@ int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v)
return snprintf(retv, inlen, "%d", v);
}
bool parse_limit_value(const char **value, unsigned long *res)
{
char *endptr = NULL;
if (strncmp(*value, "unlimited", sizeof("unlimited") - 1) == 0) {
*res = RLIM_INFINITY;
*value += sizeof("unlimited") - 1;
return true;
}
errno = 0;
*res = strtoul(*value, &endptr, 10);
if (errno || !endptr)
return false;
*value = endptr;
return true;
}

View File

@ -84,5 +84,5 @@ extern void update_hwaddr(const char *line);
extern bool new_hwaddr(char *hwaddr);
extern int lxc_get_conf_str(char *retv, int inlen, const char *value);
extern int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v);
extern bool parse_limit_value(const char **value, unsigned long *res);
#endif /* __LXC_CONFILE_UTILS_H */

View File

@ -729,13 +729,22 @@ int main(int argc, char *argv[])
goto non_test_error;
}
/* lxc.limit.nofile */
/* REMOVE IN LXC 3.0
legacy lxc.limit.* key
*/
if (set_get_compare_clear_save_load(c, "lxc.limit.nofile", "65536",
tmpf, true) < 0) {
lxc_error("%s\n", "lxc.limit.nofile");
goto non_test_error;
}
/* lxc.prlimit.nofile */
if (set_get_compare_clear_save_load(c, "lxc.prlimit.nofile", "65536",
tmpf, true) < 0) {
lxc_error("%s\n", "lxc.prlimit.nofile");
goto non_test_error;
}
if (test_idmap_parser() < 0) {
lxc_error("%s\n", "failed to test parser for \"lxc.id_map\"");
goto non_test_error;