mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-15 13:47:41 +00:00
conf: simplify tty handling
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
parent
448d7b0c0f
commit
885766f5d2
@ -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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
@ -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)
|
|||||||
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);
|
||||||
|
@ -137,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -214,8 +216,6 @@ 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;
|
||||||
unsigned int tty;
|
|
||||||
unsigned int pts;
|
|
||||||
bool is_execute;
|
bool is_execute;
|
||||||
int reboot;
|
int reboot;
|
||||||
signed long personality;
|
signed long personality;
|
||||||
@ -252,12 +252,13 @@ struct lxc_conf {
|
|||||||
|
|
||||||
struct lxc_list caps;
|
struct lxc_list caps;
|
||||||
struct lxc_list keepcaps;
|
struct lxc_list keepcaps;
|
||||||
struct lxc_tty_info ttys;
|
|
||||||
/* Comma-separated list of lxc.tty.max pty names. */
|
/* Comma-separated list of lxc.tty.max pty names. */
|
||||||
char *pty_names;
|
struct lxc_tty_info ttys;
|
||||||
|
|
||||||
|
unsigned int pts;
|
||||||
struct lxc_terminal console;
|
struct lxc_terminal console;
|
||||||
struct lxc_rootfs rootfs;
|
struct lxc_rootfs rootfs;
|
||||||
char *ttydir;
|
|
||||||
bool close_all_fds;
|
bool close_all_fds;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -1127,18 +1127,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2917,13 +2925,13 @@ static int get_config_pty_max(const char *key, char *retv, int inlen,
|
|||||||
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,
|
||||||
@ -3695,15 +3703,15 @@ static inline int clr_config_pty_max(const char *key, struct lxc_conf *c,
|
|||||||
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)
|
|||||||
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);
|
|||||||
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,
|
||||||
|
@ -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)
|
|||||||
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)
|
|||||||
"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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
|||||||
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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user