Unverified Commit f1a571d6 by Stéphane Graber Committed by GitHub

Merge pull request #2354 from brauner/2018-05-26/config_cleanups

conf: cleanups, and bugfixes
parents 85f839cc 573ad77f
...@@ -835,7 +835,7 @@ static int lxc_setup_dev_symlinks(const struct lxc_rootfs *rootfs) ...@@ -835,7 +835,7 @@ static int lxc_setup_dev_symlinks(const struct lxc_rootfs *rootfs)
} }
/* Build a space-separate list of ptys to pass to systemd. */ /* Build a space-separate list of ptys to pass to systemd. */
static bool append_ptyname(char **pp, char *name) static bool append_ttyname(char **pp, char *name)
{ {
char *p; char *p;
...@@ -863,13 +863,13 @@ static int lxc_setup_ttys(struct lxc_conf *conf) ...@@ -863,13 +863,13 @@ static int lxc_setup_ttys(struct lxc_conf *conf)
{ {
int i, ret; int i, ret;
const struct lxc_tty_info *ttys = &conf->ttys; const struct lxc_tty_info *ttys = &conf->ttys;
char *ttydir = conf->ttydir; char *ttydir = ttys->dir;
char path[MAXPATHLEN], lxcpath[MAXPATHLEN]; char path[MAXPATHLEN], lxcpath[MAXPATHLEN];
if (!conf->rootfs.path) if (!conf->rootfs.path)
return 0; return 0;
for (i = 0; i < ttys->nbtty; i++) { for (i = 0; i < ttys->max; i++) {
struct lxc_terminal_info *tty = &ttys->tty[i]; struct lxc_terminal_info *tty = &ttys->tty[i];
ret = snprintf(path, sizeof(path), "/dev/tty%d", i + 1); ret = snprintf(path, sizeof(path), "/dev/tty%d", i + 1);
...@@ -942,13 +942,13 @@ static int lxc_setup_ttys(struct lxc_conf *conf) ...@@ -942,13 +942,13 @@ static int lxc_setup_ttys(struct lxc_conf *conf)
path); path);
} }
if (!append_ptyname(&conf->pty_names, tty->name)) { if (!append_ttyname(&conf->ttys.tty_names, tty->name)) {
ERROR("Error setting up container_ttys string"); ERROR("Error setting up container_ttys string");
return -1; return -1;
} }
} }
INFO("Finished setting up %d /dev/tty<N> device(s)", ttys->nbtty); INFO("Finished setting up %zu /dev/tty<N> device(s)", ttys->max);
return 0; return 0;
} }
...@@ -958,21 +958,21 @@ int lxc_allocate_ttys(const char *name, struct lxc_conf *conf) ...@@ -958,21 +958,21 @@ int lxc_allocate_ttys(const char *name, struct lxc_conf *conf)
struct lxc_tty_info *ttys = &conf->ttys; struct lxc_tty_info *ttys = &conf->ttys;
/* no tty in the configuration */ /* no tty in the configuration */
if (!conf->tty) if (ttys->max == 0)
return 0; return 0;
ttys->tty = malloc(sizeof(*ttys->tty) * conf->tty); ttys->tty = malloc(sizeof(*ttys->tty) * ttys->max);
if (!ttys->tty) if (!ttys->tty)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < conf->tty; i++) { for (i = 0; i < ttys->max; i++) {
struct lxc_terminal_info *tty = &ttys->tty[i]; struct lxc_terminal_info *tty = &ttys->tty[i];
ret = openpty(&tty->master, &tty->slave, ret = openpty(&tty->master, &tty->slave,
tty->name, NULL, NULL); tty->name, NULL, NULL);
if (ret) { if (ret) {
SYSERROR("Failed to create tty %d", i); SYSERROR("Failed to create tty %d", i);
ttys->nbtty = i; ttys->max = i;
lxc_delete_tty(ttys); lxc_delete_tty(ttys);
return -ENOTTY; return -ENOTTY;
} }
...@@ -996,9 +996,7 @@ int lxc_allocate_ttys(const char *name, struct lxc_conf *conf) ...@@ -996,9 +996,7 @@ int lxc_allocate_ttys(const char *name, struct lxc_conf *conf)
tty->busy = 0; tty->busy = 0;
} }
ttys->nbtty = conf->tty; INFO("Finished creating %zu tty devices", ttys->max);
INFO("Finished creating %d tty devices", conf->tty);
return 0; return 0;
} }
...@@ -1006,7 +1004,7 @@ void lxc_delete_tty(struct lxc_tty_info *ttys) ...@@ -1006,7 +1004,7 @@ void lxc_delete_tty(struct lxc_tty_info *ttys)
{ {
int i; int i;
for (i = 0; i < ttys->nbtty; i++) { for (i = 0; i < ttys->max; i++) {
struct lxc_terminal_info *tty = &ttys->tty[i]; struct lxc_terminal_info *tty = &ttys->tty[i];
close(tty->master); close(tty->master);
...@@ -1015,7 +1013,6 @@ void lxc_delete_tty(struct lxc_tty_info *ttys) ...@@ -1015,7 +1013,6 @@ void lxc_delete_tty(struct lxc_tty_info *ttys)
free(ttys->tty); free(ttys->tty);
ttys->tty = NULL; ttys->tty = NULL;
ttys->nbtty = 0;
} }
static int lxc_send_ttys_to_parent(struct lxc_handler *handler) static int lxc_send_ttys_to_parent(struct lxc_handler *handler)
...@@ -1026,10 +1023,10 @@ static int lxc_send_ttys_to_parent(struct lxc_handler *handler) ...@@ -1026,10 +1023,10 @@ static int lxc_send_ttys_to_parent(struct lxc_handler *handler)
struct lxc_tty_info *ttys = &conf->ttys; struct lxc_tty_info *ttys = &conf->ttys;
int sock = handler->data_sock[0]; int sock = handler->data_sock[0];
if (conf->tty == 0) if (ttys->max == 0)
return 0; return 0;
for (i = 0; i < conf->tty; i++) { for (i = 0; i < ttys->max; i++) {
int ttyfds[2]; int ttyfds[2];
struct lxc_terminal_info *tty = &ttys->tty[i]; struct lxc_terminal_info *tty = &ttys->tty[i];
...@@ -1045,10 +1042,10 @@ static int lxc_send_ttys_to_parent(struct lxc_handler *handler) ...@@ -1045,10 +1042,10 @@ static int lxc_send_ttys_to_parent(struct lxc_handler *handler)
} }
if (ret < 0) if (ret < 0)
ERROR("Failed to send %d ttys to parent: %s", conf->tty, ERROR("Failed to send %zu ttys to parent: %s", ttys->max,
strerror(errno)); strerror(errno));
else else
TRACE("Sent %d ttys to parent", conf->tty); TRACE("Sent %zu ttys to parent", ttys->max);
return ret; return ret;
} }
...@@ -1078,10 +1075,10 @@ static int lxc_create_ttys(struct lxc_handler *handler) ...@@ -1078,10 +1075,10 @@ static int lxc_create_ttys(struct lxc_handler *handler)
} }
} }
if (conf->pty_names) { if (conf->ttys.tty_names) {
ret = setenv("container_ttys", conf->pty_names, 1); ret = setenv("container_ttys", conf->ttys.tty_names, 1);
if (ret < 0) if (ret < 0)
SYSERROR("Failed to set \"container_ttys=%s\"", conf->pty_names); SYSERROR("Failed to set \"container_ttys=%s\"", conf->ttys.tty_names);
} }
ret = 0; ret = 0;
...@@ -1526,14 +1523,14 @@ static int lxc_setup_devpts(struct lxc_conf *conf) ...@@ -1526,14 +1523,14 @@ static int lxc_setup_devpts(struct lxc_conf *conf)
const char *default_devpts_mntopts = "gid=5,newinstance,ptmxmode=0666,mode=0620"; const char *default_devpts_mntopts = "gid=5,newinstance,ptmxmode=0666,mode=0620";
char devpts_mntopts[256]; char devpts_mntopts[256];
if (conf->pts <= 0) { if (conf->pty_max <= 0) {
DEBUG("No new devpts instance will be mounted since no pts " DEBUG("No new devpts instance will be mounted since no pts "
"devices are requested"); "devices are requested");
return 0; return 0;
} }
ret = snprintf(devpts_mntopts, sizeof(devpts_mntopts), "%s,max=%d", ret = snprintf(devpts_mntopts, sizeof(devpts_mntopts), "%s,max=%zu",
default_devpts_mntopts, conf->pts); default_devpts_mntopts, conf->pty_max);
if (ret < 0 || (size_t)ret >= sizeof(devpts_mntopts)) if (ret < 0 || (size_t)ret >= sizeof(devpts_mntopts))
return -1; return -1;
...@@ -3480,7 +3477,7 @@ int lxc_setup(struct lxc_handler *handler) ...@@ -3480,7 +3477,7 @@ int lxc_setup(struct lxc_handler *handler)
} }
ret = lxc_setup_console(&lxc_conf->rootfs, &lxc_conf->console, ret = lxc_setup_console(&lxc_conf->rootfs, &lxc_conf->console,
lxc_conf->ttydir); lxc_conf->ttys.dir);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to setup console"); ERROR("Failed to setup console");
return -1; return -1;
...@@ -3890,14 +3887,14 @@ void lxc_conf_free(struct lxc_conf *conf) ...@@ -3890,14 +3887,14 @@ void lxc_conf_free(struct lxc_conf *conf)
if (conf->logfd != -1) if (conf->logfd != -1)
close(conf->logfd); close(conf->logfd);
free(conf->utsname); free(conf->utsname);
free(conf->ttydir); free(conf->ttys.dir);
free(conf->ttys.tty_names);
free(conf->fstab); free(conf->fstab);
free(conf->rcfile); free(conf->rcfile);
free(conf->execute_cmd); free(conf->execute_cmd);
free(conf->init_cmd); free(conf->init_cmd);
free(conf->init_cwd); free(conf->init_cwd);
free(conf->unexpanded_config); free(conf->unexpanded_config);
free(conf->pty_names);
free(conf->syslog); free(conf->syslog);
lxc_free_networks(&conf->network); lxc_free_networks(&conf->network);
free(conf->lsm_aa_profile); free(conf->lsm_aa_profile);
......
...@@ -78,12 +78,13 @@ struct lxc_cgroup { ...@@ -78,12 +78,13 @@ struct lxc_cgroup {
}; };
#if !HAVE_SYS_RESOURCE_H #if !HAVE_SYS_RESOURCE_H
# define RLIM_INFINITY ((unsigned long)-1) #define RLIM_INFINITY ((unsigned long)-1)
struct rlimit { struct rlimit {
unsigned long rlim_cur; unsigned long rlim_cur;
unsigned long rlim_max; unsigned long rlim_max;
}; };
#endif #endif
/* /*
* Defines a structure to configure resource limits to set via setrlimit(). * Defines a structure to configure resource limits to set via setrlimit().
* @resource : the resource name in lowercase without the RLIMIT_ prefix * @resource : the resource name in lowercase without the RLIMIT_ prefix
...@@ -136,10 +137,12 @@ struct id_map { ...@@ -136,10 +137,12 @@ struct id_map {
/* Defines the number of tty configured and contains the /* Defines the number of tty configured and contains the
* instantiated ptys * instantiated ptys
* @nbtty = number of configured ttys * @max = number of configured ttys
*/ */
struct lxc_tty_info { struct lxc_tty_info {
int nbtty; size_t max;
char *dir;
char *tty_names;
struct lxc_terminal_info *tty; struct lxc_terminal_info *tty;
}; };
...@@ -176,11 +179,12 @@ enum { ...@@ -176,11 +179,12 @@ enum {
LXC_AUTO_CGROUP_FULL_RO = 0x040, /* /sys/fs/cgroup (full mount, read-only) */ LXC_AUTO_CGROUP_FULL_RO = 0x040, /* /sys/fs/cgroup (full mount, read-only) */
LXC_AUTO_CGROUP_FULL_RW = 0x050, /* /sys/fs/cgroup (full mount, read-write) */ LXC_AUTO_CGROUP_FULL_RW = 0x050, /* /sys/fs/cgroup (full mount, read-write) */
LXC_AUTO_CGROUP_FULL_MIXED = 0x060, /* /sys/fs/cgroup (full mount, parent r/o, own r/w) */ LXC_AUTO_CGROUP_FULL_MIXED = 0x060, /* /sys/fs/cgroup (full mount, parent r/o, own r/w) */
/* These are defined in such a way as to retain /*
* binary compatibility with earlier versions of * These are defined in such a way as to retain binary compatibility
* this code. If the previous mask is applied, * with earlier versions of this code. If the previous mask is applied,
* both of these will default back to the _MIXED * both of these will default back to the _MIXED variants, which is
* variants, which is safe. */ * safe.
*/
LXC_AUTO_CGROUP_NOSPEC = 0x0B0, /* /sys/fs/cgroup (partial mount, r/w or mixed, depending on caps) */ LXC_AUTO_CGROUP_NOSPEC = 0x0B0, /* /sys/fs/cgroup (partial mount, r/w or mixed, depending on caps) */
LXC_AUTO_CGROUP_FULL_NOSPEC = 0x0E0, /* /sys/fs/cgroup (full mount, r/w or mixed, depending on caps) */ LXC_AUTO_CGROUP_FULL_NOSPEC = 0x0E0, /* /sys/fs/cgroup (full mount, r/w or mixed, depending on caps) */
LXC_AUTO_CGROUP_FORCE = 0x100, /* mount cgroups even when cgroup namespaces are supported */ LXC_AUTO_CGROUP_FORCE = 0x100, /* mount cgroups even when cgroup namespaces are supported */
...@@ -188,24 +192,6 @@ enum { ...@@ -188,24 +192,6 @@ enum {
LXC_AUTO_ALL_MASK = 0x1FF, /* all known settings */ LXC_AUTO_ALL_MASK = 0x1FF, /* all known settings */
}; };
/*
* Defines the global container configuration
* @rootfs : root directory to run the container
* @mount : list of mount points
* @tty : numbers of tty
* @pts : new pts instance
* @mount_list : list of mount point (alternative to fstab file)
* @network : network configuration
* @utsname : container utsname
* @fstab : path to a fstab file format
* @caps : list of the capabilities to drop
* @keepcaps : list of the capabilities to keep
* @ttys : tty data
* @console : console data
* @ttydir : directory (under /dev) in which to create console and ttys
* @lsm_aa_profile : apparmor profile to switch to or NULL
* @lsm_se_context : selinux type to switch to or NULL
*/
enum lxchooks { enum lxchooks {
LXCHOOK_PRESTART, LXCHOOK_PRESTART,
LXCHOOK_PREMOUNT, LXCHOOK_PREMOUNT,
...@@ -230,40 +216,52 @@ struct lxc_state_client { ...@@ -230,40 +216,52 @@ struct lxc_state_client {
struct lxc_conf { struct lxc_conf {
/* Pointer to the name of the container. Do not free! */ /* Pointer to the name of the container. Do not free! */
const char *name; const char *name;
int is_execute; bool is_execute;
char *fstab;
unsigned int tty;
unsigned int pts;
int reboot; int reboot;
signed long personality; signed long personality;
struct utsname *utsname; struct utsname *utsname;
struct { struct {
struct lxc_list cgroup; struct lxc_list cgroup;
struct lxc_list cgroup2; struct lxc_list cgroup2;
}; };
struct { struct {
struct lxc_list id_map; struct lxc_list id_map;
/* Pointer to the idmap entry for the container's root uid in /*
* the id_map list. Do not free! */ * Pointer to the idmap entry for the container's root uid in
* the id_map list. Do not free!
*/
struct id_map *root_nsuid_map; struct id_map *root_nsuid_map;
/* Pointer to the idmap entry for the container's root gid in /*
* the id_map list. Do not free! */ * Pointer to the idmap entry for the container's root gid in
* the id_map list. Do not free!
*/
struct id_map *root_nsgid_map; struct id_map *root_nsgid_map;
}; };
struct lxc_list network; struct lxc_list network;
struct {
char *fstab;
int auto_mounts; int auto_mounts;
struct lxc_list mount_list; struct lxc_list mount_list;
};
struct lxc_list caps; struct lxc_list caps;
struct lxc_list keepcaps; struct lxc_list keepcaps;
/* /dev/tty<idx> devices */
struct lxc_tty_info ttys; struct lxc_tty_info ttys;
/* Comma-separated list of lxc.tty.max pty names. */ /* /dev/console device */
char *pty_names;
struct lxc_terminal console; struct lxc_terminal console;
/* maximum pty devices allowed by devpts mount */
size_t pty_max;
struct lxc_rootfs rootfs; struct lxc_rootfs rootfs;
char *ttydir; bool close_all_fds;
int close_all_fds;
struct { struct {
unsigned int hooks_version; unsigned int hooks_version;
......
...@@ -974,14 +974,19 @@ static int set_config_personality(const char *key, const char *value, ...@@ -974,14 +974,19 @@ static int set_config_personality(const char *key, const char *value,
static int set_config_pty_max(const char *key, const char *value, static int set_config_pty_max(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data) struct lxc_conf *lxc_conf, void *data)
{ {
int ret;
unsigned int max = 0;
if (lxc_config_value_empty(value)) { if (lxc_config_value_empty(value)) {
lxc_conf->pts = 0; lxc_conf->pty_max = 0;
return 0; return 0;
} }
if (lxc_safe_uint(value, &lxc_conf->pts) < 0) ret = lxc_safe_uint(value, &max);
if (ret < 0)
return -1; return -1;
lxc_conf->pty_max = max;
return 0; return 0;
} }
...@@ -1127,18 +1132,26 @@ on_error: ...@@ -1127,18 +1132,26 @@ on_error:
static int set_config_tty_max(const char *key, const char *value, static int set_config_tty_max(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data) struct lxc_conf *lxc_conf, void *data)
{ {
int ret;
unsigned int nbtty = 0;
if (lxc_config_value_empty(value)) { if (lxc_config_value_empty(value)) {
lxc_conf->tty = 0; lxc_conf->ttys.max = 0;
return 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, static int set_config_tty_dir(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data) 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); NAME_MAX + 1);
} }
...@@ -2911,19 +2924,19 @@ static int get_config_personality(const char *key, char *retv, int inlen, ...@@ -2911,19 +2924,19 @@ static int get_config_personality(const char *key, char *retv, int inlen,
static int get_config_pty_max(const char *key, char *retv, int inlen, static int get_config_pty_max(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data) 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, static int get_config_tty_max(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data) 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, static int get_config_tty_dir(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data) 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, static int get_config_apparmor_profile(const char *key, char *retv, int inlen,
...@@ -3688,22 +3701,22 @@ static inline int clr_config_personality(const char *key, struct lxc_conf *c, ...@@ -3688,22 +3701,22 @@ static inline int clr_config_personality(const char *key, struct lxc_conf *c,
static inline int clr_config_pty_max(const char *key, struct lxc_conf *c, static inline int clr_config_pty_max(const char *key, struct lxc_conf *c,
void *data) void *data)
{ {
c->pts = 0; c->pty_max = 0;
return 0; return 0;
} }
static inline int clr_config_tty_max(const char *key, struct lxc_conf *c, static inline int clr_config_tty_max(const char *key, struct lxc_conf *c,
void *data) void *data)
{ {
c->tty = 0; c->ttys.tty = 0;
return 0; return 0;
} }
static inline int clr_config_tty_dir(const char *key, struct lxc_conf *c, static inline int clr_config_tty_dir(const char *key, struct lxc_conf *c,
void *data) void *data)
{ {
free(c->ttydir); free(c->ttys.dir);
c->ttydir = NULL; c->ttys.dir = NULL;
return 0; return 0;
} }
......
...@@ -643,6 +643,16 @@ int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v) ...@@ -643,6 +643,16 @@ int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v)
return snprintf(retv, inlen, "%d", v); return snprintf(retv, inlen, "%d", v);
} }
int lxc_get_conf_size_t(struct lxc_conf *c, char *retv, int inlen, size_t v)
{
if (!retv)
inlen = 0;
else
memset(retv, 0, inlen);
return snprintf(retv, inlen, "%zu", v);
}
int lxc_get_conf_uint64(struct lxc_conf *c, char *retv, int inlen, uint64_t v) int lxc_get_conf_uint64(struct lxc_conf *c, char *retv, int inlen, uint64_t v)
{ {
if (!retv) if (!retv)
......
...@@ -84,6 +84,7 @@ extern void update_hwaddr(const char *line); ...@@ -84,6 +84,7 @@ extern void update_hwaddr(const char *line);
extern bool new_hwaddr(char *hwaddr); extern bool new_hwaddr(char *hwaddr);
extern int lxc_get_conf_str(char *retv, int inlen, const char *value); 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 int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v);
extern int lxc_get_conf_size_t(struct lxc_conf *c, char *retv, int inlen, size_t v);
extern int lxc_get_conf_uint64(struct lxc_conf *c, char *retv, int inlen, uint64_t v); extern int lxc_get_conf_uint64(struct lxc_conf *c, char *retv, int inlen, uint64_t v);
extern bool parse_limit_value(const char **value, rlim_t *res); extern bool parse_limit_value(const char **value, rlim_t *res);
extern int lxc_inherit_namespace(const char *lxcname_or_pid, extern int lxc_inherit_namespace(const char *lxcname_or_pid,
......
...@@ -152,7 +152,7 @@ int lxc_execute(const char *name, char *const argv[], int quiet, ...@@ -152,7 +152,7 @@ int lxc_execute(const char *name, char *const argv[], int quiet,
struct execute_args args = {.argv = argv, .quiet = quiet}; struct execute_args args = {.argv = argv, .quiet = quiet};
TRACE("Doing lxc_execute"); TRACE("Doing lxc_execute");
handler->conf->is_execute = 1; handler->conf->is_execute = true;
return __lxc_start(name, handler, &execute_start_ops, &args, lxcpath, return __lxc_start(name, handler, &execute_start_ops, &args, lxcpath,
backgrounded, error_num); backgrounded, error_num);
} }
...@@ -2008,7 +2008,7 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout) ...@@ -2008,7 +2008,7 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
/* Detect whether we should send SIGRTMIN + 3 (e.g. systemd). */ /* Detect whether we should send SIGRTMIN + 3 (e.g. systemd). */
if (c->lxc_conf && c->lxc_conf->haltsignal) if (c->lxc_conf && c->lxc_conf->haltsignal)
haltsignal = c->lxc_conf->haltsignal; haltsignal = c->lxc_conf->haltsignal;
else if (task_blocking_signal(pid, (SIGRTMIN + 3))) else if (task_blocks_signal(pid, (SIGRTMIN + 3)))
haltsignal = (SIGRTMIN + 3); haltsignal = (SIGRTMIN + 3);
/* Add a new state client before sending the shutdown signal so that we /* Add a new state client before sending the shutdown signal so that we
......
...@@ -144,29 +144,42 @@ int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data) ...@@ -144,29 +144,42 @@ int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data)
int lxc_char_left_gc(const char *buffer, size_t len) int lxc_char_left_gc(const char *buffer, size_t len)
{ {
size_t i; size_t i;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
if (buffer[i] == ' ' || if (buffer[i] == ' ' ||
buffer[i] == '\t') buffer[i] == '\t')
continue; continue;
return i; return i;
} }
return 0; return 0;
} }
int lxc_char_right_gc(const char *buffer, size_t len) int lxc_char_right_gc(const char *buffer, size_t len)
{ {
int i; int i;
for (i = len - 1; i >= 0; i--) { for (i = len - 1; i >= 0; i--) {
if (buffer[i] == ' ' || if (buffer[i] == ' ' ||
buffer[i] == '\t' || buffer[i] == '\t' ||
buffer[i] == '\n' || buffer[i] == '\n' ||
buffer[i] == '\0') buffer[i] == '\0')
continue; continue;
return i + 1; return i + 1;
} }
return 0; return 0;
} }
char *lxc_trim_whitespace_in_place(char *buffer)
{
buffer += lxc_char_left_gc(buffer, strlen(buffer));
buffer[lxc_char_right_gc(buffer, strlen(buffer))] = '\0';
return buffer;
}
int lxc_is_line_empty(const char *line) int lxc_is_line_empty(const char *line)
{ {
int i; int i;
......
...@@ -41,6 +41,8 @@ extern int lxc_char_left_gc(const char *buffer, size_t len); ...@@ -41,6 +41,8 @@ extern int lxc_char_left_gc(const char *buffer, size_t len);
extern int lxc_char_right_gc(const char *buffer, size_t len); extern int lxc_char_right_gc(const char *buffer, size_t len);
extern char *lxc_trim_whitespace_in_place(char *buffer);
extern int lxc_is_line_empty(const char *line); extern int lxc_is_line_empty(const char *line);
/* mmap() wrapper. lxc_strmmap() will take care to \0-terminate files so that /* mmap() wrapper. lxc_strmmap() will take care to \0-terminate files so that
......
...@@ -215,13 +215,13 @@ static int get_seccomp_arg_value(char *key, struct seccomp_v2_rule_args *rule_ar ...@@ -215,13 +215,13 @@ static int get_seccomp_arg_value(char *key, struct seccomp_v2_rule_args *rule_ar
return -1; return -1;
} }
ret = lxc_safe_uint64(v, &value); ret = lxc_safe_uint64(v, &value, 0);
if (ret < 0) { if (ret < 0) {
ERROR("Invalid argument value"); ERROR("Invalid argument value");
return -1; return -1;
} }
ret = lxc_safe_uint64(m, &mask); ret = lxc_safe_uint64(m, &mask, 0);
if (ret < 0) { if (ret < 0) {
ERROR("Invalid argument mask"); ERROR("Invalid argument mask");
return -1; return -1;
......
...@@ -1247,7 +1247,7 @@ static int do_start(void *data) ...@@ -1247,7 +1247,7 @@ static int do_start(void *data)
* make sure that that pty is stdin,stdout,stderr. * make sure that that pty is stdin,stdout,stderr.
*/ */
if (handler->conf->console.slave >= 0) { if (handler->conf->console.slave >= 0) {
if (handler->backgrounded || handler->conf->is_execute == 0) if (handler->backgrounded || !handler->conf->is_execute)
ret = set_stdfds(handler->conf->console.slave); ret = set_stdfds(handler->conf->console.slave);
else else
ret = lxc_terminal_set_stdfds(handler->conf->console.slave); ret = lxc_terminal_set_stdfds(handler->conf->console.slave);
...@@ -1331,8 +1331,8 @@ static int do_start(void *data) ...@@ -1331,8 +1331,8 @@ static int do_start(void *data)
goto out_warn_father; goto out_warn_father;
} }
if (handler->conf->pty_names) { if (handler->conf->ttys.tty_names) {
ret = putenv(handler->conf->pty_names); ret = putenv(handler->conf->ttys.tty_names);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to set environment variable for container ptys"); SYSERROR("Failed to set environment variable for container ptys");
goto out_warn_father; goto out_warn_father;
...@@ -1397,14 +1397,14 @@ static int lxc_recv_ttys_from_child(struct lxc_handler *handler) ...@@ -1397,14 +1397,14 @@ static int lxc_recv_ttys_from_child(struct lxc_handler *handler)
struct lxc_conf *conf = handler->conf; struct lxc_conf *conf = handler->conf;
struct lxc_tty_info *ttys = &conf->ttys; struct lxc_tty_info *ttys = &conf->ttys;
if (!conf->tty) if (!conf->ttys.max)
return 0; return 0;
ttys->tty = malloc(sizeof(*ttys->tty) * conf->tty); ttys->tty = malloc(sizeof(*ttys->tty) * ttys->max);
if (!ttys->tty) if (!ttys->tty)
return -1; return -1;
for (i = 0; i < conf->tty; i++) { for (i = 0; i < conf->ttys.max; i++) {
int ttyfds[2]; int ttyfds[2];
ret = lxc_abstract_unix_recv_fds(sock, ttyfds, 2, NULL, 0); ret = lxc_abstract_unix_recv_fds(sock, ttyfds, 2, NULL, 0);
...@@ -1419,12 +1419,10 @@ static int lxc_recv_ttys_from_child(struct lxc_handler *handler) ...@@ -1419,12 +1419,10 @@ static int lxc_recv_ttys_from_child(struct lxc_handler *handler)
"parent", tty->master, tty->slave); "parent", tty->master, tty->slave);
} }
if (ret < 0) if (ret < 0)
ERROR("Failed to receive %d ttys from child: %s", conf->tty, ERROR("Failed to receive %zu ttys from child: %s", ttys->max,
strerror(errno)); strerror(errno));
else else
TRACE("Received %d ttys from child", conf->tty); TRACE("Received %zu ttys from child", ttys->max);
ttys->nbtty = conf->tty;
return ret; return ret;
} }
......
...@@ -618,7 +618,7 @@ int lxc_terminal_allocate(struct lxc_conf *conf, int sockfd, int *ttyreq) ...@@ -618,7 +618,7 @@ int lxc_terminal_allocate(struct lxc_conf *conf, int sockfd, int *ttyreq)
} }
if (*ttyreq > 0) { if (*ttyreq > 0) {
if (*ttyreq > ttys->nbtty) if (*ttyreq > ttys->max)
goto out; goto out;
if (ttys->tty[*ttyreq - 1].busy) if (ttys->tty[*ttyreq - 1].busy)
...@@ -630,12 +630,12 @@ int lxc_terminal_allocate(struct lxc_conf *conf, int sockfd, int *ttyreq) ...@@ -630,12 +630,12 @@ int lxc_terminal_allocate(struct lxc_conf *conf, int sockfd, int *ttyreq)
} }
/* Search for next available tty, fixup index tty1 => [0]. */ /* Search for next available tty, fixup index tty1 => [0]. */
for (ttynum = 1; ttynum <= ttys->nbtty && ttys->tty[ttynum - 1].busy; ttynum++) { for (ttynum = 1; ttynum <= ttys->max && ttys->tty[ttynum - 1].busy; ttynum++) {
; ;
} }
/* We didn't find any available slot for tty. */ /* We didn't find any available slot for tty. */
if (ttynum > ttys->nbtty) if (ttynum > ttys->max)
goto out; goto out;
*ttyreq = ttynum; *ttyreq = ttynum;
...@@ -654,7 +654,7 @@ void lxc_terminal_free(struct lxc_conf *conf, int fd) ...@@ -654,7 +654,7 @@ void lxc_terminal_free(struct lxc_conf *conf, int fd)
struct lxc_tty_info *ttys = &conf->ttys; struct lxc_tty_info *ttys = &conf->ttys;
struct lxc_terminal *terminal = &conf->console; struct lxc_terminal *terminal = &conf->console;
for (i = 0; i < ttys->nbtty; i++) for (i = 0; i < ttys->max; i++)
if (ttys->tty[i].busy == fd) if (ttys->tty[i].busy == fd)
ttys->tty[i].busy = 0; ttys->tty[i].busy = 0;
......
...@@ -83,7 +83,7 @@ struct lxc_arguments { ...@@ -83,7 +83,7 @@ struct lxc_arguments {
int force; int force;
/* close fds from parent? */ /* close fds from parent? */
int close_all_fds; bool close_all_fds;
/* lxc-create */ /* lxc-create */
char *bdevtype, *configfile, *template; char *bdevtype, *configfile, *template;
......
...@@ -96,7 +96,7 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) ...@@ -96,7 +96,7 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg)
args->rcfile = arg; args->rcfile = arg;
break; break;
case 'C': case 'C':
args->close_all_fds = 1; args->close_all_fds = true;
break; break;
case 's': case 's':
return lxc_config_define_add(&defines, arg); return lxc_config_define_add(&defines, arg);
......
...@@ -1815,12 +1815,12 @@ int lxc_count_file_lines(const char *fn) ...@@ -1815,12 +1815,12 @@ int lxc_count_file_lines(const char *fn)
/* Check whether a signal is blocked by a process. */ /* Check whether a signal is blocked by a process. */
/* /proc/pid-to-str/status\0 = (5 + 21 + 7 + 1) */ /* /proc/pid-to-str/status\0 = (5 + 21 + 7 + 1) */
#define __PROC_STATUS_LEN (6 + (LXC_NUMSTRLEN64) + 7 + 1) #define __PROC_STATUS_LEN (6 + (LXC_NUMSTRLEN64) + 7 + 1)
bool task_blocking_signal(pid_t pid, int signal) bool task_blocks_signal(pid_t pid, int signal)
{ {
int ret; int ret;
char status[__PROC_STATUS_LEN]; char status[__PROC_STATUS_LEN];
FILE *f; FILE *f;
long unsigned int sigblk = 0; uint64_t sigblk = 0, one = 1;
size_t n = 0; size_t n = 0;
bool bret = false; bool bret = false;
char *line = NULL; char *line = NULL;
...@@ -1834,14 +1834,20 @@ bool task_blocking_signal(pid_t pid, int signal) ...@@ -1834,14 +1834,20 @@ bool task_blocking_signal(pid_t pid, int signal)
return bret; return bret;
while (getline(&line, &n, f) != -1) { while (getline(&line, &n, f) != -1) {
char *numstr;
if (strncmp(line, "SigBlk:", 7)) if (strncmp(line, "SigBlk:", 7))
continue; continue;
if (sscanf(line + 7, "%lx", &sigblk) != 1) numstr = lxc_trim_whitespace_in_place(line + 7);
ret = lxc_safe_uint64(numstr, &sigblk, 16);
if (ret < 0)
goto out; goto out;
break;
} }
if (sigblk & (1LU << (signal - 1))) if (sigblk & (one << (signal - 1)))
bret = true; bret = true;
out: out:
...@@ -1958,7 +1964,7 @@ int lxc_safe_ulong(const char *numstr, unsigned long *converted) ...@@ -1958,7 +1964,7 @@ int lxc_safe_ulong(const char *numstr, unsigned long *converted)
return 0; return 0;
} }
int lxc_safe_uint64(const char *numstr, uint64_t *converted) int lxc_safe_uint64(const char *numstr, uint64_t *converted, int base)
{ {
char *err = NULL; char *err = NULL;
uint64_t u; uint64_t u;
...@@ -1970,7 +1976,7 @@ int lxc_safe_uint64(const char *numstr, uint64_t *converted) ...@@ -1970,7 +1976,7 @@ int lxc_safe_uint64(const char *numstr, uint64_t *converted)
return -EINVAL; return -EINVAL;
errno = 0; errno = 0;
u = strtoull(numstr, &err, 0); u = strtoull(numstr, &err, base);
if (errno == ERANGE && u == ULLONG_MAX) if (errno == ERANGE && u == ULLONG_MAX)
return -ERANGE; return -ERANGE;
......
...@@ -523,7 +523,7 @@ extern int lxc_count_file_lines(const char *fn); ...@@ -523,7 +523,7 @@ extern int lxc_count_file_lines(const char *fn);
extern int lxc_preserve_ns(const int pid, const char *ns); extern int lxc_preserve_ns(const int pid, const char *ns);
/* Check whether a signal is blocked by a process. */ /* Check whether a signal is blocked by a process. */
extern bool task_blocking_signal(pid_t pid, int signal); extern bool task_blocks_signal(pid_t pid, int signal);
/* Helper functions to parse numbers. */ /* Helper functions to parse numbers. */
extern int lxc_safe_uint(const char *numstr, unsigned int *converted); extern int lxc_safe_uint(const char *numstr, unsigned int *converted);
...@@ -531,7 +531,7 @@ extern int lxc_safe_int(const char *numstr, int *converted); ...@@ -531,7 +531,7 @@ extern int lxc_safe_int(const char *numstr, int *converted);
extern int lxc_safe_long(const char *numstr, long int *converted); extern int lxc_safe_long(const char *numstr, long int *converted);
extern int lxc_safe_long_long(const char *numstr, long long int *converted); extern int lxc_safe_long_long(const char *numstr, long long int *converted);
extern int lxc_safe_ulong(const char *numstr, unsigned long *converted); extern int lxc_safe_ulong(const char *numstr, unsigned long *converted);
extern int lxc_safe_uint64(const char *numstr, uint64_t *converted); extern int lxc_safe_uint64(const char *numstr, uint64_t *converted, int base);
/* Handles B, kb, MB, GB. Detects overflows and reports -ERANGE. */ /* Handles B, kb, MB, GB. Detects overflows and reports -ERANGE. */
extern int parse_byte_size_string(const char *s, int64_t *converted); extern int parse_byte_size_string(const char *s, int64_t *converted);
......
...@@ -44,7 +44,8 @@ AM_CFLAGS=-DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \ ...@@ -44,7 +44,8 @@ AM_CFLAGS=-DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \
-I $(top_srcdir)/src/lxc \ -I $(top_srcdir)/src/lxc \
-I $(top_srcdir)/src/lxc/bdev \ -I $(top_srcdir)/src/lxc/bdev \
-I $(top_srcdir)/src/lxc/cgroups \ -I $(top_srcdir)/src/lxc/cgroups \
-I $(top_srcdir)/src/lxc/tools -I $(top_srcdir)/src/lxc/tools \
-pthread
if ENABLE_APPARMOR if ENABLE_APPARMOR
AM_CFLAGS += -DHAVE_APPARMOR AM_CFLAGS += -DHAVE_APPARMOR
......
...@@ -27,14 +27,16 @@ ...@@ -27,14 +27,16 @@
#include <fcntl.h> #include <fcntl.h>
#include <inttypes.h> #include <inttypes.h>
#include <limits.h> #include <limits.h>
#include <pthread.h>
#include <sched.h> #include <sched.h>
#include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h>
#include "lxctest.h" #include "lxctest.h"
#include "utils.h" #include "utils.h"
...@@ -507,6 +509,67 @@ void test_lxc_config_net_hwaddr(void) ...@@ -507,6 +509,67 @@ void test_lxc_config_net_hwaddr(void)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
void test_task_blocks_signal(void)
{
int ret;
pid_t pid;
pid = fork();
if (pid < 0)
_exit(EXIT_FAILURE);
if (pid == 0) {
int i;
sigset_t mask;
int signals[] = {SIGBUS, SIGILL, SIGSEGV,
SIGWINCH, SIGQUIT, SIGUSR1,
SIGUSR2, SIGRTMIN + 3, SIGRTMIN + 4};
sigemptyset(&mask);
for (i = 0; i < (sizeof(signals) / sizeof(signals[0])); i++) {
ret = sigaddset(&mask, signals[i]);
if (ret < 0)
_exit(EXIT_FAILURE);
}
ret = pthread_sigmask(SIG_BLOCK, &mask, NULL);
if (ret < 0) {
lxc_error("%s\n", "Failed to block signals");
_exit(EXIT_FAILURE);
}
for (i = 0; i < (sizeof(signals) / sizeof(signals[0])); i++) {
if (!task_blocks_signal(getpid(), signals[i])) {
lxc_error("Failed to detect blocked signal "
"(idx = %d, signal number = %d)\n",
i, signals[i]);
_exit(EXIT_FAILURE);
}
}
if (task_blocks_signal(getpid(), SIGKILL)) {
lxc_error("%s\n",
"Falsely detected SIGKILL as blocked signal");
_exit(EXIT_FAILURE);
}
if (task_blocks_signal(getpid(), SIGSTOP)) {
lxc_error("%s\n",
"Falsely detected SIGSTOP as blocked signal");
_exit(EXIT_FAILURE);
}
_exit(EXIT_SUCCESS);
}
ret = wait_for_pid(pid);
if (ret < 0)
_exit(EXIT_FAILURE);
return;
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
test_lxc_string_replace(); test_lxc_string_replace();
...@@ -518,6 +581,7 @@ int main(int argc, char *argv[]) ...@@ -518,6 +581,7 @@ int main(int argc, char *argv[])
test_lxc_safe_long(); test_lxc_safe_long();
test_parse_byte_size_string(); test_parse_byte_size_string();
test_lxc_config_net_hwaddr(); test_lxc_config_net_hwaddr();
test_task_blocks_signal();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment