#include <sys/personality.h>
#endif
+#ifndef HAVE_STRLCPY
+#include "include/strlcpy.h"
+#endif
+
lxc_log_define(lxc_confile, lxc);
#define lxc_config_define(name) \
lxc_config_define(cgroup_controller);
lxc_config_define(cgroup2_controller);
lxc_config_define(cgroup_dir);
-lxc_config_define(console_logfile);
-lxc_config_define(console_rotate);
-lxc_config_define(console_buffer_logfile);
lxc_config_define(console_buffer_size);
+lxc_config_define(console_logfile);
lxc_config_define(console_path);
+lxc_config_define(console_rotate);
+lxc_config_define(console_size);
lxc_config_define(environment);
lxc_config_define(ephemeral);
lxc_config_define(execute_cmd);
{ "lxc.cgroup2", set_config_cgroup2_controller, get_config_cgroup2_controller, clr_config_cgroup2_controller, },
{ "lxc.cgroup.dir", set_config_cgroup_dir, get_config_cgroup_dir, clr_config_cgroup_dir, },
{ "lxc.cgroup", set_config_cgroup_controller, get_config_cgroup_controller, clr_config_cgroup_controller, },
- { "lxc.console.buffer.logfile", set_config_console_buffer_logfile, get_config_console_buffer_logfile, clr_config_console_buffer_logfile, },
{ "lxc.console.buffer.size", set_config_console_buffer_size, get_config_console_buffer_size, clr_config_console_buffer_size, },
{ "lxc.console.logfile", set_config_console_logfile, get_config_console_logfile, clr_config_console_logfile, },
{ "lxc.console.path", set_config_console_path, get_config_console_path, clr_config_console_path, },
{ "lxc.console.rotate", set_config_console_rotate, get_config_console_rotate, clr_config_console_rotate, },
+ { "lxc.console.size", set_config_console_size, get_config_console_size, clr_config_console_size, },
{ "lxc.environment", set_config_environment, get_config_environment, clr_config_environment, },
{ "lxc.ephemeral", set_config_ephemeral, get_config_ephemeral, clr_config_ephemeral, },
{ "lxc.execute.cmd", set_config_execute_cmd, get_config_execute_cmd, clr_config_execute_cmd, },
/* No prefix specified, determine it from the network class. */
if (prefix) {
ret = lxc_safe_uint(prefix, &inetdev->prefix);
- if (ret < 0)
+ if (ret < 0) {
+ free(inetdev);
+ free(list);
+ free(addr);
return -1;
+ }
} else {
inetdev->prefix = config_ip_prefix(&inetdev->addr);
}
static int set_config_pty_max(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
+ int ret;
+ unsigned int max = 0;
+
if (lxc_config_value_empty(value)) {
- lxc_conf->pts = 0;
+ lxc_conf->pty_max = 0;
return 0;
}
- if (lxc_safe_uint(value, &lxc_conf->pts) < 0)
+ ret = lxc_safe_uint(value, &max);
+ if (ret < 0)
return -1;
+ lxc_conf->pty_max = max;
return 0;
}
if (!list_item)
goto on_error;
- list_item->elem = strdup(value);
+ if (!strchr(value, '=')) {
+ const char *env_val;
+ const char *env_key = value;
+ const char *env_var[3] = {0};
+
+ env_val = getenv(env_key);
+ if (!env_val)
+ goto on_error;
+
+ env_var[0] = env_key;
+ env_var[1] = env_val;
+ list_item->elem = lxc_string_join("=", env_var, false);
+ } else {
+ list_item->elem = strdup(value);
+ }
if (!list_item->elem)
goto on_error;
static int set_config_tty_max(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
+ int ret;
+ unsigned int nbtty = 0;
+
if (lxc_config_value_empty(value)) {
- lxc_conf->tty = 0;
+ lxc_conf->ttys.max = 0;
return 0;
}
- return lxc_safe_uint(value, &lxc_conf->tty);
+ ret = lxc_safe_uint(value, &nbtty);
+ if (ret < 0)
+ return -1;
+
+ lxc_conf->ttys.max = nbtty;
+ return 0;
}
static int set_config_tty_dir(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
- return set_config_string_item_max(&lxc_conf->ttydir, value,
+ return set_config_string_item_max(&lxc_conf->ttys.dir, value,
NAME_MAX + 1);
}
return 0;
}
-static int set_config_console_buffer_logfile(const char *key, const char *value,
- struct lxc_conf *lxc_conf,
- void *data)
+static int set_config_console_size(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
{
- return set_config_path_item(&lxc_conf->console.buffer_log_file, value);
+ int ret;
+ int64_t size;
+ uint64_t log_size, pgsz;
+
+ if (lxc_config_value_empty(value)) {
+ lxc_conf->console.log_size = 0;
+ return 0;
+ }
+
+ /* If the user specified "auto" the default log size is 2^17 = 128 Kib */
+ if (!strcmp(value, "auto")) {
+ lxc_conf->console.log_size = 1 << 17;
+ return 0;
+ }
+
+ ret = parse_byte_size_string(value, &size);
+ if (ret < 0)
+ return -1;
+
+ if (size < 0)
+ return -EINVAL;
+
+ /* must be at least a page size */
+ pgsz = lxc_getpagesize();
+ if ((uint64_t)size < pgsz) {
+ NOTICE("Requested ringbuffer size for the console is %" PRId64
+ " but must be at least %" PRId64
+ " bytes. Setting ringbuffer size to %" PRId64 " bytes",
+ size, pgsz, pgsz);
+ size = pgsz;
+ }
+
+ log_size = lxc_find_next_power2((uint64_t)size);
+ if (log_size == 0)
+ return -EINVAL;
+
+ if (log_size != size)
+ NOTICE("Passed size was not a power of 2. Rounding log size to "
+ "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)
while ((direntp = readdir(dir))) {
const char *fnam;
- if (!direntp)
- break;
fnam = direntp->d_name;
if (!strcmp(fnam, "."))
return -1;
}
- strcpy(utsname->nodename, value);
+ (void)strlcpy(utsname->nodename, value, sizeof(utsname->nodename));
free(lxc_conf->utsname);
lxc_conf->utsname = utsname;
if (!conf->rcfile)
conf->rcfile = strdup(file);
- return lxc_file_for_each_line(file, parse_line, &c);
+ return lxc_file_for_each_line_mmap(file, parse_line, &c);
}
int lxc_config_define_add(struct lxc_list *defines, char *arg)
char *name;
unsigned long per;
} pername[] = {
- { "x86", PER_LINUX32 },
- { "linux32", PER_LINUX32 },
+ { "arm", PER_LINUX32 },
+ { "armel", PER_LINUX32 },
+ { "armhf", PER_LINUX32 },
+ { "armv7l", PER_LINUX32 },
+ { "athlon", PER_LINUX32 },
{ "i386", PER_LINUX32 },
{ "i486", PER_LINUX32 },
{ "i586", PER_LINUX32 },
{ "i686", PER_LINUX32 },
- { "athlon", PER_LINUX32 },
+ { "linux32", PER_LINUX32 },
{ "mips", PER_LINUX32 },
{ "mipsel", PER_LINUX32 },
{ "ppc", PER_LINUX32 },
- { "arm", PER_LINUX32 },
- { "armv7l", PER_LINUX32 },
- { "armhf", PER_LINUX32 },
- { "armel", PER_LINUX32 },
{ "powerpc", PER_LINUX32 },
- { "linux64", PER_LINUX },
- { "x86_64", PER_LINUX },
+ { "x86", PER_LINUX32 },
{ "amd64", PER_LINUX },
+ { "arm64", PER_LINUX },
+ { "linux64", PER_LINUX },
{ "mips64", PER_LINUX },
{ "mips64el", PER_LINUX },
{ "ppc64", PER_LINUX },
- { "ppc64le", PER_LINUX },
{ "ppc64el", PER_LINUX },
+ { "ppc64le", PER_LINUX },
{ "powerpc64", PER_LINUX },
{ "s390x", PER_LINUX },
- { "aarch64", PER_LINUX },
- { "arm64", PER_LINUX },
+ { "x86_64", PER_LINUX },
};
size_t len = sizeof(pername) / sizeof(pername[0]);
- for (i = 0; i < len; i++) {
+ for (i = 0; i < len; i++)
if (!strcmp(pername[i].name, arch))
return pername[i].per;
- }
#endif
return -1;
}
/* Write out a configuration file. */
-void write_config(FILE *fout, struct lxc_conf *c)
+int write_config(int fd, const struct lxc_conf *conf)
{
int ret;
- size_t len = c->unexpanded_len;
+ size_t len = conf->unexpanded_len;
- if (!len)
- return;
+ if (len == 0)
+ return 0;
- ret = fwrite(c->unexpanded_config, 1, len, fout);
- if (ret != len)
+ ret = lxc_write_nointr(fd, conf->unexpanded_config, len);
+ if (ret < 0) {
SYSERROR("Failed to write configuration file");
+ return -1;
+ }
+
+ return 0;
}
bool do_append_unexp_config_line(struct lxc_conf *conf, const char *key,
if (p >= lend)
goto next;
- /* Whenever an lxc.mount.entry entry is found in a line we check
- * if the substring " overlay" or the substring " aufs" is
- * present before doing any further work. We check for "
- * overlay" and " aufs" since both substrings need to have at
- * least one space before them in a valid overlay
+ /* Whenever a lxc.mount.entry entry is found in a line we check
+ * if the substring "overlay" is present before doing any
+ * further work. We check for "overlay" because substrings need
+ * to have at least one space before them in a valid overlay
* lxc.mount.entry (/A B overlay). When the space before is
* missing it is very likely that these substrings are part of a
* path or something else. (Checking q >= lend ensures that we
* only count matches in the current line.) */
- if ((!(q = strstr(p, " overlay")) || q >= lend) &&
- (!(q = strstr(p, " aufs")) || q >= lend))
+ q = strstr(p, " overlay");
+ if (!q || q >= lend)
goto next;
if (!(q = strstr(p, olddir)) || (q >= lend))
static int get_config_pty_max(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
- return lxc_get_conf_int(c, retv, inlen, c->pts);
+ return lxc_get_conf_size_t(c, retv, inlen, c->pty_max);
}
static int get_config_tty_max(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
- return lxc_get_conf_int(c, retv, inlen, c->tty);
+ return lxc_get_conf_size_t(c, retv, inlen, c->ttys.max);
}
static int get_config_tty_dir(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
- return lxc_get_conf_str(retv, inlen, c->ttydir);
+ return lxc_get_conf_str(retv, inlen, c->ttys.dir);
}
static int get_config_apparmor_profile(const char *key, char *retv, int inlen,
return lxc_get_conf_uint64(c, retv, inlen, c->console.buffer_size);
}
-static int get_config_console_buffer_logfile(const char *key, char *retv,
- int inlen, struct lxc_conf *c,
- void *data)
+static int get_config_console_size(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
{
- return lxc_get_conf_str(retv, inlen, c->console.buffer_log_file);
+ return lxc_get_conf_uint64(c, retv, inlen, c->console.log_size);
}
+
static int get_config_seccomp_profile(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
static inline int clr_config_pty_max(const char *key, struct lxc_conf *c,
void *data)
{
- c->pts = 0;
+ c->pty_max = 0;
return 0;
}
static inline int clr_config_tty_max(const char *key, struct lxc_conf *c,
void *data)
{
- c->tty = 0;
+ c->ttys.tty = 0;
return 0;
}
static inline int clr_config_tty_dir(const char *key, struct lxc_conf *c,
void *data)
{
- free(c->ttydir);
- c->ttydir = NULL;
+ free(c->ttys.dir);
+ c->ttys.dir = NULL;
return 0;
}
return 0;
}
-static inline int clr_config_console_buffer_logfile(const char *key,
- struct lxc_conf *c,
- void *data)
+static inline int clr_config_console_size(const char *key, struct lxc_conf *c,
+ void *data)
{
- free(c->console.buffer_log_file);
- c->console.buffer_log_file = NULL;
+ c->console.log_size = 0;
return 0;
}