Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lxc
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
lxc
Commits
19462d43
Unverified
Commit
19462d43
authored
Feb 27, 2018
by
Serge Hallyn
Committed by
GitHub
Feb 27, 2018
Browse files
Options
Browse Files
Download
Plain Diff
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
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
478 additions
and
493 deletions
+478
-493
Makefile.am
src/lxc/Makefile.am
+2
-2
attach.c
src/lxc/attach.c
+17
-17
cgfsng.c
src/lxc/cgroups/cgfsng.c
+1
-3
commands.c
src/lxc/commands.c
+13
-14
commands.h
src/lxc/commands.h
+2
-2
conf.c
src/lxc/conf.c
+49
-51
conf.h
src/lxc/conf.h
+8
-64
criu.c
src/lxc/criu.c
+6
-6
lxccontainer.c
src/lxc/lxccontainer.c
+2
-2
start.c
src/lxc/start.c
+24
-24
terminal.c
src/lxc/terminal.c
+254
-258
terminal.h
src/lxc/terminal.h
+100
-50
No files found.
src/lxc/Makefile.am
View file @
19462d43
...
...
@@ -26,7 +26,6 @@ noinst_HEADERS = \
conf.h
\
confile.h
\
confile_utils.h
\
console.h
\
error.h
\
initutils.h
\
list.h
\
...
...
@@ -37,6 +36,7 @@ noinst_HEADERS = \
namespace.h
\
start.h
\
state.h
\
terminal.h
\
utils.h
\
criu.h
\
../tests/lxctest.h
...
...
@@ -100,7 +100,7 @@ liblxc_la_SOURCES = \
start.c start.h
\
execute.c
\
monitor.c monitor.h
\
console
.c
\
terminal
.c
\
freezer.c
\
error.h error.c
\
parse.c parse.h
\
...
...
src/lxc/attach.c
View file @
19462d43
...
...
@@ -61,13 +61,13 @@
#include "conf.h"
#include "config.h"
#include "confile.h"
#include "console.h"
#include "log.h"
#include "lsm/lsm.h"
#include "lxclock.h"
#include "lxcseccomp.h"
#include "mainloop.h"
#include "namespace.h"
#include "terminal.h"
#include "utils.h"
#if HAVE_SYS_PERSONALITY_H
...
...
@@ -974,20 +974,20 @@ on_error:
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
;
lxc_
pty
_init
(
pty
);
lxc_
terminal
_init
(
pty
);
ret
=
lxc_
pty
_create
(
pty
);
ret
=
lxc_
terminal
_create
(
pty
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to create pty"
);
return
-
1
;
}
/* Shift ttys to container. */
ret
=
lxc_
pty
_map_ids
(
conf
,
pty
);
ret
=
lxc_
terminal
_map_ids
(
conf
,
pty
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to shift pty"
);
goto
on_error
;
...
...
@@ -996,12 +996,12 @@ static int lxc_attach_pty(struct lxc_conf *conf, struct lxc_console *pty)
return
0
;
on_error:
lxc_
console
_delete
(
pty
);
lxc_
pty
_conf_free
(
pty
);
lxc_
terminal
_delete
(
pty
);
lxc_
terminal
_conf_free
(
pty
);
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
)
{
int
ret
;
...
...
@@ -1012,7 +1012,7 @@ static int lxc_attach_pty_mainloop_init(struct lxc_console *pty,
return
-
1
;
}
ret
=
lxc_
console
_mainloop_add
(
descr
,
pty
);
ret
=
lxc_
terminal
_mainloop_add
(
descr
,
pty
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to add handlers to mainloop"
);
lxc_mainloop_close
(
descr
);
...
...
@@ -1022,7 +1022,7 @@ static int lxc_attach_pty_mainloop_init(struct lxc_console *pty,
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
)
return
;
...
...
@@ -1031,7 +1031,7 @@ static inline void lxc_attach_pty_close_master(struct lxc_console *pty)
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
)
return
;
...
...
@@ -1040,7 +1040,7 @@ static inline void lxc_attach_pty_close_slave(struct lxc_console *pty)
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
)
return
;
...
...
@@ -1049,7 +1049,7 @@ static inline void lxc_attach_pty_close_peer(struct lxc_console *pty)
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
)
return
;
...
...
@@ -1068,7 +1068,7 @@ int lxc_attach(const char *name, const char *lxcpath,
signed
long
personality
;
pid_t
attached_pid
,
init_pid
,
pid
;
struct
lxc_proc_context_info
*
init_ctx
;
struct
lxc_
console
pty
;
struct
lxc_
terminal
pty
;
struct
lxc_conf
*
conf
;
struct
attach_clone_payload
payload
=
{
0
};
...
...
@@ -1198,7 +1198,7 @@ int lxc_attach(const char *name, const char *lxcpath,
pty
.
log_fd
=
options
->
log_fd
;
}
else
{
lxc_
pty
_init
(
&
pty
);
lxc_
terminal
_init
(
&
pty
);
}
/* 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,
(
void
)
wait_for_pid
(
to_cleanup_pid
);
if
(
options
->
attach_flags
&
LXC_ATTACH_ALLOCATE_PTY
)
{
lxc_
console
_delete
(
&
pty
);
lxc_
pty
_conf_free
(
&
pty
);
lxc_
terminal
_delete
(
&
pty
);
lxc_
terminal
_conf_free
(
&
pty
);
}
lxc_proc_put_context_info
(
init_ctx
);
return
ret_parent
;
...
...
src/lxc/cgroups/cgfsng.c
View file @
19462d43
...
...
@@ -843,13 +843,11 @@ static bool all_controllers_found(void)
if
(
!
cgroup_use
)
return
true
;
for
(
p
=
strtok_r
(
cgroup_use
,
","
,
&
saveptr
);
p
;
p
=
strtok_r
(
NULL
,
","
,
&
saveptr
))
{
for
(;
(
p
=
strtok_r
(
cgroup_use
,
","
,
&
saveptr
));
cgroup_use
=
NULL
)
if
(
!
controller_found
(
hlist
,
p
))
{
CGFSNG_DEBUG
(
"No %s controller mountpoint found
\n
"
,
p
);
return
false
;
}
}
return
true
;
}
...
...
src/lxc/commands.c
View file @
19462d43
...
...
@@ -42,13 +42,13 @@
#include "commands_utils.h"
#include "conf.h"
#include "confile.h"
#include "console.h"
#include "log.h"
#include "lxc.h"
#include "lxclock.h"
#include "mainloop.h"
#include "monitor.h"
#include "start.h"
#include "terminal.h"
#include "utils.h"
/*
...
...
@@ -82,7 +82,7 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd)
{
static
const
char
*
const
cmdname
[
LXC_CMD_MAX
]
=
{
[
LXC_CMD_CONSOLE
]
=
"console"
,
[
LXC_CMD_
CONSOLE_WINCH
]
=
"console
_winch"
,
[
LXC_CMD_
TERMINAL_WINCH
]
=
"terminal
_winch"
,
[
LXC_CMD_STOP
]
=
"stop"
,
[
LXC_CMD_GET_STATE
]
=
"get_state"
,
[
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,
}
/*
* 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
* @lxcpath : the lxcpath in which the container is running
*
* 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
;
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
);
...
...
@@ -680,12 +680,12 @@ int lxc_cmd_console_winch(const char *name, const char *lxcpath)
return
0
;
}
static
int
lxc_cmd_
console
_winch_callback
(
int
fd
,
struct
lxc_cmd_req
*
req
,
struct
lxc_handler
*
handler
)
static
int
lxc_cmd_
terminal
_winch_callback
(
int
fd
,
struct
lxc_cmd_req
*
req
,
struct
lxc_handler
*
handler
)
{
struct
lxc_cmd_rsp
rsp
=
{
.
data
=
0
};
lxc_
console
_sigwinch
(
SIGWINCH
);
lxc_
terminal
_sigwinch
(
SIGWINCH
);
return
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
}
...
...
@@ -748,7 +748,7 @@ static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
struct
lxc_cmd_rsp
rsp
;
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
)
goto
out_close
;
...
...
@@ -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
));
if
(
ret
<
0
)
{
ERROR
(
"Failed to send tty to client"
);
lxc_
console
_free
(
handler
->
conf
,
fd
);
lxc_
terminal
_free
(
handler
->
conf
,
fd
);
goto
out_close
;
}
...
...
@@ -991,8 +991,7 @@ static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
rsp
.
ret
=
0
;
if
(
log
->
clear
)
/* clear the ringbuffer */
lxc_ringbuf_clear
(
buf
);
lxc_ringbuf_clear
(
buf
);
/* clear the ringbuffer */
else
if
(
rsp
.
datalen
>
0
)
lxc_ringbuf_move_read_addr
(
buf
,
rsp
.
datalen
);
...
...
@@ -1052,7 +1051,7 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
callback
cb
[
LXC_CMD_MAX
]
=
{
[
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_GET_STATE
]
=
lxc_cmd_get_state_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,
struct
lxc_state_client
*
client
;
struct
lxc_list
*
cur
,
*
next
;
lxc_
console
_free
(
handler
->
conf
,
fd
);
lxc_
terminal
_free
(
handler
->
conf
,
fd
);
lxc_mainloop_del_handler
(
descr
,
fd
);
if
(
cmd
!=
LXC_CMD_ADD_STATE_CLIENT
)
{
close
(
fd
);
...
...
src/lxc/commands.h
View file @
19462d43
...
...
@@ -39,7 +39,7 @@
typedef
enum
{
LXC_CMD_CONSOLE
,
LXC_CMD_
CONSOLE
_WINCH
,
LXC_CMD_
TERMINAL
_WINCH
,
LXC_CMD_STOP
,
LXC_CMD_GET_STATE
,
LXC_CMD_GET_INIT_PID
,
...
...
@@ -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
,
const
char
*
lxcpath
);
/*
...
...
src/lxc/conf.c
View file @
19462d43
...
...
@@ -73,9 +73,9 @@
#include "cgroup.h"
#include "conf.h"
#include "confile_utils.h"
#include "console.h"
#include "error.h"
#include "log.h"
#include "lsm/lsm.h"
#include "lxclock.h"
#include "lxcseccomp.h"
#include "namespace.h"
...
...
@@ -85,8 +85,8 @@
#include "storage.h"
#include "storage/aufs.h"
#include "storage/overlay.h"
#include "terminal.h"
#include "utils.h"
#include "lsm/lsm.h"
#if HAVE_LIBCAP
#include <sys/capability.h>
...
...
@@ -840,15 +840,15 @@ static bool append_ptyname(char **pp, char *name)
static
int
lxc_setup_ttys
(
struct
lxc_conf
*
conf
)
{
int
i
,
ret
;
const
struct
lxc_tty_info
*
tty
_info
=
&
conf
->
tty_info
;
const
struct
lxc_tty_info
*
tty
s
=
&
conf
->
ttys
;
char
*
ttydir
=
conf
->
ttydir
;
char
path
[
MAXPATHLEN
],
lxcpath
[
MAXPATHLEN
];
if
(
!
conf
->
rootfs
.
path
)
return
0
;
for
(
i
=
0
;
i
<
tty
_info
->
nbtty
;
i
++
)
{
struct
lxc_
pty_info
*
pty_info
=
&
tty_info
->
pty_info
[
i
];
for
(
i
=
0
;
i
<
tty
s
->
nbtty
;
i
++
)
{
struct
lxc_
terminal_info
*
tty
=
&
ttys
->
tty
[
i
];
ret
=
snprintf
(
path
,
sizeof
(
path
),
"/dev/tty%d"
,
i
+
1
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
sizeof
(
path
))
...
...
@@ -875,13 +875,13 @@ static int lxc_setup_ttys(struct lxc_conf *conf)
return
-
1
;
}
ret
=
mount
(
pty_info
->
name
,
lxcpath
,
"none"
,
MS_BIND
,
0
);
ret
=
mount
(
tty
->
name
,
lxcpath
,
"none"
,
MS_BIND
,
0
);
if
(
ret
<
0
)
{
WARN
(
"Failed to bind mount
\"
%s
\"
onto
\"
%s
\"
"
,
pty_info
->
name
,
path
);
tty
->
name
,
path
);
continue
;
}
DEBUG
(
"bind mounted
\"
%s
\"
onto
\"
%s
\"
"
,
pty_info
->
name
,
DEBUG
(
"bind mounted
\"
%s
\"
onto
\"
%s
\"
"
,
tty
->
name
,
path
);
ret
=
snprintf
(
lxcpath
,
sizeof
(
lxcpath
),
"%s/tty%d"
,
...
...
@@ -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
)
{
SYSERROR
(
"Failed to mount '%s'->'%s'"
,
pty_info
->
name
,
path
);
SYSERROR
(
"Failed to mount '%s'->'%s'"
,
tty
->
name
,
path
);
continue
;
}
DEBUG
(
"Bind mounted
\"
%s
\"
onto
\"
%s
\"
"
,
pty_info
->
name
,
DEBUG
(
"Bind mounted
\"
%s
\"
onto
\"
%s
\"
"
,
tty
->
name
,
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"
);
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)"
,
tty
s
->
nbtty
);
return
0
;
}
int
lxc_allocate_ttys
(
const
char
*
name
,
struct
lxc_conf
*
conf
)
{
struct
lxc_tty_info
*
tty
_info
=
&
conf
->
tty_info
;
struct
lxc_tty_info
*
tty
s
=
&
conf
->
ttys
;
int
i
,
ret
;
/* no tty in the configuration */
if
(
!
conf
->
tty
)
return
0
;
tty_info
->
pty_info
=
malloc
(
sizeof
(
*
tty_info
->
pty_info
)
*
conf
->
tty
);
if
(
!
tty_info
->
pty_info
)
{
SYSERROR
(
"failed to allocate struct *pty_info"
);
ttys
->
tty
=
malloc
(
sizeof
(
*
ttys
->
tty
)
*
conf
->
tty
);
if
(
!
ttys
->
tty
)
return
-
ENOMEM
;
}
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
,
pty_info
->
name
,
NULL
,
NULL
);
ret
=
openpty
(
&
tty
->
master
,
&
tty
->
slave
,
tty
->
name
,
NULL
,
NULL
);
if
(
ret
)
{
SYSERROR
(
"failed to create pty device number %d"
,
i
);
tty
_info
->
nbtty
=
i
;
lxc_delete_tty
(
tty
_info
);
tty
s
->
nbtty
=
i
;
lxc_delete_tty
(
tty
s
);
return
-
ENOTTY
;
}
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 */
ret
=
fcntl
(
pty_info
->
master
,
F_SETFD
,
FD_CLOEXEC
);
ret
=
fcntl
(
tty
->
master
,
F_SETFD
,
FD_CLOEXEC
);
if
(
ret
<
0
)
WARN
(
"failed to set FD_CLOEXEC flag on master fd %d of "
"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
)
WARN
(
"failed to set FD_CLOEXEC flag on slave fd %d of "
"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
;
tty
s
->
nbtty
=
conf
->
tty
;
INFO
(
"finished allocating %d pts devices"
,
conf
->
tty
);
return
0
;
}
void
lxc_delete_tty
(
struct
lxc_tty_info
*
tty
_info
)
void
lxc_delete_tty
(
struct
lxc_tty_info
*
tty
s
)
{
int
i
;
for
(
i
=
0
;
i
<
tty
_info
->
nbtty
;
i
++
)
{
struct
lxc_
pty_info
*
pty_info
=
&
tty_info
->
pty_info
[
i
];
for
(
i
=
0
;
i
<
tty
s
->
nbtty
;
i
++
)
{
struct
lxc_
terminal_info
*
tty
=
&
ttys
->
tty
[
i
];
close
(
pty_info
->
master
);
close
(
pty_info
->
slave
);
close
(
tty
->
master
);
close
(
tty
->
slave
);
}
free
(
tty
_info
->
pty_info
);
tty
_info
->
pty_info
=
NULL
;
tty
_info
->
nbtty
=
0
;
free
(
tty
s
->
tty
);
tty
s
->
tty
=
NULL
;
tty
s
->
nbtty
=
0
;
}
static
int
lxc_send_ttys_to_parent
(
struct
lxc_handler
*
handler
)
{
int
i
;
struct
lxc_conf
*
conf
=
handler
->
conf
;
struct
lxc_tty_info
*
tty
_info
=
&
conf
->
tty_info
;
struct
lxc_tty_info
*
tty
s
=
&
conf
->
ttys
;
int
sock
=
handler
->
data_sock
[
0
];
int
ret
=
-
1
;
...
...
@@ -1011,17 +1009,17 @@ static int lxc_send_ttys_to_parent(struct lxc_handler *handler)
for
(
i
=
0
;
i
<
conf
->
tty
;
i
++
)
{
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
[
1
]
=
pty_info
->
slave
;
ttyfds
[
0
]
=
tty
->
master
;
ttyfds
[
1
]
=
tty
->
slave
;
ret
=
lxc_abstract_unix_send_fds
(
sock
,
ttyfds
,
2
,
NULL
,
0
);
if
(
ret
<
0
)
break
;
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
)
...
...
@@ -1067,7 +1065,7 @@ static int lxc_create_ttys(struct lxc_handler *handler)
ret
=
0
;
on_error:
lxc_delete_tty
(
&
conf
->
tty
_info
);
lxc_delete_tty
(
&
conf
->
tty
s
);
return
ret
;
}
...
...
@@ -1578,7 +1576,7 @@ static int setup_personality(int persona)
}
static
int
lxc_setup_dev_console
(
const
struct
lxc_rootfs
*
rootfs
,
const
struct
lxc_
console
*
console
)
const
struct
lxc_
terminal
*
console
)
{
char
path
[
MAXPATHLEN
];
int
ret
,
fd
;
...
...
@@ -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
,
const
struct
lxc_
console
*
console
,
const
struct
lxc_
terminal
*
console
,
char
*
ttydir
)
{
int
ret
,
fd
;
...
...
@@ -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
,
const
struct
lxc_
console
*
console
,
char
*
ttydir
)
const
struct
lxc_
terminal
*
console
,
char
*
ttydir
)
{
if
(
!
ttydir
)
...
...
@@ -2615,9 +2613,9 @@ struct lxc_conf *lxc_conf_init(void)
new
->
console
.
log_size
=
0
;
new
->
console
.
path
=
NULL
;
new
->
console
.
peer
=
-
1
;
new
->
console
.
p
eerpt
y
.
busy
=
-
1
;
new
->
console
.
p
eerpt
y
.
master
=
-
1
;
new
->
console
.
p
eerpt
y
.
slave
=
-
1
;
new
->
console
.
p
rox
y
.
busy
=
-
1
;
new
->
console
.
p
rox
y
.
master
=
-
1
;
new
->
console
.
p
rox
y
.
slave
=
-
1
;
new
->
console
.
master
=
-
1
;
new
->
console
.
slave
=
-
1
;
new
->
console
.
name
[
0
]
=
'\0'
;
...
...
@@ -3786,7 +3784,7 @@ void lxc_conf_free(struct lxc_conf *conf)
return
;
if
(
current_config
==
conf
)
current_config
=
NULL
;
lxc_
pty
_conf_free
(
&
conf
->
console
);
lxc_
terminal
_conf_free
(
&
conf
->
console
);
free
(
conf
->
rootfs
.
mount
);
free
(
conf
->
rootfs
.
bdev_type
);
free
(
conf
->
rootfs
.
options
);
...
...
src/lxc/conf.h
View file @
19462d43
...
...
@@ -38,6 +38,7 @@
#include "list.h"
#include "ringbuf.h"
#include "start.h"
/* for lxc_handler */
#include "terminal.h"
#if HAVE_SCMP_FILTER_CTX
typedef
void
*
scmp_filter_ctx
;
...
...
@@ -133,73 +134,16 @@ struct id_map {
unsigned
long
hostid
,
nsid
,
range
;
};
/*
* 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
/* Defines the number of tty configured and contains the
* instantiated ptys
* @nbtty = number of configured ttys
*/
struct
lxc_tty_info
{
int
nbtty
;
struct
lxc_pty_info
*
pty_info
;
};
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
;
};
struct
lxc_terminal_info
*
tty
;
};
/*
* Defines a structure to store the rootfs location, the
/* Defines a structure to store the rootfs location, the
* optionals pivot_root, rootfs mount paths
* @path : the rootfs source (directory or device)
* @mount : where it is mounted
...
...
@@ -256,7 +200,7 @@ enum {
* @fstab : path to a fstab file format
* @caps : list of the capabilities to drop
* @keepcaps : list of the capabilities to keep
* @tty
_info
: tty data
* @tty
s
: tty data
* @console : console data
* @ttydir : directory (under /dev) in which to create console and ttys
* @lsm_aa_profile : apparmor profile to switch to or NULL
...
...
@@ -311,10 +255,10 @@ struct lxc_conf {
struct
lxc_list
mount_list
;
struct
lxc_list
caps
;
struct
lxc_list
keepcaps
;
struct
lxc_tty_info
tty
_info
;
struct
lxc_tty_info
tty
s
;
/* Comma-separated list of lxc.tty.max pty names. */
char
*
pty_names
;
struct
lxc_
console
console
;
struct
lxc_
terminal
console
;
struct
lxc_rootfs
rootfs
;
char
*
ttydir
;
int
close_all_fds
;
...
...
@@ -440,7 +384,7 @@ extern void lxc_conf_free(struct lxc_conf *conf);
extern
int
pin_rootfs
(
const
char
*
rootfs
);
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
void
lxc_delete_tty
(
struct
lxc_tty_info
*
tty
_info
);
extern
void
lxc_delete_tty
(
struct
lxc_tty_info
*
tty
s
);
extern
int
lxc_clear_config_caps
(
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
);
...
...
src/lxc/criu.c
View file @
19462d43
...
...
@@ -176,7 +176,7 @@ static void exec_criu(struct criu_opts *opts)
FILE
*
mnts
;
struct
mntent
mntent
;
char
buf
[
4096
],
tty
_info
[
32
];
char
buf
[
4096
],
tty
s
[
32
];
size_t
pos
;
/* 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)
*/
static_args
+=
6
;
tty
_info
[
0
]
=
0
;
if
(
load_tty_major_minor
(
opts
->
user
->
directory
,
tty
_info
,
sizeof
(
tty_info
)))
tty
s
[
0
]
=
0
;
if
(
load_tty_major_minor
(
opts
->
user
->
directory
,
tty
s
,
sizeof
(
ttys
)))
return
;
/* --inherit-fd fd[%d]:tty[%s] */
if
(
tty
_info
[
0
])
if
(
tty
s
[
0
])
static_args
+=
2
;
}
else
{
return
;
...
...
@@ -493,13 +493,13 @@ static void exec_criu(struct criu_opts *opts)
DECLARE_ARG
(
"--restore-detached"
);
DECLARE_ARG
(
"--restore-sibling"
);
if
(
tty
_info
[
0
])
{
if
(
tty
s
[
0
])
{
if
(
opts
->
console_fd
<
0
)
{
ERROR
(
"lxc.console.path configured on source host but not target"
);
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
,
tty
s
);
if
(
ret
<
0
||
ret
>=
sizeof
(
buf
))
goto
err
;
...
...
src/lxc/lxccontainer.c
View file @
19462d43
...
...
@@ -47,7 +47,6 @@
#include "commands_utils.h"
#include "confile.h"
#include "confile_utils.h"
#include "console.h"
#include "criu.h"
#include "error.h"
#include "initutils.h"
...
...
@@ -66,6 +65,7 @@
#include "storage/btrfs.h"
#include "storage/overlay.h"
#include "sync.h"
#include "terminal.h"
#include "utils.h"
#include "version.h"
...
...
@@ -526,7 +526,7 @@ static int do_lxcapi_console_getfd(struct lxc_container *c, int *ttynum, int *ma
if
(
!
c
)
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
*
)
...
...
src/lxc/start.c
View file @
19462d43
...
...
@@ -71,9 +71,9 @@
#include "commands_utils.h"
#include "conf.h"
#include "confile_utils.h"
#include "console.h"
#include "error.h"
#include "list.h"
#include "lsm/lsm.h"
#include "log.h"
#include "lxccontainer.h"
#include "lxclock.h"
...
...
@@ -83,11 +83,11 @@
#include "namespace.h"
#include "network.h"
#include "start.h"
#include "sync.h"
#include "utils.h"
#include "lsm/lsm.h"
#include "storage/storage.h"
#include "storage/storage_utils.h"
#include "sync.h"
#include "terminal.h"
#include "utils.h"
lxc_log_define
(
lxc_start
,
lxc
);
...
...
@@ -529,15 +529,15 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
}
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
)
{
ERROR
(
"Failed to add console handlers to mainloop"
);
goto
out_mainloop_console
;
}
ret
=
lxc_
console
_mainloop_add
(
&
descr_console
,
console
);
ret
=
lxc_
terminal
_mainloop_add
(
&
descr_console
,
console
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to add console handlers to console mainloop"
);
goto
out_mainloop_console
;
...
...
@@ -804,14 +804,14 @@ int lxc_init(const char *name, struct lxc_handler *handler)
TRACE
(
"Set up signal fd"
);
/* Do this after setting up signals since it might unblock SIGWINCH. */
ret
=
lxc_
console_create
(
conf
);
ret
=
lxc_
terminal_setup
(
conf
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to create console"
);
goto
out_restore_sigmask
;
}
TRACE
(
"Created console"
);
ret
=
lxc_
pty
_map_ids
(
conf
,
&
conf
->
console
);
ret
=
lxc_
terminal
_map_ids
(
conf
,
&
conf
->
console
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to chown console"
);
goto
out_restore_sigmask
;
...
...
@@ -824,7 +824,7 @@ int lxc_init(const char *name, struct lxc_handler *handler)
out_restore_sigmask:
sigprocmask
(
SIG_SETMASK
,
&
handler
->
oldmask
,
NULL
);
out_delete_tty:
lxc_delete_tty
(
&
conf
->
tty
_info
);
lxc_delete_tty
(
&
conf
->
tty
s
);
out_aborting:
lxc_set_state
(
name
,
handler
,
ABORTING
);
out_close_maincmd_fd:
...
...
@@ -950,8 +950,8 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
if
(
ret
<
0
)
WARN
(
"%s - Failed to restore signal mask"
,
strerror
(
errno
));
lxc_
console
_delete
(
&
handler
->
conf
->
console
);
lxc_delete_tty
(
&
handler
->
conf
->
tty
_info
);
lxc_
terminal
_delete
(
&
handler
->
conf
->
console
);
lxc_delete_tty
(
&
handler
->
conf
->
tty
s
);
/* The command socket is now closed, no more state clients can register
* themselves from now on. So free the list of state clients.
...
...
@@ -1198,14 +1198,14 @@ static int do_start(void *data)
/* 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
* 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.
*/
if
(
handler
->
conf
->
console
.
slave
>=
0
)
{
if
(
handler
->
backgrounded
||
handler
->
conf
->
is_execute
==
0
)
ret
=
set_stdfds
(
handler
->
conf
->
console
.
slave
);
else
ret
=
lxc_
console
_set_stdfds
(
handler
->
conf
->
console
.
slave
);
ret
=
lxc_
terminal
_set_stdfds
(
handler
->
conf
->
console
.
slave
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to redirect std{in,out,err} to pty file "
"descriptor %d"
,
handler
->
conf
->
console
.
slave
);
...
...
@@ -1340,17 +1340,17 @@ out_error:
static
int
lxc_recv_ttys_from_child
(
struct
lxc_handler
*
handler
)
{
int
i
;
struct
lxc_
pty_info
*
pty_info
;
struct
lxc_
terminal_info
*
tty
;
int
ret
=
-
1
;
int
sock
=
handler
->
data_sock
[
1
];
struct
lxc_conf
*
conf
=
handler
->
conf
;
struct
lxc_tty_info
*
tty
_info
=
&
conf
->
tty_info
;
struct
lxc_tty_info
*
tty
s
=
&
conf
->
ttys
;
if
(
!
conf
->
tty
)
return
0
;
tty
_info
->
pty_info
=
malloc
(
sizeof
(
*
tty_info
->
pty_info
)
*
conf
->
tty
);
if
(
!
tty
_info
->
pty_info
)
tty
s
->
tty
=
malloc
(
sizeof
(
*
ttys
->
tty
)
*
conf
->
tty
);
if
(
!
tty
s
->
tty
)
return
-
1
;
for
(
i
=
0
;
i
<
conf
->
tty
;
i
++
)
{
...
...
@@ -1360,12 +1360,12 @@ static int lxc_recv_ttys_from_child(struct lxc_handler *handler)
if
(
ret
<
0
)
break
;
pty_info
=
&
tty_info
->
pty_info
[
i
];
pty_info
->
busy
=
0
;
pty_info
->
master
=
ttyfds
[
0
];
pty_info
->
slave
=
ttyfds
[
1
];
tty
=
&
ttys
->
tty
[
i
];
tty
->
busy
=
0
;
tty
->
master
=
ttyfds
[
0
];
tty
->
slave
=
ttyfds
[
1
];
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
)
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)
else
TRACE
(
"Received %d ttys from child"
,
conf
->
tty
);
tty
_info
->
nbtty
=
conf
->
tty
;
tty
s
->
nbtty
=
conf
->
tty
;
return
ret
;
}
...
...
src/lxc/
console
.c
→
src/lxc/
terminal
.c
View file @
19462d43
...
...
@@ -38,11 +38,11 @@
#include "commands.h"
#include "conf.h"
#include "config.h"
#include "console.h"
#include "log.h"
#include "lxclock.h"
#include "mainloop.h"
#include "start.h"
/* for struct lxc_handler */
#include "terminal.h"
#include "utils.h"
#if HAVE_PTY_H
...
...
@@ -51,20 +51,20 @@
#include <../include/openpty.h>
#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
;
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
);
}
void
lxc_
console
_winsz
(
int
srcfd
,
int
dstfd
)
void
lxc_
terminal
_winsz
(
int
srcfd
,
int
dstfd
)
{
int
ret
;
struct
winsize
wsz
;
...
...
@@ -88,31 +88,31 @@ void lxc_console_winsz(int srcfd, int dstfd)
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
)
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_t
ty
_state
*
ts
;
struct
lxc_t
erminal
_state
*
ts
;
lxc_list_for_each
(
it
,
&
lxc_ttys
)
{
ts
=
it
->
elem
;
lxc_
console
_winch
(
ts
);
lxc_
terminal
_winch
(
ts
);
}
}
int
lxc_
console_cb_signal_fd
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
struct
lxc_epoll_descr
*
descr
)
int
lxc_
terminal_signalfd_cb
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
struct
lxc_epoll_descr
*
descr
)
{
ssize_t
ret
;
struct
signalfd_siginfo
siginfo
;
struct
lxc_t
ty
_state
*
ts
=
cbdata
;
struct
lxc_t
erminal
_state
*
ts
=
cbdata
;
ret
=
read
(
fd
,
&
siginfo
,
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,
}
if
(
siginfo
.
ssi_signo
==
SIGTERM
)
{
DEBUG
(
"Received SIGTERM. Detaching from the
console
"
);
DEBUG
(
"Received SIGTERM. Detaching from the
terminal
"
);
return
LXC_MAINLOOP_CLOSE
;
}
if
(
siginfo
.
ssi_signo
==
SIGWINCH
)
lxc_
console
_winch
(
ts
);
lxc_
terminal
_winch
(
ts
);
return
0
;
}
struct
lxc_t
ty_state
*
lxc_console
_signal_init
(
int
srcfd
,
int
dstfd
)
struct
lxc_t
erminal_state
*
lxc_terminal
_signal_init
(
int
srcfd
,
int
dstfd
)
{
int
ret
;
bool
istty
;
sigset_t
mask
;
struct
lxc_t
ty
_state
*
ts
;
struct
lxc_t
erminal
_state
*
ts
;
ts
=
malloc
(
sizeof
(
*
ts
));
if
(
!
ts
)
...
...
@@ -189,7 +189,7 @@ on_error:
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
)
{
close
(
ts
->
sigfd
);
...
...
@@ -204,65 +204,65 @@ void lxc_console_signal_fini(struct lxc_tty_state *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 */
if
(
!
console
->
log_path
||
console
->
log_fd
<
0
)
if
(
!
terminal
->
log_path
||
terminal
->
log_fd
<
0
)
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
;
size_t
len
;
char
*
tmp
;
if
(
!
console
->
log_path
||
console
->
log_rotate
==
0
)
if
(
!
terminal
->
log_path
||
terminal
->
log_rotate
==
0
)
return
-
EOPNOTSUPP
;
/* be very certain things are kosher */
if
(
console
->
log_fd
<
0
)
if
(
terminal
->
log_fd
<
0
)
return
-
EBADF
;
len
=
strlen
(
console
->
log_path
)
+
sizeof
(
".1"
);
len
=
strlen
(
terminal
->
log_path
)
+
sizeof
(
".1"
);
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
)
return
-
EFBIG
;
close
(
console
->
log_fd
);
console
->
log_fd
=
-
1
;
ret
=
lxc_unpriv
(
rename
(
console
->
log_path
,
tmp
));
close
(
terminal
->
log_fd
);
terminal
->
log_fd
=
-
1
;
ret
=
lxc_unpriv
(
rename
(
terminal
->
log_path
,
tmp
));
if
(
ret
<
0
)
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
ret
;
int64_t
space_left
=
-
1
;
struct
stat
st
;
if
(
console
->
log_fd
<
0
)
if
(
terminal
->
log_fd
<
0
)
return
0
;
/* 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
* be rotated or not.
*/
if
(
console
->
log_size
<=
0
)
return
lxc_write_nointr
(
console
->
log_fd
,
buf
,
bytes_read
);
if
(
terminal
->
log_size
<=
0
)
return
lxc_write_nointr
(
terminal
->
log_fd
,
buf
,
bytes_read
);
/* Get current size of the log file. */
ret
=
fstat
(
console
->
log_fd
,
&
st
);
ret
=
fstat
(
terminal
->
log_fd
,
&
st
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to stat the
console
log file descriptor"
);
SYSERROR
(
"Failed to stat the
terminal
log file descriptor"
);
return
-
1
;
}
...
...
@@ -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
* 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
;
/* 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
* left so simply truncate it.
*/
if
(
space_left
<=
0
&&
console
->
log_rotate
<=
0
)
{
ret
=
lxc_
console_truncate_log_file
(
console
);
if
(
space_left
<=
0
&&
terminal
->
log_rotate
<=
0
)
{
ret
=
lxc_
terminal_truncate_log_file
(
terminal
);
if
(
ret
<
0
)
return
ret
;
if
(
bytes_read
<=
console
->
log_size
)
return
lxc_write_nointr
(
console
->
log_fd
,
buf
,
bytes_read
);
if
(
bytes_read
<=
terminal
->
log_size
)
return
lxc_write_nointr
(
terminal
->
log_fd
,
buf
,
bytes_read
);
/* 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. */
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
* 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
)
return
-
1
;
...
...
@@ -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
* file so simply return. There's no error on our side here.
*/
if
(
console
->
log_rotate
>
0
)
ret
=
lxc_
console_rotate_log_file
(
console
);
if
(
terminal
->
log_rotate
>
0
)
ret
=
lxc_
terminal_rotate_log_file
(
terminal
);
else
ret
=
lxc_
console_truncate_log_file
(
console
);
ret
=
lxc_
terminal_truncate_log_file
(
terminal
);
if
(
ret
<
0
)
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
* to write than the user has granted us space. There are
* 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
* stuff to write and move on.
* 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
* should be read and written.
*/
WARN
(
"Size of
console
log file is smaller than the bytes to write"
);
ret
=
lxc_write_nointr
(
console
->
log_fd
,
buf
,
console
->
log_size
);
WARN
(
"Size of
terminal
log file is smaller than the bytes to write"
);
ret
=
lxc_write_nointr
(
terminal
->
log_fd
,
buf
,
terminal
->
log_size
);
if
(
ret
<
0
)
return
-
1
;
bytes_read
-=
ret
;
...
...
@@ -341,33 +341,33 @@ static int lxc_console_write_log_file(struct lxc_console *console, char *buf,
}
/* 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
)
return
-
1
;
bytes_read
-=
ret
;
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_
console
*
console
=
(
struct
lxc_console
*
)
data
;
char
buf
[
LXC_
CONSOLE
_BUFFER_SIZE
];
struct
lxc_
terminal
*
terminal
=
data
;
char
buf
[
LXC_
TERMINAL
_BUFFER_SIZE
];
int
r
,
w
,
w_log
,
w_rbuf
;
w
=
r
=
lxc_read_nointr
(
fd
,
buf
,
sizeof
(
buf
));
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
);
if
(
fd
==
console
->
master
)
{
console
->
master
=
-
EBADF
;
}
else
if
(
fd
==
console
->
peer
)
{
if
(
console
->
tty_state
)
{
lxc_
console_signal_fini
(
console
->
tty_state
);
console
->
tty_state
=
NULL
;
if
(
fd
==
terminal
->
master
)
{
terminal
->
master
=
-
EBADF
;
}
else
if
(
fd
==
terminal
->
peer
)
{
if
(
terminal
->
tty_state
)
{
lxc_
terminal_signal_fini
(
terminal
->
tty_state
);
terminal
->
tty_state
=
NULL
;
}
console
->
peer
=
-
EBADF
;
terminal
->
peer
=
-
EBADF
;
}
else
{
ERROR
(
"Handler received unexpected file descriptor"
);
}
...
...
@@ -376,55 +376,55 @@ int lxc_console_cb_con(int fd, uint32_t events, void *data,
return
LXC_MAINLOOP_CLOSE
;
}
if
(
fd
==
console
->
peer
)
w
=
lxc_write_nointr
(
console
->
master
,
buf
,
r
);
if
(
fd
==
terminal
->
peer
)
w
=
lxc_write_nointr
(
terminal
->
master
,
buf
,
r
);
w_rbuf
=
w_log
=
0
;
if
(
fd
==
console
->
master
)
{
if
(
fd
==
terminal
->
master
)
{
/* write to peer first */
if
(
console
->
peer
>=
0
)
w
=
lxc_write_nointr
(
console
->
peer
,
buf
,
r
);
if
(
terminal
->
peer
>=
0
)
w
=
lxc_write_nointr
(
terminal
->
peer
,
buf
,
r
);
/* write to console ringbuffer */
if
(
console
->
buffer_size
>
0
)
w_rbuf
=
lxc_ringbuf_write
(
&
console
->
ringbuf
,
buf
,
r
);
if
(
console
->
log_fd
>
0
)
w_log
=
lxc_console_write_log_file
(
console
,
buf
,
r
);
/* write to terminal ringbuffer */
if
(
terminal
->
buffer_size
>
0
)
w_rbuf
=
lxc_ringbuf_write
(
&
terminal
->
ringbuf
,
buf
,
r
);
/* write to terminal log */
if
(
terminal
->
log_fd
>=
0
)
w_log
=
lxc_terminal_write_log_file
(
terminal
,
buf
,
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
)
TRACE
(
"%s - Failed to write %d bytes to
console
ringbuffer"
,
TRACE
(
"%s - Failed to write %d bytes to
terminal
ringbuffer"
,
strerror
(
-
w_rbuf
),
r
);
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
;
}
static
int
lxc_
console_mainloop_add_peer
(
struct
lxc_console
*
console
)
static
int
lxc_
terminal_mainloop_add_peer
(
struct
lxc_terminal
*
terminal
)
{
int
ret
;
if
(
console
->
peer
>=
0
)
{
ret
=
lxc_mainloop_add_handler
(
console
->
descr
,
console
->
peer
,
lxc_
console_cb_con
,
console
);
if
(
terminal
->
peer
>=
0
)
{
ret
=
lxc_mainloop_add_handler
(
terminal
->
descr
,
terminal
->
peer
,
lxc_
terminal_io_cb
,
terminal
);
if
(
ret
<
0
)
{
WARN
(
"Failed to add
console
peer handler to mainloop"
);
WARN
(
"Failed to add
terminal
peer handler to mainloop"
);
return
-
1
;
}
}
if
(
!
console
->
tty_state
||
console
->
tty_state
->
sigfd
<
0
)
if
(
!
terminal
->
tty_state
||
terminal
->
tty_state
->
sigfd
<
0
)
return
0
;
ret
=
lxc_mainloop_add_handler
(
console
->
descr
,
console
->
tty_state
->
sigfd
,
lxc_
console_cb_signal_fd
,
console
->
tty_state
);
ret
=
lxc_mainloop_add_handler
(
terminal
->
descr
,
terminal
->
tty_state
->
sigfd
,
lxc_
terminal_signalfd_cb
,
terminal
->
tty_state
);
if
(
ret
<
0
)
{
WARN
(
"Failed to add signal handler to mainloop"
);
return
-
1
;
...
...
@@ -433,28 +433,28 @@ static int lxc_console_mainloop_add_peer(struct lxc_console *console)
return
0
;
}
int
lxc_
console
_mainloop_add
(
struct
lxc_epoll_descr
*
descr
,
struct
lxc_
console
*
console
)
int
lxc_
terminal
_mainloop_add
(
struct
lxc_epoll_descr
*
descr
,
struct
lxc_
terminal
*
terminal
)
{
int
ret
;
if
(
console
->
master
<
0
)
{
INFO
(
"
no console
"
);
if
(
terminal
->
master
<
0
)
{
INFO
(
"
Terminal is not initialized
"
);
return
0
;
}
ret
=
lxc_mainloop_add_handler
(
descr
,
console
->
master
,
lxc_
console_cb_con
,
console
);
ret
=
lxc_mainloop_add_handler
(
descr
,
terminal
->
master
,
lxc_
terminal_io_cb
,
terminal
);
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
;
}
/* 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
;
ret
=
lxc_
console_mainloop_add_peer
(
console
);
terminal
->
descr
=
descr
;
ret
=
lxc_
terminal_mainloop_add_peer
(
terminal
);
if
(
ret
<
0
)
return
-
1
;
...
...
@@ -509,90 +509,90 @@ int lxc_setup_tios(int fd, struct termios *oldtios)
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
)
{
lxc_
console_signal_fini
(
console
->
tty_state
);
console
->
tty_state
=
NULL
;
if
(
terminal
->
tty_state
)
{
lxc_
terminal_signal_fini
(
terminal
->
tty_state
);
terminal
->
tty_state
=
NULL
;
}
close
(
console
->
peerpt
y
.
master
);
close
(
console
->
peerpt
y
.
slave
);
console
->
peerpt
y
.
master
=
-
1
;
console
->
peerpt
y
.
slave
=
-
1
;
console
->
peerpt
y
.
busy
=
-
1
;
console
->
peerpt
y
.
name
[
0
]
=
'\0'
;
console
->
peer
=
-
1
;
close
(
terminal
->
prox
y
.
master
);
close
(
terminal
->
prox
y
.
slave
);
terminal
->
prox
y
.
master
=
-
1
;
terminal
->
prox
y
.
slave
=
-
1
;
terminal
->
prox
y
.
busy
=
-
1
;
terminal
->
prox
y
.
name
[
0
]
=
'\0'
;
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
lxc_t
ty
_state
*
ts
;
struct
lxc_t
erminal
_state
*
ts
;
int
ret
;
if
(
console
->
master
<
0
)
{
ERROR
(
"
console
not set up"
);
if
(
terminal
->
master
<
0
)
{
ERROR
(
"
Terminal
not set up"
);
return
-
1
;
}
if
(
console
->
peerpty
.
busy
!=
-
1
||
console
->
peer
!=
-
1
)
{
NOTICE
(
"
console
already in use"
);
if
(
terminal
->
proxy
.
busy
!=
-
1
||
terminal
->
peer
!=
-
1
)
{
NOTICE
(
"
Terminal
already in use"
);
return
-
1
;
}
if
(
console
->
tty_state
)
{
ERROR
(
"
console
already has tty_state"
);
if
(
terminal
->
tty_state
)
{
ERROR
(
"
Terminal
already has tty_state"
);
return
-
1
;
}
/* this is the proxy pty that will be given to the client, and that
* the real pty master will send to / recv from
*/
ret
=
openpty
(
&
console
->
peerpty
.
master
,
&
console
->
peerpt
y
.
slave
,
console
->
peerpt
y
.
name
,
NULL
,
NULL
);
ret
=
openpty
(
&
terminal
->
proxy
.
master
,
&
terminal
->
prox
y
.
slave
,
terminal
->
prox
y
.
name
,
NULL
,
NULL
);
if
(
ret
)
{
SYSERROR
(
"failed to create proxy pty"
);
return
-
1
;
}
if
(
lxc_setup_tios
(
console
->
peerpt
y
.
slave
,
&
oldtermio
)
<
0
)
if
(
lxc_setup_tios
(
terminal
->
prox
y
.
slave
,
&
oldtermio
)
<
0
)
goto
err1
;
ts
=
lxc_
console_signal_init
(
console
->
peerpty
.
master
,
console
->
master
);
ts
=
lxc_
terminal_signal_init
(
terminal
->
proxy
.
master
,
terminal
->
master
);
if
(
!
ts
)
goto
err1
;
console
->
tty_state
=
ts
;
console
->
peer
=
console
->
peerpt
y
.
slave
;
console
->
peerpt
y
.
busy
=
sockfd
;
ret
=
lxc_
console_mainloop_add_peer
(
console
);
terminal
->
tty_state
=
ts
;
terminal
->
peer
=
terminal
->
prox
y
.
slave
;
terminal
->
prox
y
.
busy
=
sockfd
;
ret
=
lxc_
terminal_mainloop_add_peer
(
terminal
);
if
(
ret
<
0
)
goto
err1
;
DEBUG
(
"%d
%s peermaster:%d sockfd:%d"
,
lxc_raw_getpid
(),
__FUNCTION__
,
console
->
peerpt
y
.
master
,
sockfd
);
DEBUG
(
"%d
peermaster:%d sockfd:%d"
,
lxc_raw_getpid
(),
terminal
->
prox
y
.
master
,
sockfd
);
return
0
;
err1
:
lxc_
console_peer_proxy_free
(
console
);
lxc_
terminal_peer_proxy_free
(
terminal
);
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
;
struct
lxc_tty_info
*
tty
_info
=
&
conf
->
tty_info
;
struct
lxc_
console
*
console
=
&
conf
->
console
;
struct
lxc_tty_info
*
tty
s
=
&
conf
->
ttys
;
struct
lxc_
terminal
*
terminal
=
&
conf
->
console
;
if
(
*
ttyreq
==
0
)
{
if
(
lxc_
console_peer_proxy_alloc
(
console
,
sockfd
)
<
0
)
if
(
lxc_
terminal_peer_proxy_alloc
(
terminal
,
sockfd
)
<
0
)
goto
out
;
masterfd
=
console
->
peerpt
y
.
master
;
masterfd
=
terminal
->
prox
y
.
master
;
goto
out
;
}
if
(
*
ttyreq
>
0
)
{
if
(
*
ttyreq
>
tty
_info
->
nbtty
)
if
(
*
ttyreq
>
tty
s
->
nbtty
)
goto
out
;
if
(
tty
_info
->
pty_info
[
*
ttyreq
-
1
].
busy
)
if
(
tty
s
->
tty
[
*
ttyreq
-
1
].
busy
)
goto
out
;
/* the requested tty is available */
...
...
@@ -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] */
for
(
ttynum
=
1
;
ttynum
<=
tty
_info
->
nbtty
&&
tty_info
->
pty_info
[
ttynum
-
1
].
busy
;
ttynum
++
)
for
(
ttynum
=
1
;
ttynum
<=
tty
s
->
nbtty
&&
ttys
->
tty
[
ttynum
-
1
].
busy
;
ttynum
++
)
;
/* we didn't find any available slot for tty */
if
(
ttynum
>
tty
_info
->
nbtty
)
if
(
ttynum
>
tty
s
->
nbtty
)
goto
out
;
*
ttyreq
=
ttynum
;
out_tty
:
tty
_info
->
pty_info
[
ttynum
-
1
].
busy
=
sockfd
;
masterfd
=
tty
_info
->
pty_info
[
ttynum
-
1
].
master
;
tty
s
->
tty
[
ttynum
-
1
].
busy
=
sockfd
;
masterfd
=
tty
s
->
tty
[
ttynum
-
1
].
master
;
out
:
return
masterfd
;
}
void
lxc_
console
_free
(
struct
lxc_conf
*
conf
,
int
fd
)
void
lxc_
terminal
_free
(
struct
lxc_conf
*
conf
,
int
fd
)
{
int
i
;
struct
lxc_tty_info
*
tty
_info
=
&
conf
->
tty_info
;
struct
lxc_
console
*
console
=
&
conf
->
console
;
struct
lxc_tty_info
*
tty
s
=
&
conf
->
ttys
;
struct
lxc_
terminal
*
terminal
=
&
conf
->
console
;
for
(
i
=
0
;
i
<
tty
_info
->
nbtty
;
i
++
)
{
if
(
tty
_info
->
pty_info
[
i
].
busy
==
fd
)
tty
_info
->
pty_info
[
i
].
busy
=
0
;
for
(
i
=
0
;
i
<
tty
s
->
nbtty
;
i
++
)
{
if
(
tty
s
->
tty
[
i
].
busy
==
fd
)
tty
s
->
tty
[
i
].
busy
=
0
;
}
if
(
console
->
peerpt
y
.
busy
==
fd
)
{
lxc_mainloop_del_handler
(
console
->
descr
,
console
->
peerpt
y
.
slave
);
lxc_
console_peer_proxy_free
(
console
);
if
(
terminal
->
prox
y
.
busy
==
fd
)
{
lxc_mainloop_del_handler
(
terminal
->
descr
,
terminal
->
prox
y
.
slave
);
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_t
ty
_state
*
ts
;
const
char
*
path
=
console
->
path
;
struct
lxc_t
erminal
_state
*
ts
;
const
char
*
path
=
terminal
->
path
;
int
fd
;
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).
*/
if
(
!
path
&&
!
access
(
"/dev/tty"
,
F_OK
))
{
...
...
@@ -658,129 +658,125 @@ static int lxc_console_peer_default(struct lxc_console *console)
goto
out
;
}
console
->
peer
=
lxc_unpriv
(
open
(
path
,
O_RDWR
|
O_CLOEXEC
));
if
(
console
->
peer
<
0
)
{
terminal
->
peer
=
lxc_unpriv
(
open
(
path
,
O_RDWR
|
O_CLOEXEC
));
if
(
terminal
->
peer
<
0
)
{
ERROR
(
"Failed to open
\"
%s
\"
: %s"
,
path
,
strerror
(
errno
));
return
-
ENOTTY
;
}
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
);
goto
on_error1
;
}
ts
=
lxc_
console_signal_init
(
console
->
peer
,
console
->
master
);
console
->
tty_state
=
ts
;
ts
=
lxc_
terminal_signal_init
(
terminal
->
peer
,
terminal
->
master
);
terminal
->
tty_state
=
ts
;
if
(
!
ts
)
{
WARN
(
"Failed to install signal handler"
);
goto
on_error1
;
}
lxc_
console_winsz
(
console
->
peer
,
console
->
master
);
lxc_
terminal_winsz
(
terminal
->
peer
,
terminal
->
master
);
console
->
tios
=
malloc
(
sizeof
(
*
console
->
tios
));
if
(
!
console
->
tios
)
{
terminal
->
tios
=
malloc
(
sizeof
(
*
terminal
->
tios
));
if
(
!
terminal
->
tios
)
{
SYSERROR
(
"failed to allocate memory"
);
goto
on_error1
;
}
if
(
lxc_setup_tios
(
console
->
peer
,
console
->
tios
)
<
0
)
if
(
lxc_setup_tios
(
terminal
->
peer
,
terminal
->
tios
)
<
0
)
goto
on_error2
;
else
goto
out
;
on_error2
:
free
(
console
->
tios
);
console
->
tios
=
NULL
;
free
(
terminal
->
tios
);
terminal
->
tios
=
NULL
;
on_error1
:
close
(
console
->
peer
);
console
->
peer
=
-
1
;
close
(
terminal
->
peer
);
terminal
->
peer
=
-
1
;
ret
=
-
ENOTTY
;
out
:
return
ret
;
}
int
lxc_
console_write_ringbuffer
(
struct
lxc_console
*
console
)
int
lxc_
terminal_write_ringbuffer
(
struct
lxc_terminal
*
terminal
)
{
char
*
r_addr
;
ssize_t
ret
;
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. */
if
(
console
->
log_fd
<
0
)
return
0
;
/* The log file is simply appended to. */
if
(
console
->
log_size
==
0
)
if
(
terminal
->
log_fd
<
0
)
return
0
;
used
=
lxc_ringbuf_used
(
buf
);
if
(
used
==
0
)
return
0
;
ret
=
lxc_
console_truncate_log_file
(
console
);
ret
=
lxc_
terminal_truncate_log_file
(
terminal
);
if
(
ret
<
0
)
return
ret
;
/* Write as much as we can without exceeding the limit. */
if
(
console
->
log_size
<
used
)
used
=
console
->
log_size
;
if
(
terminal
->
log_size
<
used
)
used
=
terminal
->
log_size
;
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
)
return
-
EIO
;
return
0
;
}
void
lxc_
console_delete
(
struct
lxc_console
*
console
)
void
lxc_
terminal_delete
(
struct
lxc_terminal
*
terminal
)
{
int
ret
;
ret
=
lxc_
console_write_ringbuffer
(
console
);
ret
=
lxc_
terminal_write_ringbuffer
(
terminal
);
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
)
{
ret
=
tcsetattr
(
console
->
peer
,
TCSAFLUSH
,
console
->
tios
);
if
(
terminal
->
tios
&&
terminal
->
peer
>=
0
)
{
ret
=
tcsetattr
(
terminal
->
peer
,
TCSAFLUSH
,
terminal
->
tios
);
if
(
ret
<
0
)
WARN
(
"%s - Failed to set old terminal settings"
,
strerror
(
errno
));
}
free
(
console
->
tios
);
console
->
tios
=
NULL
;
free
(
terminal
->
tios
);
terminal
->
tios
=
NULL
;
if
(
console
->
peer
>=
0
)
close
(
console
->
peer
);
console
->
peer
=
-
1
;
if
(
terminal
->
peer
>=
0
)
close
(
terminal
->
peer
);
terminal
->
peer
=
-
1
;
if
(
console
->
master
>=
0
)
close
(
console
->
master
);
console
->
master
=
-
1
;
if
(
terminal
->
master
>=
0
)
close
(
terminal
->
master
);
terminal
->
master
=
-
1
;
if
(
console
->
slave
>=
0
)
close
(
console
->
slave
);
console
->
slave
=
-
1
;
if
(
terminal
->
slave
>=
0
)
close
(
terminal
->
slave
);
terminal
->
slave
=
-
1
;
if
(
console
->
log_fd
>=
0
)
close
(
console
->
log_fd
);
console
->
log_fd
=
-
1
;
if
(
terminal
->
log_fd
>=
0
)
close
(
terminal
->
log_fd
);
terminal
->
log_fd
=
-
1
;
}
/**
* 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
* the
console
handler needs to see an allocated ringbuffer.
* register a handler for the
terminal
's masterfd when we create the mainloop
* 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
;
struct
lxc_ringbuf
*
buf
=
&
console
->
ringbuf
;
uint64_t
size
=
console
->
buffer_size
;
struct
lxc_ringbuf
*
buf
=
&
terminal
->
ringbuf
;
uint64_t
size
=
terminal
->
buffer_size
;
/* no ringbuffer previously allocated and no ringbuffer requested */
if
(
!
buf
->
addr
&&
size
<=
0
)
...
...
@@ -793,7 +789,7 @@ static int lxc_console_create_ringbuf(struct lxc_console *console)
buf
->
r_off
=
0
;
buf
->
w_off
=
0
;
buf
->
size
=
0
;
TRACE
(
"Deallocated
console
ringbuffer"
);
TRACE
(
"Deallocated
terminal
ringbuffer"
);
return
0
;
}
...
...
@@ -802,46 +798,46 @@ static int lxc_console_create_ringbuf(struct lxc_console *console)
/* check wether the requested size for the ringbuffer has changed */
if
(
buf
->
addr
&&
buf
->
size
!=
size
)
{
TRACE
(
"
Console
ringbuffer size changed from %"
PRIu64
" to %"
PRIu64
" bytes. Deallocating
console
ringbuffer"
,
TRACE
(
"
Terminal
ringbuffer size changed from %"
PRIu64
" to %"
PRIu64
" bytes. Deallocating
terminal
ringbuffer"
,
buf
->
size
,
size
);
lxc_ringbuf_release
(
buf
);
}
ret
=
lxc_ringbuf_create
(
buf
,
size
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to setup %"
PRIu64
" byte
console
ringbuffer"
,
size
);
ERROR
(
"Failed to setup %"
PRIu64
" byte
terminal
ringbuffer"
,
size
);
return
-
1
;
}
TRACE
(
"Allocated %"
PRIu64
" byte
console
ringbuffer"
,
size
);
TRACE
(
"Allocated %"
PRIu64
" byte
terminal
ringbuffer"
,
size
);
return
0
;
}
/**
* This is the
console log file. Please note that the console
log file is
* (implementation wise not content wise) independent of the
console
ringbuffer.
* This is the
terminal log file. Please note that the terminal
log file is
* (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
;
console
->
log_fd
=
lxc_unpriv
(
open
(
console
->
log_path
,
O_CLOEXEC
|
O_RDWR
|
O_CREAT
|
O_APPEND
,
0600
));
if
(
console
->
log_fd
<
0
)
{
SYSERROR
(
"Failed to open
console log file
\"
%s
\"
"
,
console
->
log_path
);
terminal
->
log_fd
=
lxc_unpriv
(
open
(
terminal
->
log_path
,
O_CLOEXEC
|
O_RDWR
|
O_CREAT
|
O_APPEND
,
0600
));
if
(
terminal
->
log_fd
<
0
)
{
SYSERROR
(
"Failed to open
terminal log file
\"
%s
\"
"
,
terminal
->
log_path
);
return
-
1
;
}
DEBUG
(
"Using
\"
%s
\"
as
console log file"
,
console
->
log_path
);
DEBUG
(
"Using
\"
%s
\"
as
terminal log file"
,
terminal
->
log_path
);
return
0
;
}
int
lxc_
pty_create
(
struct
lxc_console
*
console
)
int
lxc_
terminal_create
(
struct
lxc_terminal
*
terminal
)
{
int
ret
,
saved_errno
;
ret
=
openpty
(
&
console
->
master
,
&
console
->
slave
,
console
->
name
,
NULL
,
ret
=
openpty
(
&
terminal
->
master
,
&
terminal
->
slave
,
terminal
->
name
,
NULL
,
NULL
);
saved_errno
=
errno
;
if
(
ret
<
0
)
{
...
...
@@ -849,19 +845,19 @@ int lxc_pty_create(struct lxc_console *console)
return
-
1
;
}
ret
=
fcntl
(
console
->
master
,
F_SETFD
,
FD_CLOEXEC
);
ret
=
fcntl
(
terminal
->
master
,
F_SETFD
,
FD_CLOEXEC
);
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
;
}
ret
=
fcntl
(
console
->
slave
,
F_SETFD
,
FD_CLOEXEC
);
ret
=
fcntl
(
terminal
->
slave
,
F_SETFD
,
FD_CLOEXEC
);
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
;
}
ret
=
lxc_
console_peer_default
(
console
);
ret
=
lxc_
terminal_peer_default
(
terminal
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to allocate a peer pty device"
);
goto
err
;
...
...
@@ -870,42 +866,42 @@ int lxc_pty_create(struct lxc_console *console)
return
0
;
err
:
lxc_
console_delete
(
console
);
lxc_
terminal_delete
(
terminal
);
return
-
ENODEV
;
}
int
lxc_
console_create
(
struct
lxc_conf
*
conf
)
int
lxc_
terminal_setup
(
struct
lxc_conf
*
conf
)
{
int
ret
;
struct
lxc_
console
*
console
=
&
conf
->
console
;
struct
lxc_
terminal
*
terminal
=
&
conf
->
console
;
if
(
console
->
path
&&
!
strcmp
(
console
->
path
,
"none"
))
{
INFO
(
"No
console
was requested"
);
if
(
terminal
->
path
&&
!
strcmp
(
terminal
->
path
,
"none"
))
{
INFO
(
"No
terminal
was requested"
);
return
0
;
}
ret
=
lxc_
pty_create
(
console
);
ret
=
lxc_
terminal_create
(
terminal
);
if
(
ret
<
0
)
return
-
1
;
/* create
console
log file */
ret
=
lxc_
console_create_log_file
(
console
);
/* create
terminal
log file */
ret
=
lxc_
terminal_create_log_file
(
terminal
);
if
(
ret
<
0
)
goto
err
;
/* create
console
ringbuffer */
ret
=
lxc_
console_create_ringbuf
(
console
);
/* create
terminal
ringbuffer */
ret
=
lxc_
terminal_create_ringbuf
(
terminal
);
if
(
ret
<
0
)
goto
err
;
return
0
;
err
:
lxc_
console_delete
(
console
);
lxc_
terminal_delete
(
terminal
);
return
-
ENODEV
;
}
int
lxc_
console
_set_stdfds
(
int
fd
)
int
lxc_
terminal
_set_stdfds
(
int
fd
)
{
if
(
fd
<
0
)
return
0
;
...
...
@@ -931,10 +927,10 @@ int lxc_console_set_stdfds(int fd)
return
0
;
}
int
lxc_
console_cb_tty_stdin
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
struct
lxc_epoll_descr
*
descr
)
int
lxc_
terminal_stdin_cb
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
struct
lxc_epoll_descr
*
descr
)
{
struct
lxc_t
ty
_state
*
ts
=
cbdata
;
struct
lxc_t
erminal
_state
*
ts
=
cbdata
;
char
c
;
if
(
fd
!=
ts
->
stdinfd
)
...
...
@@ -944,7 +940,7 @@ int lxc_console_cb_tty_stdin(int fd, uint32_t events, void *cbdata,
return
LXC_MAINLOOP_CLOSE
;
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
)
{
ts
->
saw_escape
=
1
;
return
0
;
...
...
@@ -962,11 +958,11 @@ int lxc_console_cb_tty_stdin(int fd, uint32_t events, void *cbdata,
return
0
;
}
int
lxc_
console_cb_tty_master
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
struct
lxc_epoll_descr
*
descr
)
int
lxc_
terminal_master_cb
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
struct
lxc_epoll_descr
*
descr
)
{
struct
lxc_t
ty
_state
*
ts
=
cbdata
;
char
buf
[
LXC_
CONSOLE
_BUFFER_SIZE
];
struct
lxc_t
erminal
_state
*
ts
=
cbdata
;
char
buf
[
LXC_
TERMINAL
_BUFFER_SIZE
];
int
r
,
w
;
if
(
fd
!=
ts
->
masterfd
)
...
...
@@ -987,7 +983,7 @@ int lxc_console_cb_tty_master(int fd, uint32_t events, void *cbdata,
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
);
}
...
...
@@ -999,7 +995,7 @@ int lxc_console(struct lxc_container *c, int ttynum,
int
ret
,
ttyfd
,
masterfd
;
struct
lxc_epoll_descr
descr
;
struct
termios
oldtios
;
struct
lxc_t
ty
_state
*
ts
;
struct
lxc_t
erminal
_state
*
ts
;
int
istty
=
0
;
ttyfd
=
lxc_cmd_console
(
c
->
name
,
&
ttynum
,
&
masterfd
,
c
->
config_path
);
...
...
@@ -1010,7 +1006,7 @@ int lxc_console(struct lxc_container *c, int ttynum,
if
(
ret
<
0
)
TRACE
(
"Process is already group leader"
);
ts
=
lxc_
console
_signal_init
(
stdinfd
,
masterfd
);
ts
=
lxc_
terminal
_signal_init
(
stdinfd
,
masterfd
);
if
(
!
ts
)
{
ret
=
-
1
;
goto
close_fds
;
...
...
@@ -1022,8 +1018,8 @@ int lxc_console(struct lxc_container *c, int ttynum,
istty
=
isatty
(
stdinfd
);
if
(
istty
)
{
lxc_
console
_winsz
(
stdinfd
,
masterfd
);
lxc_cmd_
console
_winch
(
ts
->
winch_proxy
,
ts
->
winch_proxy_lxcpath
);
lxc_
terminal
_winsz
(
stdinfd
,
masterfd
);
lxc_cmd_
terminal
_winch
(
ts
->
winch_proxy
,
ts
->
winch_proxy_lxcpath
);
}
else
{
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,
if
(
ts
->
sigfd
!=
-
1
)
{
ret
=
lxc_mainloop_add_handler
(
&
descr
,
ts
->
sigfd
,
lxc_
console_cb_signal_fd
,
ts
);
lxc_
terminal_signalfd_cb
,
ts
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to add signal handler to mainloop"
);
goto
close_mainloop
;
...
...
@@ -1044,14 +1040,14 @@ int lxc_console(struct lxc_container *c, int ttynum,
}
ret
=
lxc_mainloop_add_handler
(
&
descr
,
ts
->
stdinfd
,
lxc_
console_cb_tty_stdin
,
ts
);
lxc_
terminal_stdin_cb
,
ts
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to add stdin handler"
);
goto
close_mainloop
;
}
ret
=
lxc_mainloop_add_handler
(
&
descr
,
ts
->
masterfd
,
lxc_
console_cb_tty_master
,
ts
);
lxc_
terminal_master_cb
,
ts
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to add master handler"
);
goto
close_mainloop
;
...
...
@@ -1092,7 +1088,7 @@ close_mainloop:
lxc_mainloop_close
(
&
descr
);
sigwinch_fini
:
lxc_
console
_signal_fini
(
ts
);
lxc_
terminal
_signal_fini
(
ts
);
close_fds
:
close
(
masterfd
);
...
...
@@ -1122,7 +1118,7 @@ int lxc_login_pty(int fd)
if
(
ret
<
0
)
return
-
1
;
ret
=
lxc_
console
_set_stdfds
(
fd
);
ret
=
lxc_
terminal
_set_stdfds
(
fd
);
if
(
ret
<
0
)
return
-
1
;
...
...
@@ -1132,7 +1128,7 @@ int lxc_login_pty(int fd)
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
->
master
=
-
EBADF
;
...
...
@@ -1140,25 +1136,25 @@ void lxc_pty_info_init(struct lxc_pty_info *pty)
pty
->
busy
=
-
1
;
}
void
lxc_
pty_init
(
struct
lxc_console
*
pty
)
void
lxc_
terminal_init
(
struct
lxc_terminal
*
pty
)
{
memset
(
pty
,
0
,
sizeof
(
*
pty
));
pty
->
slave
=
-
EBADF
;
pty
->
master
=
-
EBADF
;
pty
->
peer
=
-
EBADF
;
pty
->
log_fd
=
-
EBADF
;
lxc_
pty_info_init
(
&
pty
->
peerpt
y
);
lxc_
terminal_info_init
(
&
pty
->
prox
y
);
}
void
lxc_
pty_conf_free
(
struct
lxc_console
*
console
)
void
lxc_
terminal_conf_free
(
struct
lxc_terminal
*
terminal
)
{
free
(
console
->
log_path
);
free
(
console
->
path
);
if
(
console
->
buffer_size
>
0
&&
console
->
ringbuf
.
addr
)
lxc_ringbuf_release
(
&
console
->
ringbuf
);
free
(
terminal
->
log_path
);
free
(
terminal
->
path
);
if
(
terminal
->
buffer_size
>
0
&&
terminal
->
ringbuf
.
addr
)
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
;
...
...
src/lxc/
console
.h
→
src/lxc/
terminal
.h
View file @
19462d43
...
...
@@ -24,27 +24,42 @@
#ifndef __LXC_CONSOLE_H
#define __LXC_CONSOLE_H
#include "config.h"
#include <signal.h>
#include <stdio.h>
#include "conf.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 */
struct
lxc_container
;
/* defined in lxccontainer.h */
struct
lxc_tty_state
{
/* 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_terminal_info
{
char
name
[
MAXPATHLEN
];
int
master
;
int
slave
;
int
busy
;
};
struct
lxc_terminal_state
{
struct
lxc_list
node
;
int
stdinfd
;
int
stdoutfd
;
int
masterfd
;
/* 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.
*
This field is checked by lxc_console_cb_tty_stdin
(). Set to -1 to
* specified. The pty can then exited by doing: Ctrl + specified_char +
*
q. This field is checked by lxc_terminal_stdin_cb
(). Set to -1 to
* disable exiting the pty via a escape sequence.
*/
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.
*/
int
saw_escape
;
...
...
@@ -60,15 +75,49 @@ struct lxc_tty_state
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
* @sockfd : the socket fd whose remote side when closed, will be an
* 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
*/
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:
...
...
@@ -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
* 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.
* - In addition to lxc_
pty
_create() also sets up all pty logs.
* lxc_
terminal_setup
: Create a new pty.
* - 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
* - 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
* /dev/tty)
* 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
* resources allocated by lxc_
console
_allocate().
* lxc_
terminal
_free: mark the console or a tty as unallocated, free any
* resources allocated by lxc_
terminal
_allocate().
*
* @conf : the configuration of the container whose tty was closed
* @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
* 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
*/
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.
*/
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.
...
...
@@ -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
* 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
);
/*
...
...
@@ -148,25 +197,25 @@ extern int lxc_console_getfd(struct lxc_container *c, int *ttynum,
* fd is made a duplicate of a specific standard file descriptor iff the
* 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
* 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.
*/
extern
int
lxc_
console_cb_tty_stdin
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
struct
lxc_epoll_descr
*
descr
);
extern
int
lxc_
terminal_stdin_cb
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
struct
lxc_epoll_descr
*
descr
);
/*
* 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
* lxc_
console
_mainloop_add().
* lxc_
terminal
_mainloop_add().
* 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
,
struct
lxc_epoll_descr
*
descr
);
extern
int
lxc_
terminal_master_cb
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
struct
lxc_epoll_descr
*
descr
);
/*
* Setup new terminal properties. The old terminal settings are stored in
...
...
@@ -176,21 +225,21 @@ extern int lxc_setup_tios(int fd, struct termios *oldtios);
/*
* lxc_
console_winsz: propag
te winsz from one terminal to another
* lxc_
terminal_winsz: propaga
te winsz from one terminal to another
*
* @srcfd : terminal to get size from (typically a slave 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
* @dstfd : dst for winsz in SIGWINCH handler
*
* Returns lxc_t
ty
_state structure on success or NULL on failure. The sigfd
* member of the returned lxc_t
ty
_state can be select()/poll()ed/epoll()ed
* Returns lxc_t
erminal
_state structure on success or NULL on failure. The sigfd
* member of the returned lxc_t
erminal
_state can be select()/poll()ed/epoll()ed
* on (ie added to a mainloop) for signals.
*
* 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);
* 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
* 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
* 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.
*/
extern
struct
lxc_t
ty_state
*
lxc_console
_signal_init
(
int
srcfd
,
int
dstfd
);
extern
struct
lxc_t
erminal_state
*
lxc_terminal
_signal_init
(
int
srcfd
,
int
dstfd
);
/*
* 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
);
/*
* lxc_
console
_signal_fini: uninstall signal handler
* lxc_
terminal
_signal_fini: uninstall signal handler
*
* @ts : the lxc_t
ty_state returned by lxc_console
_signal_init
* @ts : the lxc_t
erminal_state returned by lxc_terminal
_signal_init
*
* 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
* 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_console_cb_con
(
int
fd
,
uint32_t
events
,
void
*
data
,
extern
int
lxc_terminal_write_ringbuffer
(
struct
lxc_terminal
*
console
);
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
);
extern
int
lxc_make_controlling_pty
(
int
fd
);
extern
int
lxc_login_pty
(
int
fd
);
extern
void
lxc_
pty_conf_free
(
struct
lxc_console
*
console
);
extern
void
lxc_
pty_info_init
(
struct
lxc_pty
_info
*
pty
);
extern
void
lxc_
pty_init
(
struct
lxc_console
*
pty
);
extern
int
lxc_
pty_map_ids
(
struct
lxc_conf
*
c
,
struct
lxc_console
*
pty
);
extern
void
lxc_
terminal_conf_free
(
struct
lxc_terminal
*
console
);
extern
void
lxc_
terminal_info_init
(
struct
lxc_terminal
_info
*
pty
);
extern
void
lxc_
terminal_init
(
struct
lxc_terminal
*
pty
);
extern
int
lxc_
terminal_map_ids
(
struct
lxc_conf
*
c
,
struct
lxc_terminal
*
pty
);
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment