Unverified Commit 19462d43 by Serge Hallyn Committed by GitHub

Merge pull request #2193 from brauner/2018-02-27/naming_tweaks

tree-wide: introduce consistent and agnostic naming for ptys, ttys, and consoles
parents 7263b97f a44ae1a9
...@@ -26,7 +26,6 @@ noinst_HEADERS = \ ...@@ -26,7 +26,6 @@ noinst_HEADERS = \
conf.h \ conf.h \
confile.h \ confile.h \
confile_utils.h \ confile_utils.h \
console.h \
error.h \ error.h \
initutils.h \ initutils.h \
list.h \ list.h \
...@@ -37,6 +36,7 @@ noinst_HEADERS = \ ...@@ -37,6 +36,7 @@ noinst_HEADERS = \
namespace.h \ namespace.h \
start.h \ start.h \
state.h \ state.h \
terminal.h \
utils.h \ utils.h \
criu.h \ criu.h \
../tests/lxctest.h ../tests/lxctest.h
...@@ -100,7 +100,7 @@ liblxc_la_SOURCES = \ ...@@ -100,7 +100,7 @@ liblxc_la_SOURCES = \
start.c start.h \ start.c start.h \
execute.c \ execute.c \
monitor.c monitor.h \ monitor.c monitor.h \
console.c \ terminal.c \
freezer.c \ freezer.c \
error.h error.c \ error.h error.c \
parse.c parse.h \ parse.c parse.h \
......
...@@ -61,13 +61,13 @@ ...@@ -61,13 +61,13 @@
#include "conf.h" #include "conf.h"
#include "config.h" #include "config.h"
#include "confile.h" #include "confile.h"
#include "console.h"
#include "log.h" #include "log.h"
#include "lsm/lsm.h" #include "lsm/lsm.h"
#include "lxclock.h" #include "lxclock.h"
#include "lxcseccomp.h" #include "lxcseccomp.h"
#include "mainloop.h" #include "mainloop.h"
#include "namespace.h" #include "namespace.h"
#include "terminal.h"
#include "utils.h" #include "utils.h"
#if HAVE_SYS_PERSONALITY_H #if HAVE_SYS_PERSONALITY_H
...@@ -974,20 +974,20 @@ on_error: ...@@ -974,20 +974,20 @@ on_error:
rexit(EXIT_FAILURE); rexit(EXIT_FAILURE);
} }
static int lxc_attach_pty(struct lxc_conf *conf, struct lxc_console *pty) static int lxc_attach_pty(struct lxc_conf *conf, struct lxc_terminal *pty)
{ {
int ret; int ret;
lxc_pty_init(pty); lxc_terminal_init(pty);
ret = lxc_pty_create(pty); ret = lxc_terminal_create(pty);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to create pty"); SYSERROR("Failed to create pty");
return -1; return -1;
} }
/* Shift ttys to container. */ /* Shift ttys to container. */
ret = lxc_pty_map_ids(conf, pty); ret = lxc_terminal_map_ids(conf, pty);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to shift pty"); ERROR("Failed to shift pty");
goto on_error; goto on_error;
...@@ -996,12 +996,12 @@ static int lxc_attach_pty(struct lxc_conf *conf, struct lxc_console *pty) ...@@ -996,12 +996,12 @@ static int lxc_attach_pty(struct lxc_conf *conf, struct lxc_console *pty)
return 0; return 0;
on_error: on_error:
lxc_console_delete(pty); lxc_terminal_delete(pty);
lxc_pty_conf_free(pty); lxc_terminal_conf_free(pty);
return -1; return -1;
} }
static int lxc_attach_pty_mainloop_init(struct lxc_console *pty, static int lxc_attach_pty_mainloop_init(struct lxc_terminal *pty,
struct lxc_epoll_descr *descr) struct lxc_epoll_descr *descr)
{ {
int ret; int ret;
...@@ -1012,7 +1012,7 @@ static int lxc_attach_pty_mainloop_init(struct lxc_console *pty, ...@@ -1012,7 +1012,7 @@ static int lxc_attach_pty_mainloop_init(struct lxc_console *pty,
return -1; return -1;
} }
ret = lxc_console_mainloop_add(descr, pty); ret = lxc_terminal_mainloop_add(descr, pty);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to add handlers to mainloop"); ERROR("Failed to add handlers to mainloop");
lxc_mainloop_close(descr); lxc_mainloop_close(descr);
...@@ -1022,7 +1022,7 @@ static int lxc_attach_pty_mainloop_init(struct lxc_console *pty, ...@@ -1022,7 +1022,7 @@ static int lxc_attach_pty_mainloop_init(struct lxc_console *pty,
return 0; return 0;
} }
static inline void lxc_attach_pty_close_master(struct lxc_console *pty) static inline void lxc_attach_pty_close_master(struct lxc_terminal *pty)
{ {
if (pty->master < 0) if (pty->master < 0)
return; return;
...@@ -1031,7 +1031,7 @@ static inline void lxc_attach_pty_close_master(struct lxc_console *pty) ...@@ -1031,7 +1031,7 @@ static inline void lxc_attach_pty_close_master(struct lxc_console *pty)
pty->master = -EBADF; pty->master = -EBADF;
} }
static inline void lxc_attach_pty_close_slave(struct lxc_console *pty) static inline void lxc_attach_pty_close_slave(struct lxc_terminal *pty)
{ {
if (pty->slave < 0) if (pty->slave < 0)
return; return;
...@@ -1040,7 +1040,7 @@ static inline void lxc_attach_pty_close_slave(struct lxc_console *pty) ...@@ -1040,7 +1040,7 @@ static inline void lxc_attach_pty_close_slave(struct lxc_console *pty)
pty->slave = -EBADF; pty->slave = -EBADF;
} }
static inline void lxc_attach_pty_close_peer(struct lxc_console *pty) static inline void lxc_attach_pty_close_peer(struct lxc_terminal *pty)
{ {
if (pty->peer < 0) if (pty->peer < 0)
return; return;
...@@ -1049,7 +1049,7 @@ static inline void lxc_attach_pty_close_peer(struct lxc_console *pty) ...@@ -1049,7 +1049,7 @@ static inline void lxc_attach_pty_close_peer(struct lxc_console *pty)
pty->peer = -EBADF; pty->peer = -EBADF;
} }
static inline void lxc_attach_pty_close_log(struct lxc_console *pty) static inline void lxc_attach_pty_close_log(struct lxc_terminal *pty)
{ {
if (pty->log_fd < 0) if (pty->log_fd < 0)
return; return;
...@@ -1068,7 +1068,7 @@ int lxc_attach(const char *name, const char *lxcpath, ...@@ -1068,7 +1068,7 @@ int lxc_attach(const char *name, const char *lxcpath,
signed long personality; signed long personality;
pid_t attached_pid, init_pid, pid; pid_t attached_pid, init_pid, pid;
struct lxc_proc_context_info *init_ctx; struct lxc_proc_context_info *init_ctx;
struct lxc_console pty; struct lxc_terminal pty;
struct lxc_conf *conf; struct lxc_conf *conf;
struct attach_clone_payload payload = {0}; struct attach_clone_payload payload = {0};
...@@ -1198,7 +1198,7 @@ int lxc_attach(const char *name, const char *lxcpath, ...@@ -1198,7 +1198,7 @@ int lxc_attach(const char *name, const char *lxcpath,
pty.log_fd = options->log_fd; pty.log_fd = options->log_fd;
} else { } else {
lxc_pty_init(&pty); lxc_terminal_init(&pty);
} }
/* Create a socket pair for IPC communication; set SOCK_CLOEXEC in order /* Create a socket pair for IPC communication; set SOCK_CLOEXEC in order
...@@ -1386,8 +1386,8 @@ int lxc_attach(const char *name, const char *lxcpath, ...@@ -1386,8 +1386,8 @@ int lxc_attach(const char *name, const char *lxcpath,
(void)wait_for_pid(to_cleanup_pid); (void)wait_for_pid(to_cleanup_pid);
if (options->attach_flags & LXC_ATTACH_ALLOCATE_PTY) { if (options->attach_flags & LXC_ATTACH_ALLOCATE_PTY) {
lxc_console_delete(&pty); lxc_terminal_delete(&pty);
lxc_pty_conf_free(&pty); lxc_terminal_conf_free(&pty);
} }
lxc_proc_put_context_info(init_ctx); lxc_proc_put_context_info(init_ctx);
return ret_parent; return ret_parent;
......
...@@ -843,13 +843,11 @@ static bool all_controllers_found(void) ...@@ -843,13 +843,11 @@ static bool all_controllers_found(void)
if (!cgroup_use) if (!cgroup_use)
return true; return true;
for (p = strtok_r(cgroup_use, ",", &saveptr); p; for (; (p = strtok_r(cgroup_use, ",", &saveptr)); cgroup_use = NULL)
p = strtok_r(NULL, ",", &saveptr)) {
if (!controller_found(hlist, p)) { if (!controller_found(hlist, p)) {
CGFSNG_DEBUG("No %s controller mountpoint found\n", p); CGFSNG_DEBUG("No %s controller mountpoint found\n", p);
return false; return false;
} }
}
return true; return true;
} }
......
...@@ -42,13 +42,13 @@ ...@@ -42,13 +42,13 @@
#include "commands_utils.h" #include "commands_utils.h"
#include "conf.h" #include "conf.h"
#include "confile.h" #include "confile.h"
#include "console.h"
#include "log.h" #include "log.h"
#include "lxc.h" #include "lxc.h"
#include "lxclock.h" #include "lxclock.h"
#include "mainloop.h" #include "mainloop.h"
#include "monitor.h" #include "monitor.h"
#include "start.h" #include "start.h"
#include "terminal.h"
#include "utils.h" #include "utils.h"
/* /*
...@@ -82,7 +82,7 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd) ...@@ -82,7 +82,7 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd)
{ {
static const char *const cmdname[LXC_CMD_MAX] = { static const char *const cmdname[LXC_CMD_MAX] = {
[LXC_CMD_CONSOLE] = "console", [LXC_CMD_CONSOLE] = "console",
[LXC_CMD_CONSOLE_WINCH] = "console_winch", [LXC_CMD_TERMINAL_WINCH] = "terminal_winch",
[LXC_CMD_STOP] = "stop", [LXC_CMD_STOP] = "stop",
[LXC_CMD_GET_STATE] = "get_state", [LXC_CMD_GET_STATE] = "get_state",
[LXC_CMD_GET_INIT_PID] = "get_init_pid", [LXC_CMD_GET_INIT_PID] = "get_init_pid",
...@@ -659,18 +659,18 @@ static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req, ...@@ -659,18 +659,18 @@ static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req,
} }
/* /*
* lxc_cmd_console_winch: To process as if a SIGWINCH were received * lxc_cmd_terminal_winch: To process as if a SIGWINCH were received
* *
* @name : name of container to connect to * @name : name of container to connect to
* @lxcpath : the lxcpath in which the container is running * @lxcpath : the lxcpath in which the container is running
* *
* Returns 0 on success, < 0 on failure * Returns 0 on success, < 0 on failure
*/ */
int lxc_cmd_console_winch(const char *name, const char *lxcpath) int lxc_cmd_terminal_winch(const char *name, const char *lxcpath)
{ {
int ret, stopped; int ret, stopped;
struct lxc_cmd_rr cmd = { struct lxc_cmd_rr cmd = {
.req = { .cmd = LXC_CMD_CONSOLE_WINCH }, .req = { .cmd = LXC_CMD_TERMINAL_WINCH },
}; };
ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL); ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
...@@ -680,12 +680,12 @@ int lxc_cmd_console_winch(const char *name, const char *lxcpath) ...@@ -680,12 +680,12 @@ int lxc_cmd_console_winch(const char *name, const char *lxcpath)
return 0; return 0;
} }
static int lxc_cmd_console_winch_callback(int fd, struct lxc_cmd_req *req, static int lxc_cmd_terminal_winch_callback(int fd, struct lxc_cmd_req *req,
struct lxc_handler *handler) struct lxc_handler *handler)
{ {
struct lxc_cmd_rsp rsp = { .data = 0 }; struct lxc_cmd_rsp rsp = { .data = 0 };
lxc_console_sigwinch(SIGWINCH); lxc_terminal_sigwinch(SIGWINCH);
return lxc_cmd_rsp_send(fd, &rsp); return lxc_cmd_rsp_send(fd, &rsp);
} }
...@@ -748,7 +748,7 @@ static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req, ...@@ -748,7 +748,7 @@ static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
struct lxc_cmd_rsp rsp; struct lxc_cmd_rsp rsp;
int ttynum = PTR_TO_INT(req->data); int ttynum = PTR_TO_INT(req->data);
masterfd = lxc_console_allocate(handler->conf, fd, &ttynum); masterfd = lxc_terminal_allocate(handler->conf, fd, &ttynum);
if (masterfd < 0) if (masterfd < 0)
goto out_close; goto out_close;
...@@ -757,7 +757,7 @@ static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req, ...@@ -757,7 +757,7 @@ static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
ret = lxc_abstract_unix_send_fds(fd, &masterfd, 1, &rsp, sizeof(rsp)); ret = lxc_abstract_unix_send_fds(fd, &masterfd, 1, &rsp, sizeof(rsp));
if (ret < 0) { if (ret < 0) {
ERROR("Failed to send tty to client"); ERROR("Failed to send tty to client");
lxc_console_free(handler->conf, fd); lxc_terminal_free(handler->conf, fd);
goto out_close; goto out_close;
} }
...@@ -991,8 +991,7 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req, ...@@ -991,8 +991,7 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
rsp.ret = 0; rsp.ret = 0;
if (log->clear) if (log->clear)
/* clear the ringbuffer */ lxc_ringbuf_clear(buf); /* clear the ringbuffer */
lxc_ringbuf_clear(buf);
else if (rsp.datalen > 0) else if (rsp.datalen > 0)
lxc_ringbuf_move_read_addr(buf, rsp.datalen); lxc_ringbuf_move_read_addr(buf, rsp.datalen);
...@@ -1052,7 +1051,7 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, ...@@ -1052,7 +1051,7 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
callback cb[LXC_CMD_MAX] = { callback cb[LXC_CMD_MAX] = {
[LXC_CMD_CONSOLE] = lxc_cmd_console_callback, [LXC_CMD_CONSOLE] = lxc_cmd_console_callback,
[LXC_CMD_CONSOLE_WINCH] = lxc_cmd_console_winch_callback, [LXC_CMD_TERMINAL_WINCH] = lxc_cmd_terminal_winch_callback,
[LXC_CMD_STOP] = lxc_cmd_stop_callback, [LXC_CMD_STOP] = lxc_cmd_stop_callback,
[LXC_CMD_GET_STATE] = lxc_cmd_get_state_callback, [LXC_CMD_GET_STATE] = lxc_cmd_get_state_callback,
[LXC_CMD_GET_INIT_PID] = lxc_cmd_get_init_pid_callback, [LXC_CMD_GET_INIT_PID] = lxc_cmd_get_init_pid_callback,
...@@ -1080,7 +1079,7 @@ static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler, ...@@ -1080,7 +1079,7 @@ static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler,
struct lxc_state_client *client; struct lxc_state_client *client;
struct lxc_list *cur, *next; struct lxc_list *cur, *next;
lxc_console_free(handler->conf, fd); lxc_terminal_free(handler->conf, fd);
lxc_mainloop_del_handler(descr, fd); lxc_mainloop_del_handler(descr, fd);
if (cmd != LXC_CMD_ADD_STATE_CLIENT) { if (cmd != LXC_CMD_ADD_STATE_CLIENT) {
close(fd); close(fd);
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
typedef enum { typedef enum {
LXC_CMD_CONSOLE, LXC_CMD_CONSOLE,
LXC_CMD_CONSOLE_WINCH, LXC_CMD_TERMINAL_WINCH,
LXC_CMD_STOP, LXC_CMD_STOP,
LXC_CMD_GET_STATE, LXC_CMD_GET_STATE,
LXC_CMD_GET_INIT_PID, LXC_CMD_GET_INIT_PID,
...@@ -84,7 +84,7 @@ struct lxc_cmd_console_log { ...@@ -84,7 +84,7 @@ struct lxc_cmd_console_log {
}; };
extern int lxc_cmd_console_winch(const char *name, const char *lxcpath); extern int lxc_cmd_terminal_winch(const char *name, const char *lxcpath);
extern int lxc_cmd_console(const char *name, int *ttynum, int *fd, extern int lxc_cmd_console(const char *name, int *ttynum, int *fd,
const char *lxcpath); const char *lxcpath);
/* /*
......
...@@ -73,9 +73,9 @@ ...@@ -73,9 +73,9 @@
#include "cgroup.h" #include "cgroup.h"
#include "conf.h" #include "conf.h"
#include "confile_utils.h" #include "confile_utils.h"
#include "console.h"
#include "error.h" #include "error.h"
#include "log.h" #include "log.h"
#include "lsm/lsm.h"
#include "lxclock.h" #include "lxclock.h"
#include "lxcseccomp.h" #include "lxcseccomp.h"
#include "namespace.h" #include "namespace.h"
...@@ -85,8 +85,8 @@ ...@@ -85,8 +85,8 @@
#include "storage.h" #include "storage.h"
#include "storage/aufs.h" #include "storage/aufs.h"
#include "storage/overlay.h" #include "storage/overlay.h"
#include "terminal.h"
#include "utils.h" #include "utils.h"
#include "lsm/lsm.h"
#if HAVE_LIBCAP #if HAVE_LIBCAP
#include <sys/capability.h> #include <sys/capability.h>
...@@ -840,15 +840,15 @@ static bool append_ptyname(char **pp, char *name) ...@@ -840,15 +840,15 @@ static bool append_ptyname(char **pp, char *name)
static int lxc_setup_ttys(struct lxc_conf *conf) static int lxc_setup_ttys(struct lxc_conf *conf)
{ {
int i, ret; int i, ret;
const struct lxc_tty_info *tty_info = &conf->tty_info; const struct lxc_tty_info *ttys = &conf->ttys;
char *ttydir = conf->ttydir; char *ttydir = conf->ttydir;
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 < tty_info->nbtty; i++) { for (i = 0; i < ttys->nbtty; i++) {
struct lxc_pty_info *pty_info = &tty_info->pty_info[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);
if (ret < 0 || (size_t)ret >= sizeof(path)) if (ret < 0 || (size_t)ret >= sizeof(path))
...@@ -875,13 +875,13 @@ static int lxc_setup_ttys(struct lxc_conf *conf) ...@@ -875,13 +875,13 @@ static int lxc_setup_ttys(struct lxc_conf *conf)
return -1; return -1;
} }
ret = mount(pty_info->name, lxcpath, "none", MS_BIND, 0); ret = mount(tty->name, lxcpath, "none", MS_BIND, 0);
if (ret < 0) { if (ret < 0) {
WARN("Failed to bind mount \"%s\" onto \"%s\"", WARN("Failed to bind mount \"%s\" onto \"%s\"",
pty_info->name, path); tty->name, path);
continue; continue;
} }
DEBUG("bind mounted \"%s\" onto \"%s\"", pty_info->name, DEBUG("bind mounted \"%s\" onto \"%s\"", tty->name,
path); path);
ret = snprintf(lxcpath, sizeof(lxcpath), "%s/tty%d", ret = snprintf(lxcpath, sizeof(lxcpath), "%s/tty%d",
...@@ -910,99 +910,97 @@ static int lxc_setup_ttys(struct lxc_conf *conf) ...@@ -910,99 +910,97 @@ static int lxc_setup_ttys(struct lxc_conf *conf)
} }
} }
ret = mount(pty_info->name, path, "none", MS_BIND, 0); ret = mount(tty->name, path, "none", MS_BIND, 0);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to mount '%s'->'%s'", pty_info->name, path); SYSERROR("Failed to mount '%s'->'%s'", tty->name, path);
continue; continue;
} }
DEBUG("Bind mounted \"%s\" onto \"%s\"", pty_info->name, DEBUG("Bind mounted \"%s\" onto \"%s\"", tty->name,
path); path);
} }
if (!append_ptyname(&conf->pty_names, pty_info->name)) { if (!append_ptyname(&conf->pty_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)", tty_info->nbtty); INFO("Finished setting up %d /dev/tty<N> device(s)", ttys->nbtty);
return 0; return 0;
} }
int lxc_allocate_ttys(const char *name, struct lxc_conf *conf) int lxc_allocate_ttys(const char *name, struct lxc_conf *conf)
{ {
struct lxc_tty_info *tty_info = &conf->tty_info; struct lxc_tty_info *ttys = &conf->ttys;
int i, ret; int i, ret;
/* no tty in the configuration */ /* no tty in the configuration */
if (!conf->tty) if (!conf->tty)
return 0; return 0;
tty_info->pty_info = malloc(sizeof(*tty_info->pty_info) * conf->tty); ttys->tty = malloc(sizeof(*ttys->tty) * conf->tty);
if (!tty_info->pty_info) { if (!ttys->tty)
SYSERROR("failed to allocate struct *pty_info");
return -ENOMEM; return -ENOMEM;
}
for (i = 0; i < conf->tty; i++) { for (i = 0; i < conf->tty; i++) {
struct lxc_pty_info *pty_info = &tty_info->pty_info[i]; struct lxc_terminal_info *tty = &ttys->tty[i];
ret = openpty(&pty_info->master, &pty_info->slave, ret = openpty(&tty->master, &tty->slave,
pty_info->name, NULL, NULL); tty->name, NULL, NULL);
if (ret) { if (ret) {
SYSERROR("failed to create pty device number %d", i); SYSERROR("failed to create pty device number %d", i);
tty_info->nbtty = i; ttys->nbtty = i;
lxc_delete_tty(tty_info); lxc_delete_tty(ttys);
return -ENOTTY; return -ENOTTY;
} }
DEBUG("allocated pty \"%s\" with master fd %d and slave fd %d", DEBUG("allocated pty \"%s\" with master fd %d and slave fd %d",
pty_info->name, pty_info->master, pty_info->slave); tty->name, tty->master, tty->slave);
/* Prevent leaking the file descriptors to the container */ /* Prevent leaking the file descriptors to the container */
ret = fcntl(pty_info->master, F_SETFD, FD_CLOEXEC); ret = fcntl(tty->master, F_SETFD, FD_CLOEXEC);
if (ret < 0) if (ret < 0)
WARN("failed to set FD_CLOEXEC flag on master fd %d of " WARN("failed to set FD_CLOEXEC flag on master fd %d of "
"pty device \"%s\": %s", "pty device \"%s\": %s",
pty_info->master, pty_info->name, strerror(errno)); tty->master, tty->name, strerror(errno));
ret = fcntl(pty_info->slave, F_SETFD, FD_CLOEXEC); ret = fcntl(tty->slave, F_SETFD, FD_CLOEXEC);
if (ret < 0) if (ret < 0)
WARN("failed to set FD_CLOEXEC flag on slave fd %d of " WARN("failed to set FD_CLOEXEC flag on slave fd %d of "
"pty device \"%s\": %s", "pty device \"%s\": %s",
pty_info->slave, pty_info->name, strerror(errno)); tty->slave, tty->name, strerror(errno));
pty_info->busy = 0; tty->busy = 0;
} }
tty_info->nbtty = conf->tty; ttys->nbtty = conf->tty;
INFO("finished allocating %d pts devices", conf->tty); INFO("finished allocating %d pts devices", conf->tty);
return 0; return 0;
} }
void lxc_delete_tty(struct lxc_tty_info *tty_info) void lxc_delete_tty(struct lxc_tty_info *ttys)
{ {
int i; int i;
for (i = 0; i < tty_info->nbtty; i++) { for (i = 0; i < ttys->nbtty; i++) {
struct lxc_pty_info *pty_info = &tty_info->pty_info[i]; struct lxc_terminal_info *tty = &ttys->tty[i];
close(pty_info->master); close(tty->master);
close(pty_info->slave); close(tty->slave);
} }
free(tty_info->pty_info); free(ttys->tty);
tty_info->pty_info = NULL; ttys->tty = NULL;
tty_info->nbtty = 0; 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)
{ {
int i; int i;
struct lxc_conf *conf = handler->conf; struct lxc_conf *conf = handler->conf;
struct lxc_tty_info *tty_info = &conf->tty_info; struct lxc_tty_info *ttys = &conf->ttys;
int sock = handler->data_sock[0]; int sock = handler->data_sock[0];
int ret = -1; int ret = -1;
...@@ -1011,17 +1009,17 @@ static int lxc_send_ttys_to_parent(struct lxc_handler *handler) ...@@ -1011,17 +1009,17 @@ static int lxc_send_ttys_to_parent(struct lxc_handler *handler)
for (i = 0; i < conf->tty; i++) { for (i = 0; i < conf->tty; i++) {
int ttyfds[2]; int ttyfds[2];
struct lxc_pty_info *pty_info = &tty_info->pty_info[i]; struct lxc_terminal_info *tty = &ttys->tty[i];
ttyfds[0] = pty_info->master; ttyfds[0] = tty->master;
ttyfds[1] = pty_info->slave; ttyfds[1] = tty->slave;
ret = lxc_abstract_unix_send_fds(sock, ttyfds, 2, NULL, 0); ret = lxc_abstract_unix_send_fds(sock, ttyfds, 2, NULL, 0);
if (ret < 0) if (ret < 0)
break; break;
TRACE("Send pty \"%s\" with master fd %d and slave fd %d to " TRACE("Send pty \"%s\" with master fd %d and slave fd %d to "
"parent", pty_info->name, pty_info->master, pty_info->slave); "parent", tty->name, tty->master, tty->slave);
} }
if (ret < 0) if (ret < 0)
...@@ -1067,7 +1065,7 @@ static int lxc_create_ttys(struct lxc_handler *handler) ...@@ -1067,7 +1065,7 @@ static int lxc_create_ttys(struct lxc_handler *handler)
ret = 0; ret = 0;
on_error: on_error:
lxc_delete_tty(&conf->tty_info); lxc_delete_tty(&conf->ttys);
return ret; return ret;
} }
...@@ -1578,7 +1576,7 @@ static int setup_personality(int persona) ...@@ -1578,7 +1576,7 @@ static int setup_personality(int persona)
} }
static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs, static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs,
const struct lxc_console *console) const struct lxc_terminal *console)
{ {
char path[MAXPATHLEN]; char path[MAXPATHLEN];
int ret, fd; int ret, fd;
...@@ -1634,7 +1632,7 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs, ...@@ -1634,7 +1632,7 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs,
} }
static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs, static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs,
const struct lxc_console *console, const struct lxc_terminal *console,
char *ttydir) char *ttydir)
{ {
int ret, fd; int ret, fd;
...@@ -1720,7 +1718,7 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs, ...@@ -1720,7 +1718,7 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs,
} }
static int lxc_setup_console(const struct lxc_rootfs *rootfs, static int lxc_setup_console(const struct lxc_rootfs *rootfs,
const struct lxc_console *console, char *ttydir) const struct lxc_terminal *console, char *ttydir)
{ {
if (!ttydir) if (!ttydir)
...@@ -2615,9 +2613,9 @@ struct lxc_conf *lxc_conf_init(void) ...@@ -2615,9 +2613,9 @@ struct lxc_conf *lxc_conf_init(void)
new->console.log_size = 0; new->console.log_size = 0;
new->console.path = NULL; new->console.path = NULL;
new->console.peer = -1; new->console.peer = -1;
new->console.peerpty.busy = -1; new->console.proxy.busy = -1;
new->console.peerpty.master = -1; new->console.proxy.master = -1;
new->console.peerpty.slave = -1; new->console.proxy.slave = -1;
new->console.master = -1; new->console.master = -1;
new->console.slave = -1; new->console.slave = -1;
new->console.name[0] = '\0'; new->console.name[0] = '\0';
...@@ -3786,7 +3784,7 @@ void lxc_conf_free(struct lxc_conf *conf) ...@@ -3786,7 +3784,7 @@ void lxc_conf_free(struct lxc_conf *conf)
return; return;
if (current_config == conf) if (current_config == conf)
current_config = NULL; current_config = NULL;
lxc_pty_conf_free(&conf->console); lxc_terminal_conf_free(&conf->console);
free(conf->rootfs.mount); free(conf->rootfs.mount);
free(conf->rootfs.bdev_type); free(conf->rootfs.bdev_type);
free(conf->rootfs.options); free(conf->rootfs.options);
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "list.h" #include "list.h"
#include "ringbuf.h" #include "ringbuf.h"
#include "start.h" /* for lxc_handler */ #include "start.h" /* for lxc_handler */
#include "terminal.h"
#if HAVE_SCMP_FILTER_CTX #if HAVE_SCMP_FILTER_CTX
typedef void * scmp_filter_ctx; typedef void * scmp_filter_ctx;
...@@ -133,73 +134,16 @@ struct id_map { ...@@ -133,73 +134,16 @@ struct id_map {
unsigned long hostid, nsid, range; unsigned long hostid, nsid, range;
}; };
/* /* Defines the number of tty configured and contains the
* Defines a structure containing a pty information for
* virtualizing a tty
* @name : the path name of the slave pty side
* @master : the file descriptor of the master
* @slave : the file descriptor of the slave
*/
struct lxc_pty_info {
char name[MAXPATHLEN];
int master;
int slave;
int busy;
};
/*
* Defines the number of tty configured and contains the
* instantiated ptys * instantiated ptys
* @nbtty = number of configured ttys * @nbtty = number of configured ttys
*/ */
struct lxc_tty_info { struct lxc_tty_info {
int nbtty; int nbtty;
struct lxc_pty_info *pty_info; struct lxc_terminal_info *tty;
};
struct lxc_tty_state;
/*
* Defines the structure to store the console information
* @peer : the file descriptor put/get console traffic
* @name : the file name of the slave pty
*/
struct lxc_console {
int slave;
int master;
int peer;
struct lxc_pty_info peerpty;
struct lxc_epoll_descr *descr;
char *path;
char name[MAXPATHLEN];
struct termios *tios;
struct lxc_tty_state *tty_state;
struct /* lxc_console_log */ {
/* size of the log file */
uint64_t log_size;
/* path to the log file */
char *log_path;
/* fd to the log file */
int log_fd;
/* whether the log file will be rotated */
unsigned int log_rotate;
};
struct /* lxc_console_ringbuf */ {
/* size of the ringbuffer */
uint64_t buffer_size;
/* the in-memory ringbuffer */
struct lxc_ringbuf ringbuf;
};
}; };
/* /* Defines a structure to store the rootfs location, the
* Defines a structure to store the rootfs location, the
* optionals pivot_root, rootfs mount paths * optionals pivot_root, rootfs mount paths
* @path : the rootfs source (directory or device) * @path : the rootfs source (directory or device)
* @mount : where it is mounted * @mount : where it is mounted
...@@ -256,7 +200,7 @@ enum { ...@@ -256,7 +200,7 @@ enum {
* @fstab : path to a fstab file format * @fstab : path to a fstab file format
* @caps : list of the capabilities to drop * @caps : list of the capabilities to drop
* @keepcaps : list of the capabilities to keep * @keepcaps : list of the capabilities to keep
* @tty_info : tty data * @ttys : tty data
* @console : console data * @console : console data
* @ttydir : directory (under /dev) in which to create console and ttys * @ttydir : directory (under /dev) in which to create console and ttys
* @lsm_aa_profile : apparmor profile to switch to or NULL * @lsm_aa_profile : apparmor profile to switch to or NULL
...@@ -311,10 +255,10 @@ struct lxc_conf { ...@@ -311,10 +255,10 @@ struct lxc_conf {
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;
struct lxc_tty_info tty_info; 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; char *pty_names;
struct lxc_console console; struct lxc_terminal console;
struct lxc_rootfs rootfs; struct lxc_rootfs rootfs;
char *ttydir; char *ttydir;
int close_all_fds; int close_all_fds;
...@@ -440,7 +384,7 @@ extern void lxc_conf_free(struct lxc_conf *conf); ...@@ -440,7 +384,7 @@ extern void lxc_conf_free(struct lxc_conf *conf);
extern int pin_rootfs(const char *rootfs); extern int pin_rootfs(const char *rootfs);
extern int lxc_map_ids(struct lxc_list *idmap, pid_t pid); extern int lxc_map_ids(struct lxc_list *idmap, pid_t pid);
extern int lxc_create_tty(const char *name, struct lxc_conf *conf); extern int lxc_create_tty(const char *name, struct lxc_conf *conf);
extern void lxc_delete_tty(struct lxc_tty_info *tty_info); extern void lxc_delete_tty(struct lxc_tty_info *ttys);
extern int lxc_clear_config_caps(struct lxc_conf *c); extern int lxc_clear_config_caps(struct lxc_conf *c);
extern int lxc_clear_config_keepcaps(struct lxc_conf *c); extern int lxc_clear_config_keepcaps(struct lxc_conf *c);
extern int lxc_clear_cgroups(struct lxc_conf *c, const char *key, int version); extern int lxc_clear_cgroups(struct lxc_conf *c, const char *key, int version);
......
...@@ -176,7 +176,7 @@ static void exec_criu(struct criu_opts *opts) ...@@ -176,7 +176,7 @@ static void exec_criu(struct criu_opts *opts)
FILE *mnts; FILE *mnts;
struct mntent mntent; struct mntent mntent;
char buf[4096], tty_info[32]; char buf[4096], ttys[32];
size_t pos; size_t pos;
/* If we are currently in a cgroup /foo/bar, and the container is in a /* If we are currently in a cgroup /foo/bar, and the container is in a
...@@ -233,12 +233,12 @@ static void exec_criu(struct criu_opts *opts) ...@@ -233,12 +233,12 @@ static void exec_criu(struct criu_opts *opts)
*/ */
static_args += 6; static_args += 6;
tty_info[0] = 0; ttys[0] = 0;
if (load_tty_major_minor(opts->user->directory, tty_info, sizeof(tty_info))) if (load_tty_major_minor(opts->user->directory, ttys, sizeof(ttys)))
return; return;
/* --inherit-fd fd[%d]:tty[%s] */ /* --inherit-fd fd[%d]:tty[%s] */
if (tty_info[0]) if (ttys[0])
static_args += 2; static_args += 2;
} else { } else {
return; return;
...@@ -493,13 +493,13 @@ static void exec_criu(struct criu_opts *opts) ...@@ -493,13 +493,13 @@ static void exec_criu(struct criu_opts *opts)
DECLARE_ARG("--restore-detached"); DECLARE_ARG("--restore-detached");
DECLARE_ARG("--restore-sibling"); DECLARE_ARG("--restore-sibling");
if (tty_info[0]) { if (ttys[0]) {
if (opts->console_fd < 0) { if (opts->console_fd < 0) {
ERROR("lxc.console.path configured on source host but not target"); ERROR("lxc.console.path configured on source host but not target");
goto err; goto err;
} }
ret = snprintf(buf, sizeof(buf), "fd[%d]:%s", opts->console_fd, tty_info); ret = snprintf(buf, sizeof(buf), "fd[%d]:%s", opts->console_fd, ttys);
if (ret < 0 || ret >= sizeof(buf)) if (ret < 0 || ret >= sizeof(buf))
goto err; goto err;
......
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
#include "commands_utils.h" #include "commands_utils.h"
#include "confile.h" #include "confile.h"
#include "confile_utils.h" #include "confile_utils.h"
#include "console.h"
#include "criu.h" #include "criu.h"
#include "error.h" #include "error.h"
#include "initutils.h" #include "initutils.h"
...@@ -66,6 +65,7 @@ ...@@ -66,6 +65,7 @@
#include "storage/btrfs.h" #include "storage/btrfs.h"
#include "storage/overlay.h" #include "storage/overlay.h"
#include "sync.h" #include "sync.h"
#include "terminal.h"
#include "utils.h" #include "utils.h"
#include "version.h" #include "version.h"
...@@ -526,7 +526,7 @@ static int do_lxcapi_console_getfd(struct lxc_container *c, int *ttynum, int *ma ...@@ -526,7 +526,7 @@ static int do_lxcapi_console_getfd(struct lxc_container *c, int *ttynum, int *ma
if (!c) if (!c)
return -1; return -1;
return lxc_console_getfd(c, ttynum, masterfd); return lxc_terminal_getfd(c, ttynum, masterfd);
} }
WRAP_API_2(int, lxcapi_console_getfd, int *, int *) WRAP_API_2(int, lxcapi_console_getfd, int *, int *)
......
...@@ -71,9 +71,9 @@ ...@@ -71,9 +71,9 @@
#include "commands_utils.h" #include "commands_utils.h"
#include "conf.h" #include "conf.h"
#include "confile_utils.h" #include "confile_utils.h"
#include "console.h"
#include "error.h" #include "error.h"
#include "list.h" #include "list.h"
#include "lsm/lsm.h"
#include "log.h" #include "log.h"
#include "lxccontainer.h" #include "lxccontainer.h"
#include "lxclock.h" #include "lxclock.h"
...@@ -83,11 +83,11 @@ ...@@ -83,11 +83,11 @@
#include "namespace.h" #include "namespace.h"
#include "network.h" #include "network.h"
#include "start.h" #include "start.h"
#include "sync.h"
#include "utils.h"
#include "lsm/lsm.h"
#include "storage/storage.h" #include "storage/storage.h"
#include "storage/storage_utils.h" #include "storage/storage_utils.h"
#include "sync.h"
#include "terminal.h"
#include "utils.h"
lxc_log_define(lxc_start, lxc); lxc_log_define(lxc_start, lxc);
...@@ -529,15 +529,15 @@ int lxc_poll(const char *name, struct lxc_handler *handler) ...@@ -529,15 +529,15 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
} }
if (has_console) { if (has_console) {
struct lxc_console *console = &handler->conf->console; struct lxc_terminal *console = &handler->conf->console;
ret = lxc_console_mainloop_add(&descr, console); ret = lxc_terminal_mainloop_add(&descr, console);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to add console handlers to mainloop"); ERROR("Failed to add console handlers to mainloop");
goto out_mainloop_console; goto out_mainloop_console;
} }
ret = lxc_console_mainloop_add(&descr_console, console); ret = lxc_terminal_mainloop_add(&descr_console, console);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to add console handlers to console mainloop"); ERROR("Failed to add console handlers to console mainloop");
goto out_mainloop_console; goto out_mainloop_console;
...@@ -804,14 +804,14 @@ int lxc_init(const char *name, struct lxc_handler *handler) ...@@ -804,14 +804,14 @@ int lxc_init(const char *name, struct lxc_handler *handler)
TRACE("Set up signal fd"); TRACE("Set up signal fd");
/* Do this after setting up signals since it might unblock SIGWINCH. */ /* Do this after setting up signals since it might unblock SIGWINCH. */
ret = lxc_console_create(conf); ret = lxc_terminal_setup(conf);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to create console"); ERROR("Failed to create console");
goto out_restore_sigmask; goto out_restore_sigmask;
} }
TRACE("Created console"); TRACE("Created console");
ret = lxc_pty_map_ids(conf, &conf->console); ret = lxc_terminal_map_ids(conf, &conf->console);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to chown console"); ERROR("Failed to chown console");
goto out_restore_sigmask; goto out_restore_sigmask;
...@@ -824,7 +824,7 @@ int lxc_init(const char *name, struct lxc_handler *handler) ...@@ -824,7 +824,7 @@ int lxc_init(const char *name, struct lxc_handler *handler)
out_restore_sigmask: out_restore_sigmask:
sigprocmask(SIG_SETMASK, &handler->oldmask, NULL); sigprocmask(SIG_SETMASK, &handler->oldmask, NULL);
out_delete_tty: out_delete_tty:
lxc_delete_tty(&conf->tty_info); lxc_delete_tty(&conf->ttys);
out_aborting: out_aborting:
lxc_set_state(name, handler, ABORTING); lxc_set_state(name, handler, ABORTING);
out_close_maincmd_fd: out_close_maincmd_fd:
...@@ -950,8 +950,8 @@ void lxc_fini(const char *name, struct lxc_handler *handler) ...@@ -950,8 +950,8 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
if (ret < 0) if (ret < 0)
WARN("%s - Failed to restore signal mask", strerror(errno)); WARN("%s - Failed to restore signal mask", strerror(errno));
lxc_console_delete(&handler->conf->console); lxc_terminal_delete(&handler->conf->console);
lxc_delete_tty(&handler->conf->tty_info); lxc_delete_tty(&handler->conf->ttys);
/* The command socket is now closed, no more state clients can register /* The command socket is now closed, no more state clients can register
* themselves from now on. So free the list of state clients. * themselves from now on. So free the list of state clients.
...@@ -1198,14 +1198,14 @@ static int do_start(void *data) ...@@ -1198,14 +1198,14 @@ static int do_start(void *data)
/* Some init's such as busybox will set sane tty settings on stdin, /* Some init's such as busybox will set sane tty settings on stdin,
* stdout, stderr which it thinks is the console. We already set them * stdout, stderr which it thinks is the console. We already set them
* the way we wanted on the real terminal, and we want init to do its * the way we wanted on the real terminal, and we want init to do its
* setup on its console ie. the pty allocated in lxc_console_create() so * setup on its console ie. the pty allocated in lxc_terminal_setup() so
* 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 == 0)
ret = set_stdfds(handler->conf->console.slave); ret = set_stdfds(handler->conf->console.slave);
else else
ret = lxc_console_set_stdfds(handler->conf->console.slave); ret = lxc_terminal_set_stdfds(handler->conf->console.slave);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to redirect std{in,out,err} to pty file " ERROR("Failed to redirect std{in,out,err} to pty file "
"descriptor %d", handler->conf->console.slave); "descriptor %d", handler->conf->console.slave);
...@@ -1340,17 +1340,17 @@ out_error: ...@@ -1340,17 +1340,17 @@ out_error:
static int lxc_recv_ttys_from_child(struct lxc_handler *handler) static int lxc_recv_ttys_from_child(struct lxc_handler *handler)
{ {
int i; int i;
struct lxc_pty_info *pty_info; struct lxc_terminal_info *tty;
int ret = -1; int ret = -1;
int sock = handler->data_sock[1]; int sock = handler->data_sock[1];
struct lxc_conf *conf = handler->conf; struct lxc_conf *conf = handler->conf;
struct lxc_tty_info *tty_info = &conf->tty_info; struct lxc_tty_info *ttys = &conf->ttys;
if (!conf->tty) if (!conf->tty)
return 0; return 0;
tty_info->pty_info = malloc(sizeof(*tty_info->pty_info) * conf->tty); ttys->tty = malloc(sizeof(*ttys->tty) * conf->tty);
if (!tty_info->pty_info) if (!ttys->tty)
return -1; return -1;
for (i = 0; i < conf->tty; i++) { for (i = 0; i < conf->tty; i++) {
...@@ -1360,12 +1360,12 @@ static int lxc_recv_ttys_from_child(struct lxc_handler *handler) ...@@ -1360,12 +1360,12 @@ static int lxc_recv_ttys_from_child(struct lxc_handler *handler)
if (ret < 0) if (ret < 0)
break; break;
pty_info = &tty_info->pty_info[i]; tty = &ttys->tty[i];
pty_info->busy = 0; tty->busy = 0;
pty_info->master = ttyfds[0]; tty->master = ttyfds[0];
pty_info->slave = ttyfds[1]; tty->slave = ttyfds[1];
TRACE("Received pty with master fd %d and slave fd %d from " TRACE("Received pty with master fd %d and slave fd %d from "
"parent", pty_info->master, pty_info->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 %d ttys from child: %s", conf->tty,
...@@ -1373,7 +1373,7 @@ static int lxc_recv_ttys_from_child(struct lxc_handler *handler) ...@@ -1373,7 +1373,7 @@ static int lxc_recv_ttys_from_child(struct lxc_handler *handler)
else else
TRACE("Received %d ttys from child", conf->tty); TRACE("Received %d ttys from child", conf->tty);
tty_info->nbtty = conf->tty; ttys->nbtty = conf->tty;
return ret; return ret;
} }
......
...@@ -38,11 +38,11 @@ ...@@ -38,11 +38,11 @@
#include "commands.h" #include "commands.h"
#include "conf.h" #include "conf.h"
#include "config.h" #include "config.h"
#include "console.h"
#include "log.h" #include "log.h"
#include "lxclock.h" #include "lxclock.h"
#include "mainloop.h" #include "mainloop.h"
#include "start.h" /* for struct lxc_handler */ #include "start.h" /* for struct lxc_handler */
#include "terminal.h"
#include "utils.h" #include "utils.h"
#if HAVE_PTY_H #if HAVE_PTY_H
...@@ -51,20 +51,20 @@ ...@@ -51,20 +51,20 @@
#include <../include/openpty.h> #include <../include/openpty.h>
#endif #endif
#define LXC_CONSOLE_BUFFER_SIZE 1024 #define LXC_TERMINAL_BUFFER_SIZE 1024
lxc_log_define(console, lxc); lxc_log_define(terminal, lxc);
static struct lxc_list lxc_ttys; static struct lxc_list lxc_ttys;
typedef void (*sighandler_t)(int); typedef void (*sighandler_t)(int);
__attribute__((constructor)) void lxc_console_init(void) __attribute__((constructor)) void lxc_terminal_init_global(void)
{ {
lxc_list_init(&lxc_ttys); lxc_list_init(&lxc_ttys);
} }
void lxc_console_winsz(int srcfd, int dstfd) void lxc_terminal_winsz(int srcfd, int dstfd)
{ {
int ret; int ret;
struct winsize wsz; struct winsize wsz;
...@@ -88,31 +88,31 @@ void lxc_console_winsz(int srcfd, int dstfd) ...@@ -88,31 +88,31 @@ void lxc_console_winsz(int srcfd, int dstfd)
return; return;
} }
static void lxc_console_winch(struct lxc_tty_state *ts) static void lxc_terminal_winch(struct lxc_terminal_state *ts)
{ {
lxc_console_winsz(ts->stdinfd, ts->masterfd); lxc_terminal_winsz(ts->stdinfd, ts->masterfd);
if (ts->winch_proxy) if (ts->winch_proxy)
lxc_cmd_console_winch(ts->winch_proxy, ts->winch_proxy_lxcpath); lxc_cmd_terminal_winch(ts->winch_proxy, ts->winch_proxy_lxcpath);
} }
void lxc_console_sigwinch(int sig) void lxc_terminal_sigwinch(int sig)
{ {
struct lxc_list *it; struct lxc_list *it;
struct lxc_tty_state *ts; struct lxc_terminal_state *ts;
lxc_list_for_each(it, &lxc_ttys) { lxc_list_for_each(it, &lxc_ttys) {
ts = it->elem; ts = it->elem;
lxc_console_winch(ts); lxc_terminal_winch(ts);
} }
} }
int lxc_console_cb_signal_fd(int fd, uint32_t events, void *cbdata, int lxc_terminal_signalfd_cb(int fd, uint32_t events, void *cbdata,
struct lxc_epoll_descr *descr) struct lxc_epoll_descr *descr)
{ {
ssize_t ret; ssize_t ret;
struct signalfd_siginfo siginfo; struct signalfd_siginfo siginfo;
struct lxc_tty_state *ts = cbdata; struct lxc_terminal_state *ts = cbdata;
ret = read(fd, &siginfo, sizeof(siginfo)); ret = read(fd, &siginfo, sizeof(siginfo));
if (ret < 0 || (size_t)ret < sizeof(siginfo)) { if (ret < 0 || (size_t)ret < sizeof(siginfo)) {
...@@ -121,22 +121,22 @@ int lxc_console_cb_signal_fd(int fd, uint32_t events, void *cbdata, ...@@ -121,22 +121,22 @@ int lxc_console_cb_signal_fd(int fd, uint32_t events, void *cbdata,
} }
if (siginfo.ssi_signo == SIGTERM) { if (siginfo.ssi_signo == SIGTERM) {
DEBUG("Received SIGTERM. Detaching from the console"); DEBUG("Received SIGTERM. Detaching from the terminal");
return LXC_MAINLOOP_CLOSE; return LXC_MAINLOOP_CLOSE;
} }
if (siginfo.ssi_signo == SIGWINCH) if (siginfo.ssi_signo == SIGWINCH)
lxc_console_winch(ts); lxc_terminal_winch(ts);
return 0; return 0;
} }
struct lxc_tty_state *lxc_console_signal_init(int srcfd, int dstfd) struct lxc_terminal_state *lxc_terminal_signal_init(int srcfd, int dstfd)
{ {
int ret; int ret;
bool istty; bool istty;
sigset_t mask; sigset_t mask;
struct lxc_tty_state *ts; struct lxc_terminal_state *ts;
ts = malloc(sizeof(*ts)); ts = malloc(sizeof(*ts));
if (!ts) if (!ts)
...@@ -189,7 +189,7 @@ on_error: ...@@ -189,7 +189,7 @@ on_error:
return ts; return ts;
} }
void lxc_console_signal_fini(struct lxc_tty_state *ts) void lxc_terminal_signal_fini(struct lxc_terminal_state *ts)
{ {
if (ts->sigfd >= 0) { if (ts->sigfd >= 0) {
close(ts->sigfd); close(ts->sigfd);
...@@ -204,65 +204,65 @@ void lxc_console_signal_fini(struct lxc_tty_state *ts) ...@@ -204,65 +204,65 @@ void lxc_console_signal_fini(struct lxc_tty_state *ts)
free(ts); free(ts);
} }
static int lxc_console_truncate_log_file(struct lxc_console *console) static int lxc_terminal_truncate_log_file(struct lxc_terminal *terminal)
{ {
/* be very certain things are kosher */ /* be very certain things are kosher */
if (!console->log_path || console->log_fd < 0) if (!terminal->log_path || terminal->log_fd < 0)
return -EBADF; return -EBADF;
return lxc_unpriv(ftruncate(console->log_fd, 0)); return lxc_unpriv(ftruncate(terminal->log_fd, 0));
} }
static int lxc_console_rotate_log_file(struct lxc_console *console) static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal)
{ {
int ret; int ret;
size_t len; size_t len;
char *tmp; char *tmp;
if (!console->log_path || console->log_rotate == 0) if (!terminal->log_path || terminal->log_rotate == 0)
return -EOPNOTSUPP; return -EOPNOTSUPP;
/* be very certain things are kosher */ /* be very certain things are kosher */
if (console->log_fd < 0) if (terminal->log_fd < 0)
return -EBADF; return -EBADF;
len = strlen(console->log_path) + sizeof(".1"); len = strlen(terminal->log_path) + sizeof(".1");
tmp = alloca(len); tmp = alloca(len);
ret = snprintf(tmp, len, "%s.1", console->log_path); ret = snprintf(tmp, len, "%s.1", terminal->log_path);
if (ret < 0 || (size_t)ret >= len) if (ret < 0 || (size_t)ret >= len)
return -EFBIG; return -EFBIG;
close(console->log_fd); close(terminal->log_fd);
console->log_fd = -1; terminal->log_fd = -1;
ret = lxc_unpriv(rename(console->log_path, tmp)); ret = lxc_unpriv(rename(terminal->log_path, tmp));
if (ret < 0) if (ret < 0)
return ret; return ret;
return lxc_console_create_log_file(console); return lxc_terminal_create_log_file(terminal);
} }
static int lxc_console_write_log_file(struct lxc_console *console, char *buf, static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf,
int bytes_read) int bytes_read)
{ {
int ret; int ret;
int64_t space_left = -1; int64_t space_left = -1;
struct stat st; struct stat st;
if (console->log_fd < 0) if (terminal->log_fd < 0)
return 0; return 0;
/* A log size <= 0 means that there's no limit on the size of the log /* A log size <= 0 means that there's no limit on the size of the log
* file at which point we simply ignore whether the log is supposed to * file at which point we simply ignore whether the log is supposed to
* be rotated or not. * be rotated or not.
*/ */
if (console->log_size <= 0) if (terminal->log_size <= 0)
return lxc_write_nointr(console->log_fd, buf, bytes_read); return lxc_write_nointr(terminal->log_fd, buf, bytes_read);
/* Get current size of the log file. */ /* Get current size of the log file. */
ret = fstat(console->log_fd, &st); ret = fstat(terminal->log_fd, &st);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to stat the console log file descriptor"); SYSERROR("Failed to stat the terminal log file descriptor");
return -1; return -1;
} }
...@@ -273,38 +273,38 @@ static int lxc_console_write_log_file(struct lxc_console *console, char *buf, ...@@ -273,38 +273,38 @@ static int lxc_console_write_log_file(struct lxc_console *console, char *buf,
* questionable. Let's not risk anything and tell the user that * questionable. Let's not risk anything and tell the user that
* he's requesting us to do weird stuff. * he's requesting us to do weird stuff.
*/ */
if (console->log_rotate > 0 || console->log_size > 0) if (terminal->log_rotate > 0 || terminal->log_size > 0)
return -EINVAL; return -EINVAL;
/* I mean, sure log wherever you want to. */ /* I mean, sure log wherever you want to. */
return lxc_write_nointr(console->log_fd, buf, bytes_read); return lxc_write_nointr(terminal->log_fd, buf, bytes_read);
} }
space_left = console->log_size - st.st_size; space_left = terminal->log_size - st.st_size;
/* User doesn't want to rotate the log file and there's no more space /* User doesn't want to rotate the log file and there's no more space
* left so simply truncate it. * left so simply truncate it.
*/ */
if (space_left <= 0 && console->log_rotate <= 0) { if (space_left <= 0 && terminal->log_rotate <= 0) {
ret = lxc_console_truncate_log_file(console); ret = lxc_terminal_truncate_log_file(terminal);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (bytes_read <= console->log_size) if (bytes_read <= terminal->log_size)
return lxc_write_nointr(console->log_fd, buf, bytes_read); return lxc_write_nointr(terminal->log_fd, buf, bytes_read);
/* Write as much as we can into the buffer and loose the rest. */ /* Write as much as we can into the buffer and loose the rest. */
return lxc_write_nointr(console->log_fd, buf, console->log_size); return lxc_write_nointr(terminal->log_fd, buf, terminal->log_size);
} }
/* There's enough space left. */ /* There's enough space left. */
if (bytes_read <= space_left) if (bytes_read <= space_left)
return lxc_write_nointr(console->log_fd, buf, bytes_read); return lxc_write_nointr(terminal->log_fd, buf, bytes_read);
/* There's not enough space left but at least write as much as we can /* There's not enough space left but at least write as much as we can
* into the old log file. * into the old log file.
*/ */
ret = lxc_write_nointr(console->log_fd, buf, space_left); ret = lxc_write_nointr(terminal->log_fd, buf, space_left);
if (ret < 0) if (ret < 0)
return -1; return -1;
...@@ -314,26 +314,26 @@ static int lxc_console_write_log_file(struct lxc_console *console, char *buf, ...@@ -314,26 +314,26 @@ static int lxc_console_write_log_file(struct lxc_console *console, char *buf,
/* There'd be more to write but we aren't instructed to rotate the log /* There'd be more to write but we aren't instructed to rotate the log
* file so simply return. There's no error on our side here. * file so simply return. There's no error on our side here.
*/ */
if (console->log_rotate > 0) if (terminal->log_rotate > 0)
ret = lxc_console_rotate_log_file(console); ret = lxc_terminal_rotate_log_file(terminal);
else else
ret = lxc_console_truncate_log_file(console); ret = lxc_terminal_truncate_log_file(terminal);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (console->log_size < bytes_read) { if (terminal->log_size < bytes_read) {
/* Well, this is unfortunate because it means that there is more /* Well, this is unfortunate because it means that there is more
* to write than the user has granted us space. There are * to write than the user has granted us space. There are
* multiple ways to handle this but let's use the simplest one: * multiple ways to handle this but let's use the simplest one:
* write as much as we can, tell the user that there was more * write as much as we can, tell the user that there was more
* stuff to write and move on. * stuff to write and move on.
* Note that this scenario shouldn't actually happen with the * Note that this scenario shouldn't actually happen with the
* standard pty-based console that LXC allocates since it will * standard pty-based terminal that LXC allocates since it will
* be switched into raw mode. In raw mode only 1 byte at a time * be switched into raw mode. In raw mode only 1 byte at a time
* should be read and written. * should be read and written.
*/ */
WARN("Size of console log file is smaller than the bytes to write"); WARN("Size of terminal log file is smaller than the bytes to write");
ret = lxc_write_nointr(console->log_fd, buf, console->log_size); ret = lxc_write_nointr(terminal->log_fd, buf, terminal->log_size);
if (ret < 0) if (ret < 0)
return -1; return -1;
bytes_read -= ret; bytes_read -= ret;
...@@ -341,33 +341,33 @@ static int lxc_console_write_log_file(struct lxc_console *console, char *buf, ...@@ -341,33 +341,33 @@ static int lxc_console_write_log_file(struct lxc_console *console, char *buf,
} }
/* Yay, we made it. */ /* Yay, we made it. */
ret = lxc_write_nointr(console->log_fd, buf, bytes_read); ret = lxc_write_nointr(terminal->log_fd, buf, bytes_read);
if (ret < 0) if (ret < 0)
return -1; return -1;
bytes_read -= ret; bytes_read -= ret;
return bytes_read; return bytes_read;
} }
int lxc_console_cb_con(int fd, uint32_t events, void *data, int lxc_terminal_io_cb(int fd, uint32_t events, void *data,
struct lxc_epoll_descr *descr) struct lxc_epoll_descr *descr)
{ {
struct lxc_console *console = (struct lxc_console *)data; struct lxc_terminal *terminal = data;
char buf[LXC_CONSOLE_BUFFER_SIZE]; char buf[LXC_TERMINAL_BUFFER_SIZE];
int r, w, w_log, w_rbuf; int r, w, w_log, w_rbuf;
w = r = lxc_read_nointr(fd, buf, sizeof(buf)); w = r = lxc_read_nointr(fd, buf, sizeof(buf));
if (r <= 0) { if (r <= 0) {
INFO("Console client on fd %d has exited", fd); INFO("Terminal client on fd %d has exited", fd);
lxc_mainloop_del_handler(descr, fd); lxc_mainloop_del_handler(descr, fd);
if (fd == console->master) { if (fd == terminal->master) {
console->master = -EBADF; terminal->master = -EBADF;
} else if (fd == console->peer) { } else if (fd == terminal->peer) {
if (console->tty_state) { if (terminal->tty_state) {
lxc_console_signal_fini(console->tty_state); lxc_terminal_signal_fini(terminal->tty_state);
console->tty_state = NULL; terminal->tty_state = NULL;
} }
console->peer = -EBADF; terminal->peer = -EBADF;
} else { } else {
ERROR("Handler received unexpected file descriptor"); ERROR("Handler received unexpected file descriptor");
} }
...@@ -376,55 +376,55 @@ int lxc_console_cb_con(int fd, uint32_t events, void *data, ...@@ -376,55 +376,55 @@ int lxc_console_cb_con(int fd, uint32_t events, void *data,
return LXC_MAINLOOP_CLOSE; return LXC_MAINLOOP_CLOSE;
} }
if (fd == console->peer) if (fd == terminal->peer)
w = lxc_write_nointr(console->master, buf, r); w = lxc_write_nointr(terminal->master, buf, r);
w_rbuf = w_log = 0; w_rbuf = w_log = 0;
if (fd == console->master) { if (fd == terminal->master) {
/* write to peer first */ /* write to peer first */
if (console->peer >= 0) if (terminal->peer >= 0)
w = lxc_write_nointr(console->peer, buf, r); w = lxc_write_nointr(terminal->peer, buf, r);
/* write to console ringbuffer */ /* write to terminal ringbuffer */
if (console->buffer_size > 0) if (terminal->buffer_size > 0)
w_rbuf = lxc_ringbuf_write(&console->ringbuf, buf, r); w_rbuf = lxc_ringbuf_write(&terminal->ringbuf, buf, r);
if (console->log_fd > 0)
w_log = lxc_console_write_log_file(console, buf, r);
/* write to terminal log */
if (terminal->log_fd >= 0)
w_log = lxc_terminal_write_log_file(terminal, buf, r);
} }
if (w != r) if (w != r)
WARN("Console short write r:%d != w:%d", r, w); WARN("Short write on terminal r:%d != w:%d", r, w);
if (w_rbuf < 0) if (w_rbuf < 0)
TRACE("%s - Failed to write %d bytes to console ringbuffer", TRACE("%s - Failed to write %d bytes to terminal ringbuffer",
strerror(-w_rbuf), r); strerror(-w_rbuf), r);
if (w_log < 0) if (w_log < 0)
TRACE("Failed to write %d bytes to console log", r); TRACE("Failed to write %d bytes to terminal log", r);
return 0; return 0;
} }
static int lxc_console_mainloop_add_peer(struct lxc_console *console) static int lxc_terminal_mainloop_add_peer(struct lxc_terminal *terminal)
{ {
int ret; int ret;
if (console->peer >= 0) { if (terminal->peer >= 0) {
ret = lxc_mainloop_add_handler(console->descr, console->peer, ret = lxc_mainloop_add_handler(terminal->descr, terminal->peer,
lxc_console_cb_con, console); lxc_terminal_io_cb, terminal);
if (ret < 0) { if (ret < 0) {
WARN("Failed to add console peer handler to mainloop"); WARN("Failed to add terminal peer handler to mainloop");
return -1; return -1;
} }
} }
if (!console->tty_state || console->tty_state->sigfd < 0) if (!terminal->tty_state || terminal->tty_state->sigfd < 0)
return 0; return 0;
ret = lxc_mainloop_add_handler(console->descr, console->tty_state->sigfd, ret = lxc_mainloop_add_handler(terminal->descr, terminal->tty_state->sigfd,
lxc_console_cb_signal_fd, console->tty_state); lxc_terminal_signalfd_cb, terminal->tty_state);
if (ret < 0) { if (ret < 0) {
WARN("Failed to add signal handler to mainloop"); WARN("Failed to add signal handler to mainloop");
return -1; return -1;
...@@ -433,28 +433,28 @@ static int lxc_console_mainloop_add_peer(struct lxc_console *console) ...@@ -433,28 +433,28 @@ static int lxc_console_mainloop_add_peer(struct lxc_console *console)
return 0; return 0;
} }
int lxc_console_mainloop_add(struct lxc_epoll_descr *descr, int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr,
struct lxc_console *console) struct lxc_terminal *terminal)
{ {
int ret; int ret;
if (console->master < 0) { if (terminal->master < 0) {
INFO("no console"); INFO("Terminal is not initialized");
return 0; return 0;
} }
ret = lxc_mainloop_add_handler(descr, console->master, ret = lxc_mainloop_add_handler(descr, terminal->master,
lxc_console_cb_con, console); lxc_terminal_io_cb, terminal);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to add handler for %d to mainloop", console->master); ERROR("Failed to add handler for %d to mainloop", terminal->master);
return -1; return -1;
} }
/* We cache the descr so that we can add an fd to it when someone /* We cache the descr so that we can add an fd to it when someone
* does attach to it in lxc_console_allocate(). * does attach to it in lxc_terminal_allocate().
*/ */
console->descr = descr; terminal->descr = descr;
ret = lxc_console_mainloop_add_peer(console); ret = lxc_terminal_mainloop_add_peer(terminal);
if (ret < 0) if (ret < 0)
return -1; return -1;
...@@ -509,90 +509,90 @@ int lxc_setup_tios(int fd, struct termios *oldtios) ...@@ -509,90 +509,90 @@ int lxc_setup_tios(int fd, struct termios *oldtios)
return 0; return 0;
} }
static void lxc_console_peer_proxy_free(struct lxc_console *console) static void lxc_terminal_peer_proxy_free(struct lxc_terminal *terminal)
{ {
if (console->tty_state) { if (terminal->tty_state) {
lxc_console_signal_fini(console->tty_state); lxc_terminal_signal_fini(terminal->tty_state);
console->tty_state = NULL; terminal->tty_state = NULL;
} }
close(console->peerpty.master); close(terminal->proxy.master);
close(console->peerpty.slave); close(terminal->proxy.slave);
console->peerpty.master = -1; terminal->proxy.master = -1;
console->peerpty.slave = -1; terminal->proxy.slave = -1;
console->peerpty.busy = -1; terminal->proxy.busy = -1;
console->peerpty.name[0] = '\0'; terminal->proxy.name[0] = '\0';
console->peer = -1; terminal->peer = -1;
} }
static int lxc_console_peer_proxy_alloc(struct lxc_console *console, int sockfd) static int lxc_terminal_peer_proxy_alloc(struct lxc_terminal *terminal, int sockfd)
{ {
struct termios oldtermio; struct termios oldtermio;
struct lxc_tty_state *ts; struct lxc_terminal_state *ts;
int ret; int ret;
if (console->master < 0) { if (terminal->master < 0) {
ERROR("console not set up"); ERROR("Terminal not set up");
return -1; return -1;
} }
if (console->peerpty.busy != -1 || console->peer != -1) { if (terminal->proxy.busy != -1 || terminal->peer != -1) {
NOTICE("console already in use"); NOTICE("Terminal already in use");
return -1; return -1;
} }
if (console->tty_state) { if (terminal->tty_state) {
ERROR("console already has tty_state"); ERROR("Terminal already has tty_state");
return -1; return -1;
} }
/* this is the proxy pty that will be given to the client, and that /* this is the proxy pty that will be given to the client, and that
* the real pty master will send to / recv from * the real pty master will send to / recv from
*/ */
ret = openpty(&console->peerpty.master, &console->peerpty.slave, ret = openpty(&terminal->proxy.master, &terminal->proxy.slave,
console->peerpty.name, NULL, NULL); terminal->proxy.name, NULL, NULL);
if (ret) { if (ret) {
SYSERROR("failed to create proxy pty"); SYSERROR("failed to create proxy pty");
return -1; return -1;
} }
if (lxc_setup_tios(console->peerpty.slave, &oldtermio) < 0) if (lxc_setup_tios(terminal->proxy.slave, &oldtermio) < 0)
goto err1; goto err1;
ts = lxc_console_signal_init(console->peerpty.master, console->master); ts = lxc_terminal_signal_init(terminal->proxy.master, terminal->master);
if (!ts) if (!ts)
goto err1; goto err1;
console->tty_state = ts; terminal->tty_state = ts;
console->peer = console->peerpty.slave; terminal->peer = terminal->proxy.slave;
console->peerpty.busy = sockfd; terminal->proxy.busy = sockfd;
ret = lxc_console_mainloop_add_peer(console); ret = lxc_terminal_mainloop_add_peer(terminal);
if (ret < 0) if (ret < 0)
goto err1; goto err1;
DEBUG("%d %s peermaster:%d sockfd:%d", lxc_raw_getpid(), __FUNCTION__, console->peerpty.master, sockfd); DEBUG("%d peermaster:%d sockfd:%d", lxc_raw_getpid(), terminal->proxy.master, sockfd);
return 0; return 0;
err1: err1:
lxc_console_peer_proxy_free(console); lxc_terminal_peer_proxy_free(terminal);
return -1; return -1;
} }
int lxc_console_allocate(struct lxc_conf *conf, int sockfd, int *ttyreq) int lxc_terminal_allocate(struct lxc_conf *conf, int sockfd, int *ttyreq)
{ {
int masterfd = -1, ttynum; int masterfd = -1, ttynum;
struct lxc_tty_info *tty_info = &conf->tty_info; struct lxc_tty_info *ttys = &conf->ttys;
struct lxc_console *console = &conf->console; struct lxc_terminal *terminal = &conf->console;
if (*ttyreq == 0) { if (*ttyreq == 0) {
if (lxc_console_peer_proxy_alloc(console, sockfd) < 0) if (lxc_terminal_peer_proxy_alloc(terminal, sockfd) < 0)
goto out; goto out;
masterfd = console->peerpty.master; masterfd = terminal->proxy.master;
goto out; goto out;
} }
if (*ttyreq > 0) { if (*ttyreq > 0) {
if (*ttyreq > tty_info->nbtty) if (*ttyreq > ttys->nbtty)
goto out; goto out;
if (tty_info->pty_info[*ttyreq - 1].busy) if (ttys->tty[*ttyreq - 1].busy)
goto out; goto out;
/* the requested tty is available */ /* the requested tty is available */
...@@ -601,47 +601,47 @@ int lxc_console_allocate(struct lxc_conf *conf, int sockfd, int *ttyreq) ...@@ -601,47 +601,47 @@ int lxc_console_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 <= tty_info->nbtty && tty_info->pty_info[ttynum - 1].busy; ttynum++) for (ttynum = 1; ttynum <= ttys->nbtty && 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 > tty_info->nbtty) if (ttynum > ttys->nbtty)
goto out; goto out;
*ttyreq = ttynum; *ttyreq = ttynum;
out_tty: out_tty:
tty_info->pty_info[ttynum - 1].busy = sockfd; ttys->tty[ttynum - 1].busy = sockfd;
masterfd = tty_info->pty_info[ttynum - 1].master; masterfd = ttys->tty[ttynum - 1].master;
out: out:
return masterfd; return masterfd;
} }
void lxc_console_free(struct lxc_conf *conf, int fd) void lxc_terminal_free(struct lxc_conf *conf, int fd)
{ {
int i; int i;
struct lxc_tty_info *tty_info = &conf->tty_info; struct lxc_tty_info *ttys = &conf->ttys;
struct lxc_console *console = &conf->console; struct lxc_terminal *terminal = &conf->console;
for (i = 0; i < tty_info->nbtty; i++) { for (i = 0; i < ttys->nbtty; i++) {
if (tty_info->pty_info[i].busy == fd) if (ttys->tty[i].busy == fd)
tty_info->pty_info[i].busy = 0; ttys->tty[i].busy = 0;
} }
if (console->peerpty.busy == fd) { if (terminal->proxy.busy == fd) {
lxc_mainloop_del_handler(console->descr, console->peerpty.slave); lxc_mainloop_del_handler(terminal->descr, terminal->proxy.slave);
lxc_console_peer_proxy_free(console); lxc_terminal_peer_proxy_free(terminal);
} }
} }
static int lxc_console_peer_default(struct lxc_console *console) static int lxc_terminal_peer_default(struct lxc_terminal *terminal)
{ {
struct lxc_tty_state *ts; struct lxc_terminal_state *ts;
const char *path = console->path; const char *path = terminal->path;
int fd; int fd;
int ret = 0; int ret = 0;
/* If no console was given, try current controlling terminal, there /* If no terminal was given, try current controlling terminal, there
* won't be one if we were started as a daemon (-d). * won't be one if we were started as a daemon (-d).
*/ */
if (!path && !access("/dev/tty", F_OK)) { if (!path && !access("/dev/tty", F_OK)) {
...@@ -658,129 +658,125 @@ static int lxc_console_peer_default(struct lxc_console *console) ...@@ -658,129 +658,125 @@ static int lxc_console_peer_default(struct lxc_console *console)
goto out; goto out;
} }
console->peer = lxc_unpriv(open(path, O_RDWR | O_CLOEXEC)); terminal->peer = lxc_unpriv(open(path, O_RDWR | O_CLOEXEC));
if (console->peer < 0) { if (terminal->peer < 0) {
ERROR("Failed to open \"%s\": %s", path, strerror(errno)); ERROR("Failed to open \"%s\": %s", path, strerror(errno));
return -ENOTTY; return -ENOTTY;
} }
DEBUG("using \"%s\" as peer tty device", path); DEBUG("using \"%s\" as peer tty device", path);
if (!isatty(console->peer)) { if (!isatty(terminal->peer)) {
ERROR("file descriptor for file \"%s\" does not refer to a tty device", path); ERROR("file descriptor for file \"%s\" does not refer to a tty device", path);
goto on_error1; goto on_error1;
} }
ts = lxc_console_signal_init(console->peer, console->master); ts = lxc_terminal_signal_init(terminal->peer, terminal->master);
console->tty_state = ts; terminal->tty_state = ts;
if (!ts) { if (!ts) {
WARN("Failed to install signal handler"); WARN("Failed to install signal handler");
goto on_error1; goto on_error1;
} }
lxc_console_winsz(console->peer, console->master); lxc_terminal_winsz(terminal->peer, terminal->master);
console->tios = malloc(sizeof(*console->tios)); terminal->tios = malloc(sizeof(*terminal->tios));
if (!console->tios) { if (!terminal->tios) {
SYSERROR("failed to allocate memory"); SYSERROR("failed to allocate memory");
goto on_error1; goto on_error1;
} }
if (lxc_setup_tios(console->peer, console->tios) < 0) if (lxc_setup_tios(terminal->peer, terminal->tios) < 0)
goto on_error2; goto on_error2;
else else
goto out; goto out;
on_error2: on_error2:
free(console->tios); free(terminal->tios);
console->tios = NULL; terminal->tios = NULL;
on_error1: on_error1:
close(console->peer); close(terminal->peer);
console->peer = -1; terminal->peer = -1;
ret = -ENOTTY; ret = -ENOTTY;
out: out:
return ret; return ret;
} }
int lxc_console_write_ringbuffer(struct lxc_console *console) int lxc_terminal_write_ringbuffer(struct lxc_terminal *terminal)
{ {
char *r_addr; char *r_addr;
ssize_t ret; ssize_t ret;
uint64_t used; uint64_t used;
struct lxc_ringbuf *buf = &console->ringbuf; struct lxc_ringbuf *buf = &terminal->ringbuf;
/* There's not log file where we can dump the ringbuffer to. */ /* There's not log file where we can dump the ringbuffer to. */
if (console->log_fd < 0) if (terminal->log_fd < 0)
return 0;
/* The log file is simply appended to. */
if (console->log_size == 0)
return 0; return 0;
used = lxc_ringbuf_used(buf); used = lxc_ringbuf_used(buf);
if (used == 0) if (used == 0)
return 0; return 0;
ret = lxc_console_truncate_log_file(console); ret = lxc_terminal_truncate_log_file(terminal);
if (ret < 0) if (ret < 0)
return ret; return ret;
/* Write as much as we can without exceeding the limit. */ /* Write as much as we can without exceeding the limit. */
if (console->log_size < used) if (terminal->log_size < used)
used = console->log_size; used = terminal->log_size;
r_addr = lxc_ringbuf_get_read_addr(buf); r_addr = lxc_ringbuf_get_read_addr(buf);
ret = lxc_write_nointr(console->log_fd, r_addr, used); ret = lxc_write_nointr(terminal->log_fd, r_addr, used);
if (ret < 0) if (ret < 0)
return -EIO; return -EIO;
return 0; return 0;
} }
void lxc_console_delete(struct lxc_console *console) void lxc_terminal_delete(struct lxc_terminal *terminal)
{ {
int ret; int ret;
ret = lxc_console_write_ringbuffer(console); ret = lxc_terminal_write_ringbuffer(terminal);
if (ret < 0) if (ret < 0)
WARN("Failed to write console ringbuffer to console log file"); WARN("Failed to write terminal log to disk");
if (console->tios && console->peer >= 0) { if (terminal->tios && terminal->peer >= 0) {
ret = tcsetattr(console->peer, TCSAFLUSH, console->tios); ret = tcsetattr(terminal->peer, TCSAFLUSH, terminal->tios);
if (ret < 0) if (ret < 0)
WARN("%s - Failed to set old terminal settings", strerror(errno)); WARN("%s - Failed to set old terminal settings", strerror(errno));
} }
free(console->tios); free(terminal->tios);
console->tios = NULL; terminal->tios = NULL;
if (console->peer >= 0) if (terminal->peer >= 0)
close(console->peer); close(terminal->peer);
console->peer = -1; terminal->peer = -1;
if (console->master >= 0) if (terminal->master >= 0)
close(console->master); close(terminal->master);
console->master = -1; terminal->master = -1;
if (console->slave >= 0) if (terminal->slave >= 0)
close(console->slave); close(terminal->slave);
console->slave = -1; terminal->slave = -1;
if (console->log_fd >= 0) if (terminal->log_fd >= 0)
close(console->log_fd); close(terminal->log_fd);
console->log_fd = -1; terminal->log_fd = -1;
} }
/** /**
* Note that this function needs to run before the mainloop starts. Since we * Note that this function needs to run before the mainloop starts. Since we
* register a handler for the console's masterfd when we create the mainloop * register a handler for the terminal's masterfd when we create the mainloop
* the console handler needs to see an allocated ringbuffer. * the terminal handler needs to see an allocated ringbuffer.
*/ */
static int lxc_console_create_ringbuf(struct lxc_console *console) static int lxc_terminal_create_ringbuf(struct lxc_terminal *terminal)
{ {
int ret; int ret;
struct lxc_ringbuf *buf = &console->ringbuf; struct lxc_ringbuf *buf = &terminal->ringbuf;
uint64_t size = console->buffer_size; uint64_t size = terminal->buffer_size;
/* no ringbuffer previously allocated and no ringbuffer requested */ /* no ringbuffer previously allocated and no ringbuffer requested */
if (!buf->addr && size <= 0) if (!buf->addr && size <= 0)
...@@ -793,7 +789,7 @@ static int lxc_console_create_ringbuf(struct lxc_console *console) ...@@ -793,7 +789,7 @@ static int lxc_console_create_ringbuf(struct lxc_console *console)
buf->r_off = 0; buf->r_off = 0;
buf->w_off = 0; buf->w_off = 0;
buf->size = 0; buf->size = 0;
TRACE("Deallocated console ringbuffer"); TRACE("Deallocated terminal ringbuffer");
return 0; return 0;
} }
...@@ -802,46 +798,46 @@ static int lxc_console_create_ringbuf(struct lxc_console *console) ...@@ -802,46 +798,46 @@ static int lxc_console_create_ringbuf(struct lxc_console *console)
/* check wether the requested size for the ringbuffer has changed */ /* check wether the requested size for the ringbuffer has changed */
if (buf->addr && buf->size != size) { if (buf->addr && buf->size != size) {
TRACE("Console ringbuffer size changed from %" PRIu64 TRACE("Terminal ringbuffer size changed from %" PRIu64
" to %" PRIu64 " bytes. Deallocating console ringbuffer", " to %" PRIu64 " bytes. Deallocating terminal ringbuffer",
buf->size, size); buf->size, size);
lxc_ringbuf_release(buf); lxc_ringbuf_release(buf);
} }
ret = lxc_ringbuf_create(buf, size); ret = lxc_ringbuf_create(buf, size);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to setup %" PRIu64 " byte console ringbuffer", size); ERROR("Failed to setup %" PRIu64 " byte terminal ringbuffer", size);
return -1; return -1;
} }
TRACE("Allocated %" PRIu64 " byte console ringbuffer", size); TRACE("Allocated %" PRIu64 " byte terminal ringbuffer", size);
return 0; return 0;
} }
/** /**
* This is the console log file. Please note that the console log file is * This is the terminal log file. Please note that the terminal log file is
* (implementation wise not content wise) independent of the console ringbuffer. * (implementation wise not content wise) independent of the terminal ringbuffer.
*/ */
int lxc_console_create_log_file(struct lxc_console *console) int lxc_terminal_create_log_file(struct lxc_terminal *terminal)
{ {
if (!console->log_path) if (!terminal->log_path)
return 0; return 0;
console->log_fd = lxc_unpriv(open(console->log_path, O_CLOEXEC | O_RDWR | O_CREAT | O_APPEND, 0600)); terminal->log_fd = lxc_unpriv(open(terminal->log_path, O_CLOEXEC | O_RDWR | O_CREAT | O_APPEND, 0600));
if (console->log_fd < 0) { if (terminal->log_fd < 0) {
SYSERROR("Failed to open console log file \"%s\"", console->log_path); SYSERROR("Failed to open terminal log file \"%s\"", terminal->log_path);
return -1; return -1;
} }
DEBUG("Using \"%s\" as console log file", console->log_path); DEBUG("Using \"%s\" as terminal log file", terminal->log_path);
return 0; return 0;
} }
int lxc_pty_create(struct lxc_console *console) int lxc_terminal_create(struct lxc_terminal *terminal)
{ {
int ret, saved_errno; int ret, saved_errno;
ret = openpty(&console->master, &console->slave, console->name, NULL, ret = openpty(&terminal->master, &terminal->slave, terminal->name, NULL,
NULL); NULL);
saved_errno = errno; saved_errno = errno;
if (ret < 0) { if (ret < 0) {
...@@ -849,19 +845,19 @@ int lxc_pty_create(struct lxc_console *console) ...@@ -849,19 +845,19 @@ int lxc_pty_create(struct lxc_console *console)
return -1; return -1;
} }
ret = fcntl(console->master, F_SETFD, FD_CLOEXEC); ret = fcntl(terminal->master, F_SETFD, FD_CLOEXEC);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to set FD_CLOEXEC flag on console master"); SYSERROR("Failed to set FD_CLOEXEC flag on terminal master");
goto err; goto err;
} }
ret = fcntl(console->slave, F_SETFD, FD_CLOEXEC); ret = fcntl(terminal->slave, F_SETFD, FD_CLOEXEC);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to set FD_CLOEXEC flag on console slave"); SYSERROR("Failed to set FD_CLOEXEC flag on terminal slave");
goto err; goto err;
} }
ret = lxc_console_peer_default(console); ret = lxc_terminal_peer_default(terminal);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to allocate a peer pty device"); ERROR("Failed to allocate a peer pty device");
goto err; goto err;
...@@ -870,42 +866,42 @@ int lxc_pty_create(struct lxc_console *console) ...@@ -870,42 +866,42 @@ int lxc_pty_create(struct lxc_console *console)
return 0; return 0;
err: err:
lxc_console_delete(console); lxc_terminal_delete(terminal);
return -ENODEV; return -ENODEV;
} }
int lxc_console_create(struct lxc_conf *conf) int lxc_terminal_setup(struct lxc_conf *conf)
{ {
int ret; int ret;
struct lxc_console *console = &conf->console; struct lxc_terminal *terminal = &conf->console;
if (console->path && !strcmp(console->path, "none")) { if (terminal->path && !strcmp(terminal->path, "none")) {
INFO("No console was requested"); INFO("No terminal was requested");
return 0; return 0;
} }
ret = lxc_pty_create(console); ret = lxc_terminal_create(terminal);
if (ret < 0) if (ret < 0)
return -1; return -1;
/* create console log file */ /* create terminal log file */
ret = lxc_console_create_log_file(console); ret = lxc_terminal_create_log_file(terminal);
if (ret < 0) if (ret < 0)
goto err; goto err;
/* create console ringbuffer */ /* create terminal ringbuffer */
ret = lxc_console_create_ringbuf(console); ret = lxc_terminal_create_ringbuf(terminal);
if (ret < 0) if (ret < 0)
goto err; goto err;
return 0; return 0;
err: err:
lxc_console_delete(console); lxc_terminal_delete(terminal);
return -ENODEV; return -ENODEV;
} }
int lxc_console_set_stdfds(int fd) int lxc_terminal_set_stdfds(int fd)
{ {
if (fd < 0) if (fd < 0)
return 0; return 0;
...@@ -931,10 +927,10 @@ int lxc_console_set_stdfds(int fd) ...@@ -931,10 +927,10 @@ int lxc_console_set_stdfds(int fd)
return 0; return 0;
} }
int lxc_console_cb_tty_stdin(int fd, uint32_t events, void *cbdata, int lxc_terminal_stdin_cb(int fd, uint32_t events, void *cbdata,
struct lxc_epoll_descr *descr) struct lxc_epoll_descr *descr)
{ {
struct lxc_tty_state *ts = cbdata; struct lxc_terminal_state *ts = cbdata;
char c; char c;
if (fd != ts->stdinfd) if (fd != ts->stdinfd)
...@@ -944,7 +940,7 @@ int lxc_console_cb_tty_stdin(int fd, uint32_t events, void *cbdata, ...@@ -944,7 +940,7 @@ int lxc_console_cb_tty_stdin(int fd, uint32_t events, void *cbdata,
return LXC_MAINLOOP_CLOSE; return LXC_MAINLOOP_CLOSE;
if (ts->escape >= 1) { if (ts->escape >= 1) {
/* we want to exit the console with Ctrl+a q */ /* we want to exit the terminal with Ctrl+a q */
if (c == ts->escape && !ts->saw_escape) { if (c == ts->escape && !ts->saw_escape) {
ts->saw_escape = 1; ts->saw_escape = 1;
return 0; return 0;
...@@ -962,11 +958,11 @@ int lxc_console_cb_tty_stdin(int fd, uint32_t events, void *cbdata, ...@@ -962,11 +958,11 @@ int lxc_console_cb_tty_stdin(int fd, uint32_t events, void *cbdata,
return 0; return 0;
} }
int lxc_console_cb_tty_master(int fd, uint32_t events, void *cbdata, int lxc_terminal_master_cb(int fd, uint32_t events, void *cbdata,
struct lxc_epoll_descr *descr) struct lxc_epoll_descr *descr)
{ {
struct lxc_tty_state *ts = cbdata; struct lxc_terminal_state *ts = cbdata;
char buf[LXC_CONSOLE_BUFFER_SIZE]; char buf[LXC_TERMINAL_BUFFER_SIZE];
int r, w; int r, w;
if (fd != ts->masterfd) if (fd != ts->masterfd)
...@@ -987,7 +983,7 @@ int lxc_console_cb_tty_master(int fd, uint32_t events, void *cbdata, ...@@ -987,7 +983,7 @@ int lxc_console_cb_tty_master(int fd, uint32_t events, void *cbdata,
return 0; return 0;
} }
int lxc_console_getfd(struct lxc_container *c, int *ttynum, int *masterfd) int lxc_terminal_getfd(struct lxc_container *c, int *ttynum, int *masterfd)
{ {
return lxc_cmd_console(c->name, ttynum, masterfd, c->config_path); return lxc_cmd_console(c->name, ttynum, masterfd, c->config_path);
} }
...@@ -999,7 +995,7 @@ int lxc_console(struct lxc_container *c, int ttynum, ...@@ -999,7 +995,7 @@ int lxc_console(struct lxc_container *c, int ttynum,
int ret, ttyfd, masterfd; int ret, ttyfd, masterfd;
struct lxc_epoll_descr descr; struct lxc_epoll_descr descr;
struct termios oldtios; struct termios oldtios;
struct lxc_tty_state *ts; struct lxc_terminal_state *ts;
int istty = 0; int istty = 0;
ttyfd = lxc_cmd_console(c->name, &ttynum, &masterfd, c->config_path); ttyfd = lxc_cmd_console(c->name, &ttynum, &masterfd, c->config_path);
...@@ -1010,7 +1006,7 @@ int lxc_console(struct lxc_container *c, int ttynum, ...@@ -1010,7 +1006,7 @@ int lxc_console(struct lxc_container *c, int ttynum,
if (ret < 0) if (ret < 0)
TRACE("Process is already group leader"); TRACE("Process is already group leader");
ts = lxc_console_signal_init(stdinfd, masterfd); ts = lxc_terminal_signal_init(stdinfd, masterfd);
if (!ts) { if (!ts) {
ret = -1; ret = -1;
goto close_fds; goto close_fds;
...@@ -1022,8 +1018,8 @@ int lxc_console(struct lxc_container *c, int ttynum, ...@@ -1022,8 +1018,8 @@ int lxc_console(struct lxc_container *c, int ttynum,
istty = isatty(stdinfd); istty = isatty(stdinfd);
if (istty) { if (istty) {
lxc_console_winsz(stdinfd, masterfd); lxc_terminal_winsz(stdinfd, masterfd);
lxc_cmd_console_winch(ts->winch_proxy, ts->winch_proxy_lxcpath); lxc_cmd_terminal_winch(ts->winch_proxy, ts->winch_proxy_lxcpath);
} else { } else {
INFO("File descriptor %d does not refer to a tty device", stdinfd); INFO("File descriptor %d does not refer to a tty device", stdinfd);
} }
...@@ -1036,7 +1032,7 @@ int lxc_console(struct lxc_container *c, int ttynum, ...@@ -1036,7 +1032,7 @@ int lxc_console(struct lxc_container *c, int ttynum,
if (ts->sigfd != -1) { if (ts->sigfd != -1) {
ret = lxc_mainloop_add_handler(&descr, ts->sigfd, ret = lxc_mainloop_add_handler(&descr, ts->sigfd,
lxc_console_cb_signal_fd, ts); lxc_terminal_signalfd_cb, ts);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to add signal handler to mainloop"); ERROR("Failed to add signal handler to mainloop");
goto close_mainloop; goto close_mainloop;
...@@ -1044,14 +1040,14 @@ int lxc_console(struct lxc_container *c, int ttynum, ...@@ -1044,14 +1040,14 @@ int lxc_console(struct lxc_container *c, int ttynum,
} }
ret = lxc_mainloop_add_handler(&descr, ts->stdinfd, ret = lxc_mainloop_add_handler(&descr, ts->stdinfd,
lxc_console_cb_tty_stdin, ts); lxc_terminal_stdin_cb, ts);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to add stdin handler"); ERROR("Failed to add stdin handler");
goto close_mainloop; goto close_mainloop;
} }
ret = lxc_mainloop_add_handler(&descr, ts->masterfd, ret = lxc_mainloop_add_handler(&descr, ts->masterfd,
lxc_console_cb_tty_master, ts); lxc_terminal_master_cb, ts);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to add master handler"); ERROR("Failed to add master handler");
goto close_mainloop; goto close_mainloop;
...@@ -1092,7 +1088,7 @@ close_mainloop: ...@@ -1092,7 +1088,7 @@ close_mainloop:
lxc_mainloop_close(&descr); lxc_mainloop_close(&descr);
sigwinch_fini: sigwinch_fini:
lxc_console_signal_fini(ts); lxc_terminal_signal_fini(ts);
close_fds: close_fds:
close(masterfd); close(masterfd);
...@@ -1122,7 +1118,7 @@ int lxc_login_pty(int fd) ...@@ -1122,7 +1118,7 @@ int lxc_login_pty(int fd)
if (ret < 0) if (ret < 0)
return -1; return -1;
ret = lxc_console_set_stdfds(fd); ret = lxc_terminal_set_stdfds(fd);
if (ret < 0) if (ret < 0)
return -1; return -1;
...@@ -1132,7 +1128,7 @@ int lxc_login_pty(int fd) ...@@ -1132,7 +1128,7 @@ int lxc_login_pty(int fd)
return 0; return 0;
} }
void lxc_pty_info_init(struct lxc_pty_info *pty) void lxc_terminal_info_init(struct lxc_terminal_info *pty)
{ {
pty->name[0] = '\0'; pty->name[0] = '\0';
pty->master = -EBADF; pty->master = -EBADF;
...@@ -1140,25 +1136,25 @@ void lxc_pty_info_init(struct lxc_pty_info *pty) ...@@ -1140,25 +1136,25 @@ void lxc_pty_info_init(struct lxc_pty_info *pty)
pty->busy = -1; pty->busy = -1;
} }
void lxc_pty_init(struct lxc_console *pty) void lxc_terminal_init(struct lxc_terminal *pty)
{ {
memset(pty, 0, sizeof(*pty)); memset(pty, 0, sizeof(*pty));
pty->slave = -EBADF; pty->slave = -EBADF;
pty->master = -EBADF; pty->master = -EBADF;
pty->peer = -EBADF; pty->peer = -EBADF;
pty->log_fd = -EBADF; pty->log_fd = -EBADF;
lxc_pty_info_init(&pty->peerpty); lxc_terminal_info_init(&pty->proxy);
} }
void lxc_pty_conf_free(struct lxc_console *console) void lxc_terminal_conf_free(struct lxc_terminal *terminal)
{ {
free(console->log_path); free(terminal->log_path);
free(console->path); free(terminal->path);
if (console->buffer_size > 0 && console->ringbuf.addr) if (terminal->buffer_size > 0 && terminal->ringbuf.addr)
lxc_ringbuf_release(&console->ringbuf); lxc_ringbuf_release(&terminal->ringbuf);
} }
int lxc_pty_map_ids(struct lxc_conf *c, struct lxc_console *pty) int lxc_terminal_map_ids(struct lxc_conf *c, struct lxc_terminal *pty)
{ {
int ret; int ret;
......
...@@ -24,27 +24,42 @@ ...@@ -24,27 +24,42 @@
#ifndef __LXC_CONSOLE_H #ifndef __LXC_CONSOLE_H
#define __LXC_CONSOLE_H #define __LXC_CONSOLE_H
#include "config.h"
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include "conf.h"
#include "list.h" #include "list.h"
#include "ringbuf.h"
struct lxc_container;
struct lxc_conf;
struct lxc_epoll_descr;
struct lxc_epoll_descr; /* defined in mainloop.h */ /* Defines a structure containing a pty information for virtualizing a tty
struct lxc_container; /* defined in lxccontainer.h */ * @name : the path name of the slave pty side
struct lxc_tty_state * @master : the file descriptor of the master
{ * @slave : the file descriptor of the slave
*/
struct lxc_terminal_info {
char name[MAXPATHLEN];
int master;
int slave;
int busy;
};
struct lxc_terminal_state {
struct lxc_list node; struct lxc_list node;
int stdinfd; int stdinfd;
int stdoutfd; int stdoutfd;
int masterfd; int masterfd;
/* Escape sequence to use for exiting the pty. A single char can be /* Escape sequence to use for exiting the pty. A single char can be
* specified. The pty can then exited by doing: Ctrl + specified_char + q. * specified. The pty can then exited by doing: Ctrl + specified_char +
* This field is checked by lxc_console_cb_tty_stdin(). Set to -1 to * q. This field is checked by lxc_terminal_stdin_cb(). Set to -1 to
* disable exiting the pty via a escape sequence. * disable exiting the pty via a escape sequence.
*/ */
int escape; int escape;
/* Used internally by lxc_console_cb_tty_stdin() to check whether an /* Used internally by lxc_terminal_stdin_cb() to check whether an
* escape sequence has been received. * escape sequence has been received.
*/ */
int saw_escape; int saw_escape;
...@@ -60,15 +75,49 @@ struct lxc_tty_state ...@@ -60,15 +75,49 @@ struct lxc_tty_state
sigset_t oldmask; sigset_t oldmask;
}; };
struct lxc_terminal {
int slave;
int master;
int peer;
struct lxc_terminal_info proxy;
struct lxc_epoll_descr *descr;
char *path;
char name[MAXPATHLEN];
struct termios *tios;
struct lxc_terminal_state *tty_state;
struct /* lxc_console_log */ {
/* size of the log file */
uint64_t log_size;
/* path to the log file */
char *log_path;
/* fd to the log file */
int log_fd;
/* whether the log file will be rotated */
unsigned int log_rotate;
};
struct /* lxc_terminal_ringbuf */ {
/* size of the ringbuffer */
uint64_t buffer_size;
/* the in-memory ringbuffer */
struct lxc_ringbuf ringbuf;
};
};
/* /*
* lxc_console_allocate: allocate the console or a tty * lxc_terminal_allocate: allocate the console or a tty
* *
* @conf : the configuration of the container to allocate from * @conf : the configuration of the container to allocate from
* @sockfd : the socket fd whose remote side when closed, will be an * @sockfd : the socket fd whose remote side when closed, will be an
* indication that the console or tty is no longer in use * indication that the console or tty is no longer in use
* @ttyreq : the tty requested to be opened, -1 for any, 0 for the console * @ttyreq : the tty requested to be opened, -1 for any, 0 for the console
*/ */
extern int lxc_console_allocate(struct lxc_conf *conf, int sockfd, int *ttynum); extern int lxc_terminal_allocate(struct lxc_conf *conf, int sockfd, int *ttynum);
/* /*
* Create a new pty: * Create a new pty:
...@@ -82,44 +131,44 @@ extern int lxc_console_allocate(struct lxc_conf *conf, int sockfd, int *ttynum) ...@@ -82,44 +131,44 @@ extern int lxc_console_allocate(struct lxc_conf *conf, int sockfd, int *ttynum)
* automatically chowned to the uid/gid of the unprivileged user. For this * automatically chowned to the uid/gid of the unprivileged user. For this
* ttys_shift_ids() can be called.) * ttys_shift_ids() can be called.)
*/ */
extern int lxc_pty_create(struct lxc_console *console); extern int lxc_terminal_create(struct lxc_terminal *console);
/** /**
* lxc_console_create: Create a new pty. * lxc_terminal_setup: Create a new pty.
* - In addition to lxc_pty_create() also sets up all pty logs. * - In addition to lxc_terminal_create() also sets up all pty logs.
*/ */
extern int lxc_console_create(struct lxc_conf *); extern int lxc_terminal_setup(struct lxc_conf *);
/* /*
* Delete a pty created via lxc_console_create(): * Delete a pty created via lxc_terminal_setup():
* - set old terminal settings * - set old terminal settings
* - memory allocated via lxc_console_create() is free()ed. * - memory allocated via lxc_terminal_setup() is free()ed.
* - close master/slave pty pair and allocated fd for the peer (usually * - close master/slave pty pair and allocated fd for the peer (usually
* /dev/tty) * /dev/tty)
* Registered handlers in a mainloop are not automatically deleted. * Registered handlers in a mainloop are not automatically deleted.
*/ */
extern void lxc_console_delete(struct lxc_console *); extern void lxc_terminal_delete(struct lxc_terminal *);
/* /*
* lxc_console_free: mark the console or a tty as unallocated, free any * lxc_terminal_free: mark the console or a tty as unallocated, free any
* resources allocated by lxc_console_allocate(). * resources allocated by lxc_terminal_allocate().
* *
* @conf : the configuration of the container whose tty was closed * @conf : the configuration of the container whose tty was closed
* @fd : the socket fd whose remote side was closed, which indicated * @fd : the socket fd whose remote side was closed, which indicated
* the console or tty is no longer in use. this is used to match * the console or tty is no longer in use. this is used to match
* which console/tty is being freed. * which console/tty is being freed.
*/ */
extern void lxc_console_free(struct lxc_conf *conf, int fd); extern void lxc_terminal_free(struct lxc_conf *conf, int fd);
/* /*
* Register pty event handlers in an open mainloop * Register pty event handlers in an open mainloop
*/ */
extern int lxc_console_mainloop_add(struct lxc_epoll_descr *, struct lxc_console *); extern int lxc_terminal_mainloop_add(struct lxc_epoll_descr *, struct lxc_terminal *);
/* /*
* Handle SIGWINCH events on the allocated ptys. * Handle SIGWINCH events on the allocated ptys.
*/ */
extern void lxc_console_sigwinch(int sig); extern void lxc_terminal_sigwinch(int sig);
/* /*
* Connect to one of the ptys given to the container via lxc.tty.max. * Connect to one of the ptys given to the container via lxc.tty.max.
...@@ -140,7 +189,7 @@ extern int lxc_console(struct lxc_container *c, int ttynum, ...@@ -140,7 +189,7 @@ extern int lxc_console(struct lxc_container *c, int ttynum,
* Set ttynum to -1 to allocate the first available pty, or to a value within * Set ttynum to -1 to allocate the first available pty, or to a value within
* the range specified by lxc.tty.max to allocate a specific pty. * the range specified by lxc.tty.max to allocate a specific pty.
*/ */
extern int lxc_console_getfd(struct lxc_container *c, int *ttynum, extern int lxc_terminal_getfd(struct lxc_container *c, int *ttynum,
int *masterfd); int *masterfd);
/* /*
...@@ -148,24 +197,24 @@ extern int lxc_console_getfd(struct lxc_container *c, int *ttynum, ...@@ -148,24 +197,24 @@ extern int lxc_console_getfd(struct lxc_container *c, int *ttynum,
* fd is made a duplicate of a specific standard file descriptor iff the * fd is made a duplicate of a specific standard file descriptor iff the
* standard file descriptor refers to a pty. * standard file descriptor refers to a pty.
*/ */
extern int lxc_console_set_stdfds(int fd); extern int lxc_terminal_set_stdfds(int fd);
/* /*
* Handler for events on the stdin fd of the pty. To be registered via the * Handler for events on the stdin fd of the pty. To be registered via the
* corresponding functions declared and defined in mainloop.{c,h} or * corresponding functions declared and defined in mainloop.{c,h} or
* lxc_console_mainloop_add(). * lxc_terminal_mainloop_add().
* This function exits the loop cleanly when an EPOLLHUP event is received. * This function exits the loop cleanly when an EPOLLHUP event is received.
*/ */
extern int lxc_console_cb_tty_stdin(int fd, uint32_t events, void *cbdata, extern int lxc_terminal_stdin_cb(int fd, uint32_t events, void *cbdata,
struct lxc_epoll_descr *descr); struct lxc_epoll_descr *descr);
/* /*
* Handler for events on the master fd of the pty. To be registered via the * Handler for events on the master fd of the pty. To be registered via the
* corresponding functions declared and defined in mainloop.{c,h} or * corresponding functions declared and defined in mainloop.{c,h} or
* lxc_console_mainloop_add(). * lxc_terminal_mainloop_add().
* This function exits the loop cleanly when an EPOLLHUP event is received. * This function exits the loop cleanly when an EPOLLHUP event is received.
*/ */
extern int lxc_console_cb_tty_master(int fd, uint32_t events, void *cbdata, extern int lxc_terminal_master_cb(int fd, uint32_t events, void *cbdata,
struct lxc_epoll_descr *descr); struct lxc_epoll_descr *descr);
/* /*
...@@ -176,21 +225,21 @@ extern int lxc_setup_tios(int fd, struct termios *oldtios); ...@@ -176,21 +225,21 @@ extern int lxc_setup_tios(int fd, struct termios *oldtios);
/* /*
* lxc_console_winsz: propagte winsz from one terminal to another * lxc_terminal_winsz: propagate winsz from one terminal to another
* *
* @srcfd : terminal to get size from (typically a slave pty) * @srcfd : terminal to get size from (typically a slave pty)
* @dstfd : terminal to set size on (typically a master pty) * @dstfd : terminal to set size on (typically a master pty)
*/ */
extern void lxc_console_winsz(int srcfd, int dstfd); extern void lxc_terminal_winsz(int srcfd, int dstfd);
/* /*
* lxc_console_signal_init: install signal handler * lxc_terminal_signal_init: install signal handler
* *
* @srcfd : src for winsz in SIGWINCH handler * @srcfd : src for winsz in SIGWINCH handler
* @dstfd : dst for winsz in SIGWINCH handler * @dstfd : dst for winsz in SIGWINCH handler
* *
* Returns lxc_tty_state structure on success or NULL on failure. The sigfd * Returns lxc_terminal_state structure on success or NULL on failure. The sigfd
* member of the returned lxc_tty_state can be select()/poll()ed/epoll()ed * member of the returned lxc_terminal_state can be select()/poll()ed/epoll()ed
* on (ie added to a mainloop) for signals. * on (ie added to a mainloop) for signals.
* *
* Must be called with process_lock held to protect the lxc_ttys list, or * Must be called with process_lock held to protect the lxc_ttys list, or
...@@ -199,43 +248,44 @@ extern void lxc_console_winsz(int srcfd, int dstfd); ...@@ -199,43 +248,44 @@ extern void lxc_console_winsz(int srcfd, int dstfd);
* Note that the signal handler isn't installed as a classic asychronous * Note that the signal handler isn't installed as a classic asychronous
* handler, rather signalfd(2) is used so that we can handle the signal when * handler, rather signalfd(2) is used so that we can handle the signal when
* we're ready for it. This avoids deadlocks since a signal handler (ie * we're ready for it. This avoids deadlocks since a signal handler (ie
* lxc_console_sigwinch()) would need to take the thread mutex to prevent * lxc_terminal_sigwinch()) would need to take the thread mutex to prevent
* lxc_ttys list corruption, but using the fd we can provide the tty_state * lxc_ttys list corruption, but using the fd we can provide the tty_state
* needed to the callback (lxc_console_cb_signal_fd()). * needed to the callback (lxc_terminal_signalfd_cb()).
* *
* This function allocates memory. It is up to the caller to free it. * This function allocates memory. It is up to the caller to free it.
*/ */
extern struct lxc_tty_state *lxc_console_signal_init(int srcfd, int dstfd); extern struct lxc_terminal_state *lxc_terminal_signal_init(int srcfd, int dstfd);
/* /*
* Handler for signal events. To be registered via the corresponding functions * Handler for signal events. To be registered via the corresponding functions
* declared and defined in mainloop.{c,h} or lxc_console_mainloop_add(). * declared and defined in mainloop.{c,h} or lxc_terminal_mainloop_add().
*/ */
extern int lxc_console_cb_signal_fd(int fd, uint32_t events, void *cbdata, extern int lxc_terminal_signalfd_cb(int fd, uint32_t events, void *cbdata,
struct lxc_epoll_descr *descr); struct lxc_epoll_descr *descr);
/* /*
* lxc_console_signal_fini: uninstall signal handler * lxc_terminal_signal_fini: uninstall signal handler
* *
* @ts : the lxc_tty_state returned by lxc_console_signal_init * @ts : the lxc_terminal_state returned by lxc_terminal_signal_init
* *
* Restore the saved signal handler that was in effect at the time * Restore the saved signal handler that was in effect at the time
* lxc_console_signal_init() was called. * lxc_terminal_signal_init() was called.
* *
* Must be called with process_lock held to protect the lxc_ttys list, or * Must be called with process_lock held to protect the lxc_ttys list, or
* from a non-threaded context. * from a non-threaded context.
*/ */
extern void lxc_console_signal_fini(struct lxc_tty_state *ts); extern void lxc_terminal_signal_fini(struct lxc_terminal_state *ts);
extern int lxc_console_create_log_file(struct lxc_console *console); extern int lxc_terminal_write_ringbuffer(struct lxc_terminal *console);
extern int lxc_console_cb_con(int fd, uint32_t events, void *data, extern int lxc_terminal_create_log_file(struct lxc_terminal *console);
extern int lxc_terminal_io_cb(int fd, uint32_t events, void *data,
struct lxc_epoll_descr *descr); struct lxc_epoll_descr *descr);
extern int lxc_make_controlling_pty(int fd); extern int lxc_make_controlling_pty(int fd);
extern int lxc_login_pty(int fd); extern int lxc_login_pty(int fd);
extern void lxc_pty_conf_free(struct lxc_console *console); extern void lxc_terminal_conf_free(struct lxc_terminal *console);
extern void lxc_pty_info_init(struct lxc_pty_info *pty); extern void lxc_terminal_info_init(struct lxc_terminal_info *pty);
extern void lxc_pty_init(struct lxc_console *pty); extern void lxc_terminal_init(struct lxc_terminal *pty);
extern int lxc_pty_map_ids(struct lxc_conf *c, struct lxc_console *pty); extern int lxc_terminal_map_ids(struct lxc_conf *c, struct lxc_terminal *pty);
#endif #endif
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