}
/* Setup resource limits */
- if (!lxc_list_empty(&conf->limits)) {
- ret = setup_resource_limits(&conf->limits, pid);
- if (ret < 0)
- goto on_error;
-
- TRACE("Setup resource limits");
- }
+ ret = setup_resource_limits(conf, pid);
+ if (ret < 0)
+ goto on_error;
if (options->attach_flags & LXC_ATTACH_TERMINAL) {
ret = lxc_attach_terminal_mainloop_init(&terminal, &descr);
return resid;
}
-int setup_resource_limits(struct lxc_list *limits, pid_t pid)
+int setup_resource_limits(struct lxc_conf *conf, pid_t pid)
{
int resid;
- struct lxc_list *it;
struct lxc_limit *lim;
- lxc_list_for_each (it, limits) {
- lim = it->elem;
+ if (list_empty(&conf->limits))
+ return 0;
+ list_for_each_entry(lim, &conf->limits, head) {
resid = parse_resource(lim->resource);
if (resid < 0)
return log_error(-1, "Unknown resource %s", lim->resource);
#endif
}
+ TRACE("Setup resource limits");
return 0;
}
lxc_list_init(&new->includes);
lxc_list_init(&new->aliens);
lxc_list_init(&new->environment);
- lxc_list_init(&new->limits);
+ INIT_LIST_HEAD(&new->limits);
lxc_list_init(&new->sysctls);
lxc_list_init(&new->procs);
new->hooks_version = 0;
int lxc_clear_limits(struct lxc_conf *c, const char *key)
{
- struct lxc_list *it, *next;
const char *k = NULL;
bool all = false;
+ struct lxc_limit *lim, *nlim;
if (strequal(key, "lxc.limit") || strequal(key, "lxc.prlimit"))
all = true;
else
return ret_errno(EINVAL);
- lxc_list_for_each_safe (it, &c->limits, next) {
- struct lxc_limit *lim = it->elem;
-
+ list_for_each_entry_safe(lim, nlim, &c->limits, head) {
if (!all && !strequal(lim->resource, k))
continue;
- lxc_list_del(it);
-
+ list_del(&lim->head);
free_disarm(lim->resource);
free(lim);
- free(it);
}
if (all)
- lxc_list_init(&c->limits);
+ INIT_LIST_HEAD(&c->limits);
return 0;
}
struct rlimit {
unsigned long rlim_cur;
unsigned long rlim_max;
+ struct list_head head;
};
#endif
struct lxc_limit {
char *resource;
struct rlimit limit;
+ struct list_head head;
};
static void free_lxc_limit(struct lxc_limit *ptr)
bool no_new_privs;
/* RLIMIT_* limits */
- struct lxc_list limits;
+ struct list_head limits;
/* Contains generic info about the cgroup configuration for this
* container. Note that struct lxc_cgroup contains a union. It is only
const char *lxcpath);
__hidden extern int lxc_setup(struct lxc_handler *handler);
__hidden extern int lxc_setup_parent(struct lxc_handler *handler);
-__hidden extern int setup_resource_limits(struct lxc_list *limits, pid_t pid);
+__hidden extern int setup_resource_limits(struct lxc_conf *conf, pid_t pid);
__hidden extern int find_unmapped_nsid(const struct lxc_conf *conf, enum idtype idtype);
__hidden extern int mapped_hostid(unsigned id, const struct lxc_conf *conf, enum idtype idtype);
__hidden extern int userns_exec_1(const struct lxc_conf *conf, int (*fn)(void *), void *data,
static int set_config_prlimit(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
- __do_free struct lxc_list *list = NULL;
- call_cleaner(free_lxc_limit) struct lxc_limit *elem = NULL;
- struct lxc_list *iter;
+ call_cleaner(free_lxc_limit) struct lxc_limit *new_lim = NULL;
struct rlimit limit;
rlim_t limit_value;
+ struct lxc_limit *lim;
if (lxc_config_value_empty(value))
return lxc_clear_limits(lxc_conf, key);
}
/* find existing list element */
- lxc_list_for_each(iter, &lxc_conf->limits) {
- struct lxc_limit *cur = iter->elem;
-
- if (!strequal(key, cur->resource))
+ list_for_each_entry(lim, &lxc_conf->limits, head) {
+ if (!strequal(key, lim->resource))
continue;
- cur->limit = limit;
+ lim->limit = limit;
return 0;
}
- /* allocate list element */
- list = lxc_list_new();
- if (!list)
- return ret_errno(ENOMEM);
-
- elem = zalloc(sizeof(*elem));
- if (!elem)
+ new_lim = zalloc(sizeof(*new_lim));
+ if (!new_lim)
return ret_errno(ENOMEM);
- elem->resource = strdup(key);
- if (!elem->resource)
+ new_lim->resource = strdup(key);
+ if (!new_lim->resource)
return ret_errno(ENOMEM);
- elem->limit = limit;
- lxc_list_add_elem(list, move_ptr(elem));;
- lxc_list_add_tail(&lxc_conf->limits, move_ptr(list));
+ new_lim->limit = limit;
+ list_add_tail(&new_lim->head, &lxc_conf->limits);
+ move_ptr(new_lim);
return 0;
}
{
int fulllen = 0, len;
bool get_all = false;
- struct lxc_list *it;
+ struct lxc_limit *lim;
if (!retv)
inlen = 0;
else
return ret_errno(EINVAL);
- lxc_list_for_each(it, &c->limits) {
+ list_for_each_entry(lim, &c->limits, head) {
/* 2 colon separated 64 bit integers or the word 'unlimited' */
char buf[INTTYPE_TO_STRLEN(uint64_t) * 2 + 2];
int partlen;
- struct lxc_limit *lim = it->elem;
if (lim->limit.rlim_cur == RLIM_INFINITY) {
memcpy(buf, "unlimited", STRLITERALLEN("unlimited") + 1);
goto out_delete_net;
}
- if (!lxc_list_empty(&conf->limits)) {
- ret = setup_resource_limits(&conf->limits, handler->pid);
- if (ret < 0) {
- ERROR("Failed to setup resource limits");
- goto out_delete_net;
- }
+ ret = setup_resource_limits(conf, handler->pid);
+ if (ret < 0) {
+ ERROR("Failed to setup resource limits");
+ goto out_delete_net;
}
/* Tell the child to continue its initialization. */