lxc_config_define(sysctl);
lxc_config_define(proc);
-static struct lxc_config_t config[] = {
+static struct lxc_config_t config_jump_table[] = {
{ "lxc.arch", set_config_personality, get_config_personality, clr_config_personality, },
{ "lxc.apparmor.profile", set_config_apparmor_profile, get_config_apparmor_profile, clr_config_apparmor_profile, },
{ "lxc.apparmor.allow_incomplete", set_config_apparmor_allow_incomplete, get_config_apparmor_allow_incomplete, clr_config_apparmor_allow_incomplete, },
{ "lxc.proc", set_config_proc, get_config_proc, clr_config_proc, },
};
-static const size_t config_size = sizeof(config) / sizeof(struct lxc_config_t);
+static const size_t config_jump_table_size = sizeof(config_jump_table) / sizeof(struct lxc_config_t);
struct lxc_config_t *lxc_get_config(const char *key)
{
size_t i;
- for (i = 0; i < config_size; i++)
- if (!strncmp(config[i].name, key, strlen(config[i].name)))
- return &config[i];
+ for (i = 0; i < config_jump_table_size; i++)
+ if (!strncmp(config_jump_table[i].name, key, strlen(config_jump_table[i].name)))
+ return &config_jump_table[i];
return NULL;
}
} else if (!strcmp(value, "none")) {
netdev->type = LXC_NET_NONE;
} else {
- ERROR("invalid network type %s", value);
+ ERROR("Invalid network type %s", value);
return -1;
}
const char *tmpvalue = "phys";
if (netns_getifaddrs(&ifaddr, -1, &(bool){false}) < 0) {
- SYSERROR("Get network interfaces failed");
+ SYSERROR("Failed to get network interfaces");
return -1;
}
for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
if (!ifa->ifa_addr)
continue;
+
if (ifa->ifa_addr->sa_family != AF_PACKET)
continue;
ret = set_config_net_link(
link_key, ifa->ifa_name, lxc_conf, netdev);
if (ret) {
- ERROR("failed to create matched ifnames");
+ ERROR("Failed to create matched ifnames");
break;
}
} else {
- ERROR("failed to create matched ifnames");
+ ERROR("Failed to create matched ifnames");
break;
}
}
}
netdev->hwaddr = new_value;
+
return 0;
}
inetdev = malloc(sizeof(*inetdev));
if (!inetdev)
return -1;
-
memset(inetdev, 0, sizeof(*inetdev));
list = malloc(sizeof(*list));
}
lxc_list_add_tail(&netdev->ipv4, list);
-
free(addr);
+
return 0;
}
inet6dev = malloc(sizeof(*inet6dev));
if (!inet6dev)
return -1;
-
memset(inet6dev, 0, sizeof(*inet6dev));
list = malloc(sizeof(*list));
if (slash) {
*slash = '\0';
netmask = slash + 1;
+
ret = lxc_safe_uint(netmask, &inet6dev->prefix);
if (ret < 0) {
free(list);
}
lxc_list_add_tail(&netdev->ipv6, list);
-
free(valdup);
+
return 0;
}
hooklist->elem = hook;
lxc_list_add_tail(&lxc_conf->hooks[which], hooklist);
+
return 0;
}
return add_hook(lxc_conf, LXCHOOK_DESTROY, copy);
free(copy);
+
return -1;
}
}
lxc_conf->hooks_version = tmp;
+
return 0;
}
return -1;
lxc_conf->pty_max = max;
+
return 0;
}
}
free(groups);
+
return ret;
}
on_error:
free(list_item);
+
return -1;
}
return -1;
lxc_conf->ttys.max = nbtty;
+
return 0;
}
* current logging.
*/
lxc_conf->loglevel = newlevel;
+
return lxc_log_set_level(&lxc_conf->loglevel, newlevel);
}
/* 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 */
if (*value) {
if (!parse_limit_value(&value, &limit_value))
return -1;
+
limit.rlim_max = limit_value;
/* check for trailing garbage */
limelem->resource = strdup(key);
if (!limelem->resource)
goto on_error;
- limelem->limit = limit;
+ limelem->limit = limit;
lxc_list_add_elem(limlist, limelem);;
-
lxc_list_add_tail(&lxc_conf->limits, limlist);
return 0;
on_error:
free(limlist);
+
if (limelem) {
free(limelem->resource);
free(limelem);
}
+
return -1;
}
free(sysctl_elem->value);
sysctl_elem->value = replace_value;
+
return 0;
}
goto on_error;
lxc_list_add_elem(sysctl_list, sysctl_elem);
-
lxc_list_add_tail(&lxc_conf->sysctls, sysctl_list);
return 0;
on_error:
free(sysctl_list);
+
if (sysctl_elem) {
free(sysctl_elem->key);
free(sysctl_elem->value);
free(sysctl_elem);
}
+
return -1;
}
on_error:
free(proclist);
+
if (procelem) {
free(procelem->filename);
free(procelem->value);
if (idmap->nsid == 0)
lxc_conf->root_nsuid_map = idmap;
-
if (!lxc_conf->root_nsgid_map && idmap->idtype == ID_TYPE_GID)
if (idmap->nsid == 0)
lxc_conf->root_nsgid_map = idmap;
lxc_conf->auto_mounts &= ~allowed_auto_mounts[i].mask;
lxc_conf->auto_mounts |= allowed_auto_mounts[i].flag;
+
if (is_shmounts) {
lxc_conf->shmount.path_host = strdup(token + STRLITERALLEN("shmounts:"));
if (!lxc_conf->shmount.path_host) {
"next power of two: %" PRIu64 " bytes", buffer_size);
lxc_conf->console.buffer_size = buffer_size;
+
return 0;
}
"next power of two: %" PRIu64 " bytes", log_size);
lxc_conf->console.log_size = log_size;
+
return 0;
}
int append_unexp_config_line(const char *line, struct lxc_conf *conf)
{
- size_t len = conf->unexpanded_len, linelen = strlen(line);
+ size_t linelen;
+ size_t len = conf->unexpanded_len;
update_hwaddr(line);
+ linelen = strlen(line);
while (conf->unexpanded_alloced <= len + linelen + 2) {
char *tmp = realloc(conf->unexpanded_config,
conf->unexpanded_alloced + 1024);
if (!conf->unexpanded_config)
*tmp = '\0';
+
conf->unexpanded_config = tmp;
conf->unexpanded_alloced += 1024;
}
- (void)strlcat(conf->unexpanded_config, line, conf->unexpanded_alloced);
+ memcpy(conf->unexpanded_config + conf->unexpanded_len, line, linelen);
conf->unexpanded_len += linelen;
- if (line[linelen - 1] != '\n') {
- (void)strlcat(conf->unexpanded_config, "\n", conf->unexpanded_alloced);
- conf->unexpanded_len++;
- }
+ if (line[linelen - 1] != '\n')
+ conf->unexpanded_config[conf->unexpanded_len++] = '\n';
+ conf->unexpanded_config[conf->unexpanded_len] = '\0';
return 0;
}
{
struct dirent *direntp;
DIR *dir;
- char path[MAXPATHLEN];
+ char path[PATH_MAX];
int len;
int ret = -1;
if (len < 6 || strncmp(fnam + len - 5, ".conf", 5) != 0)
continue;
- len = snprintf(path, MAXPATHLEN, "%s/%s", dirp, fnam);
- if (len < 0 || len >= MAXPATHLEN) {
+ len = snprintf(path, PATH_MAX, "%s/%s", dirp, fnam);
+ if (len < 0 || len >= PATH_MAX) {
ret = -1;
goto out;
}
tmp = strchr(dup, ':');
if (tmp) {
*tmp = '\0';
+
ret = set_config_path_item(&lxc_conf->rootfs.bdev_type, dup);
if (ret < 0) {
free(dup);
return -1;
}
+
tmp++;
container_path = tmp;
} else {
ret = set_config_path_item(&lxc_conf->rootfs.path, container_path);
free(dup);
+
return ret;
}
on_error:
free(linep);
+
return ret;
}
int lxc_config_read(const char *file, struct lxc_conf *conf, bool from_include)
{
- int ret;
struct parse_line_conf c;
c.conf = conf;
c.from_include = from_include;
- ret = access(file, R_OK);
- if (ret < 0)
- return -1;
-
/* Catch only the top level config file name in the structure. */
if (!conf->rcfile)
conf->rcfile = strdup(file);
}
lxc_list_add_tail(defines, dent);
+
return 0;
}
}
lxc_config_define_free(defines);
+
return bret;
}
while (*lstart) {
lend = strchr(lstart, '\n');
char v;
+
if (!lend)
lend = lstart + strlen(lstart);
else
lend++;
+
if (strncmp(lstart, key, strlen(key)) != 0) {
lstart = lend;
continue;
}
+
if (!rm_subkeys) {
v = lstart[strlen(key)];
if (!isspace(v) && v != '=') {
continue;
}
}
+
conf->unexpanded_len -= (lend - lstart);
+
if (*lend == '\0') {
*lstart = '\0';
return;
}
+
memmove(lstart, lend, strlen(lend) + 1);
}
}
if (olddirlen >= newdirlen) {
size_t diff = olddirlen - newdirlen;
memcpy(q, newdir, newdirlen);
+
if (olddirlen != newdirlen) {
memmove(q + newdirlen, q + newdirlen + diff,
- strlen(q) - newdirlen - diff + 1);
+ strlen(q) - newdirlen - diff + 1);
lend -= diff;
conf->unexpanded_len -= diff;
}
conf->unexpanded_alloced = newlen + 1;
new[newlen - 1] = '\0';
lend = new + (lend - conf->unexpanded_config);
+
/* Move over the remainder to make room for the newdir.
*/
memmove(new + poffset + newdirlen,
- new + poffset + olddirlen,
- oldlen - poffset - olddirlen + 1);
+ new + poffset + olddirlen,
+ oldlen - poffset - olddirlen + 1);
conf->unexpanded_config = new;
+
memcpy(new + poffset, newdir, newdirlen);
lend += diff;
}
+
next:
lstart = lend;
}
if (olddirlen >= newdirlen) {
size_t diff = olddirlen - newdirlen;
memcpy(p, newdir, newdirlen);
+
if (olddirlen != newdirlen) {
memmove(p + newdirlen, p + newdirlen + diff,
- strlen(p) - newdirlen - diff + 1);
+ strlen(p) - newdirlen - diff + 1);
lend -= diff;
conf->unexpanded_len -= diff;
}
conf->unexpanded_alloced = newlen + 1;
new[newlen - 1] = '\0';
lend = new + (lend - conf->unexpanded_config);
+
/* Move over the remainder to make room for the newdir.
*/
memmove(new + poffset + newdirlen,
- new + poffset + olddirlen,
- oldlen - poffset - olddirlen + 1);
+ new + poffset + olddirlen,
+ oldlen - poffset - olddirlen + 1);
conf->unexpanded_config = new;
+
memcpy(new + poffset, newdir, newdirlen);
lend += diff;
}
+
next:
lstart = lend;
}
return -1;
lxc_log_syslog(facility);
+
return set_config_string_item(&lxc_conf->syslog, value);
}
/* If you ask for a specific cgroup value, i.e. lxc.cgroup.devices.list, then
* just the value(s) will be printed. Since there still could be more than one,
* it is newline-separated.
- * (Maybe that's ambigous, since some values, i.e. devices.list, will already
+ * (Maybe that's ambiguous, since some values, i.e. devices.list, will already
* have newlines?)
* If you ask for 'lxc.cgroup", then all cgroup entries will be printed, in
* 'lxc.cgroup.subsystem.key = value' format.
if (version != cg->version)
continue;
- strprint(retv, inlen, "%s.%s = %s\n",
- global_token, cg->subsystem, cg->value);
- } else if (!strcmp(cg->subsystem, key)) {
+ strprint(retv, inlen, "%s.%s = %s\n", global_token,
+ cg->subsystem, cg->value);
+ } else if (strcmp(cg->subsystem, key) == 0) {
strprint(retv, inlen, "%s\n", cg->value);
}
}
strprint(retv, inlen, "%s%s", buf, (listlen-- > 1) ? "\n" : "");
}
+
return fulllen;
}
int i;
subkey = strchr(key, '.');
- if (subkey)
- subkey = strchr(subkey + 1, '.');
+ if (!subkey)
+ return -1;
+
+ subkey = strchr(subkey + 1, '.');
if (!subkey)
return -1;
subkey++;
- if (!*subkey)
+ if (*subkey == '\0')
return -1;
+
for (i = 0; i < NUM_LXC_HOOKS; i++) {
if (strcmp(lxchook_names[i], subkey) == 0) {
found = i;
break;
}
}
+
if (found == -1)
return -1;
lxc_list_for_each(it, &c->hooks[found]) {
strprint(retv, inlen, "%s\n", (char *)it->elem);
}
+
return fulllen;
}
* printed, in 'lxc.prlimit.resource = value' format.
*/
static int get_config_prlimit(const char *key, char *retv, int inlen,
- struct lxc_conf *c, void *data)
+ struct lxc_conf *c, void *data)
{
int fulllen = 0, len;
bool get_all = false;
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",
if (get_all) {
strprint(retv, inlen, "lxc.prlimit.%s = %s\n",
lim->resource, buf);
- } else if (!strcmp(lim->resource, key)) {
+ } else if (strcmp(lim->resource, key) == 0) {
strprint(retv, inlen, "%s", buf);
}
}
* entries will be printed, in 'lxc.sysctl.key = value' format.
*/
static int get_config_sysctl(const char *key, char *retv, int inlen,
- struct lxc_conf *c, void *data)
+ struct lxc_conf *c, void *data)
{
int len;
struct lxc_list *it;
lxc_list_for_each(it, &c->sysctls) {
struct lxc_sysctl *elem = it->elem;
if (get_all) {
- strprint(retv, inlen, "lxc.sysctl.%s = %s\n",
- elem->key, elem->value);
+ strprint(retv, inlen, "lxc.sysctl.%s = %s\n", elem->key,
+ elem->value);
} else if (strcmp(elem->key, key) == 0) {
strprint(retv, inlen, "%s", elem->value);
}
}
static int get_config_proc(const char *key, char *retv, int inlen,
- struct lxc_conf *c, void *data)
+ struct lxc_conf *c, void *data)
{
struct lxc_list *it;
int len;
if (get_all) {
strprint(retv, inlen, "lxc.proc.%s = %s\n",
- proc->filename, proc->value);
+ proc->filename, proc->value);
} else if (strcmp(proc->filename, key) == 0) {
strprint(retv, inlen, "%s", proc->value);
}
ret = lxc_safe_uint((idx_start + 1), &tmpidx);
if (ret < 0) {
errno = -ret;
- SYSERROR("Failed to parse usigned integer from string \"%s\"",
+ SYSERROR("Failed to parse unsigned integer from string \"%s\"",
idx_start + 1);
*idx = ret;
goto on_error;
*/
if (tmpidx == INT_MAX) {
SYSERROR("Number of configured networks would overflow the "
- "counter");
+ "counter");
goto on_error;
}
*idx = tmpidx;
ret = config->set(deindexed_key, value, lxc_conf, netdev);
free(deindexed_key);
+
return ret;
}
ret = config->clr(deindexed_key, lxc_conf, netdev);
free(deindexed_key);
+
return ret;
}
ret = config->get(deindexed_key, retv, inlen, c, netdev);
free(deindexed_key);
+
return ret;
}
return -1;
listlen = lxc_list_len(&netdev->ipv4);
+
lxc_list_for_each(it, &netdev->ipv4) {
struct lxc_inetdev *i = it->elem;
inet_ntop(AF_INET, &i->addr, buf, sizeof(buf));
return -1;
listlen = lxc_list_len(&netdev->ipv6);
+
lxc_list_for_each(it, &netdev->ipv6) {
struct lxc_inet6dev *i = it->elem;
inet_ntop(AF_INET6, &i->addr, buf, sizeof(buf));
else
memset(retv, 0, inlen);
- for (i = 0; i < config_size; i++) {
- char *s = config[i].name;
+ for (i = 0; i < config_jump_table_size; i++) {
+ char *s = config_jump_table[i].name;
if (s[strlen(s) - 1] == '.')
continue;
strprint(retv, inlen, "type\n");
strprint(retv, inlen, "script.up\n");
strprint(retv, inlen, "script.down\n");
+
if (netdev->type != LXC_NET_EMPTY) {
strprint(retv, inlen, "flags\n");
strprint(retv, inlen, "link\n");