]>
Commit | Line | Data |
---|---|---|
63376d7d DL |
1 | /* |
2 | * lxc: linux Container library | |
3 | * | |
4 | * (C) Copyright IBM Corp. 2007, 2010 | |
5 | * | |
6 | * Authors: | |
9afe19d6 | 7 | * Daniel Lezcano <daniel.lezcano at free.fr> |
63376d7d DL |
8 | * |
9 | * This library is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU Lesser General Public | |
11 | * License as published by the Free Software Foundation; either | |
12 | * version 2.1 of the License, or (at your option) any later version. | |
13 | * | |
14 | * This library is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 | * Lesser General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU Lesser General Public | |
20 | * License along with this library; if not, write to the Free Software | |
250b1eec | 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
63376d7d DL |
22 | */ |
23 | ||
e9a55b51 CB |
24 | #ifndef __LXC_TERMINAL_H |
25 | #define __LXC_TERMINAL_H | |
f1a4a029 | 26 | |
0519b5cc CB |
27 | #include <signal.h> |
28 | #include <stdio.h> | |
29 | ||
0d4137cc | 30 | #include "list.h" |
8c880e57 | 31 | #include "macro.h" |
13bb312d CB |
32 | #include "ringbuf.h" |
33 | ||
5b55021f | 34 | struct lxc_container; |
13bb312d | 35 | struct lxc_conf; |
5b55021f | 36 | struct lxc_epoll_descr; |
13bb312d | 37 | |
13bb312d | 38 | struct lxc_terminal_info { |
e9a55b51 | 39 | /* the path name of the slave side */ |
8c880e57 | 40 | char name[PATH_MAX]; |
e9a55b51 CB |
41 | |
42 | /* the file descriptor of the master */ | |
13bb312d | 43 | int master; |
e9a55b51 CB |
44 | |
45 | /* the file descriptor of the slave */ | |
13bb312d | 46 | int slave; |
e9a55b51 CB |
47 | |
48 | /* whether the terminal is currently used */ | |
13bb312d CB |
49 | int busy; |
50 | }; | |
51 | ||
5b55021f CB |
52 | struct lxc_terminal_state { |
53 | struct lxc_list node; | |
54 | int stdinfd; | |
55 | int stdoutfd; | |
56 | int masterfd; | |
e9a55b51 CB |
57 | |
58 | /* Escape sequence to use for exiting the terminal. A single char can | |
59 | * be specified. The terminal can then exited by doing: Ctrl + | |
60 | * specified_char + q. This field is checked by | |
61 | * lxc_terminal_stdin_cb(). Set to -1 to disable exiting the terminal | |
62 | * via a escape sequence. | |
5b55021f CB |
63 | */ |
64 | int escape; | |
e9a55b51 | 65 | |
5b55021f CB |
66 | /* Used internally by lxc_terminal_stdin_cb() to check whether an |
67 | * escape sequence has been received. | |
68 | */ | |
69 | int saw_escape; | |
e9a55b51 | 70 | |
5b55021f CB |
71 | /* Name of the container to forward the SIGWINCH event to. */ |
72 | const char *winch_proxy; | |
e9a55b51 | 73 | |
5b55021f CB |
74 | /* Path of the container to forward the SIGWINCH event to. */ |
75 | const char *winch_proxy_lxcpath; | |
e9a55b51 | 76 | |
5b55021f CB |
77 | /* File descriptor that accepts signals. If set to -1 no signal handler |
78 | * could be installed. This also means that the sigset_t oldmask member | |
79 | * is meaningless. | |
80 | */ | |
81 | int sigfd; | |
e9a55b51 | 82 | |
5b55021f CB |
83 | sigset_t oldmask; |
84 | }; | |
85 | ||
13bb312d CB |
86 | struct lxc_terminal { |
87 | int slave; | |
88 | int master; | |
89 | int peer; | |
fb87aa6a | 90 | struct lxc_terminal_info proxy; |
13bb312d CB |
91 | struct lxc_epoll_descr *descr; |
92 | char *path; | |
8c880e57 | 93 | char name[PATH_MAX]; |
13bb312d | 94 | struct termios *tios; |
5b55021f | 95 | struct lxc_terminal_state *tty_state; |
13bb312d | 96 | |
e9a55b51 | 97 | struct /* lxc_terminal_log */ { |
13bb312d CB |
98 | /* size of the log file */ |
99 | uint64_t log_size; | |
100 | ||
101 | /* path to the log file */ | |
102 | char *log_path; | |
103 | ||
104 | /* fd to the log file */ | |
105 | int log_fd; | |
106 | ||
107 | /* whether the log file will be rotated */ | |
108 | unsigned int log_rotate; | |
109 | }; | |
110 | ||
5b55021f | 111 | struct /* lxc_terminal_ringbuf */ { |
13bb312d CB |
112 | /* size of the ringbuffer */ |
113 | uint64_t buffer_size; | |
114 | ||
115 | /* the in-memory ringbuffer */ | |
116 | struct lxc_ringbuf ringbuf; | |
117 | }; | |
118 | }; | |
0d4137cc | 119 | |
e9a55b51 | 120 | /** |
c1ee47cd | 121 | * lxc_terminal_allocate: allocate the console or a tty |
22926b39 CB |
122 | * |
123 | * @conf : the configuration of the container to allocate from | |
124 | * @sockfd : the socket fd whose remote side when closed, will be an | |
125 | * indication that the console or tty is no longer in use | |
126 | * @ttyreq : the tty requested to be opened, -1 for any, 0 for the console | |
127 | */ | |
c1ee47cd | 128 | extern int lxc_terminal_allocate(struct lxc_conf *conf, int sockfd, int *ttynum); |
22926b39 | 129 | |
e9a55b51 CB |
130 | /** |
131 | * Create a new terminal: | |
132 | * - calls openpty() to allocate a master/slave pair | |
22926b39 | 133 | * - sets the FD_CLOEXEC flag on the master/slave fds |
e9a55b51 CB |
134 | * - allocates either the current controlling terminal (default) or a user |
135 | * specified terminal as proxy for the newly created master/slave pair | |
22926b39 CB |
136 | * - sets up SIGWINCH handler, winsz, and new terminal settings |
137 | * (Handlers for SIGWINCH and I/O are not registered in a mainloop.) | |
22926b39 | 138 | */ |
dcad02f8 | 139 | extern int lxc_terminal_create(struct lxc_terminal *console); |
5777fe90 CB |
140 | |
141 | /** | |
e9a55b51 CB |
142 | * lxc_terminal_setup: Create a new terminal. |
143 | * - In addition to lxc_terminal_create() also sets up logging. | |
5777fe90 | 144 | */ |
564e31c4 | 145 | extern int lxc_terminal_setup(struct lxc_conf *); |
22926b39 | 146 | |
e9a55b51 CB |
147 | /** |
148 | * Delete a terminal created via lxc_terminal_create() or lxc_terminal_setup(): | |
149 | * Note, registered handlers are not automatically deleted. | |
22926b39 | 150 | */ |
dcad02f8 | 151 | extern void lxc_terminal_delete(struct lxc_terminal *); |
22926b39 | 152 | |
e9a55b51 CB |
153 | /** |
154 | * lxc_terminal_free: mark the terminal as unallocated and free any resources | |
155 | * allocated by lxc_terminal_allocate(). | |
22926b39 CB |
156 | * |
157 | * @conf : the configuration of the container whose tty was closed | |
158 | * @fd : the socket fd whose remote side was closed, which indicated | |
e9a55b51 CB |
159 | * the terminal is no longer in use. this is used to match |
160 | * which terminal is being freed. | |
22926b39 | 161 | */ |
3dfe6f8d | 162 | extern void lxc_terminal_free(struct lxc_conf *conf, int fd); |
b5159817 | 163 | |
e9a55b51 CB |
164 | /** |
165 | * Register terminal event handlers in an open mainloop. | |
22926b39 | 166 | */ |
dcad02f8 | 167 | extern int lxc_terminal_mainloop_add(struct lxc_epoll_descr *, struct lxc_terminal *); |
22926b39 | 168 | |
e9a55b51 CB |
169 | /** |
170 | * Handle SIGWINCH events on the allocated terminals. | |
22926b39 | 171 | */ |
dad4a039 | 172 | extern void lxc_terminal_sigwinch(int sig); |
22926b39 | 173 | |
e9a55b51 CB |
174 | /** |
175 | * Connect to one of the ttys given to the container via lxc.tty.max. | |
176 | * - allocates either the current controlling terminal (default) or a user specified | |
177 | * terminal as proxy terminal for the containers tty | |
22926b39 CB |
178 | * - sets up SIGWINCH handler, winsz, and new terminal settings |
179 | * - opens mainloop | |
180 | * - registers SIGWINCH, I/O handlers in the mainloop | |
181 | * - performs all necessary cleanup operations | |
182 | */ | |
b5159817 DE |
183 | extern int lxc_console(struct lxc_container *c, int ttynum, |
184 | int stdinfd, int stdoutfd, int stderrfd, | |
185 | int escape); | |
22926b39 | 186 | |
e9a55b51 CB |
187 | /** |
188 | * Allocate one of the tty given to the container via lxc.tty.max. Returns an | |
189 | * open fd to the allocated tty. | |
190 | * Set ttynum to -1 to allocate the first available tty, or to a value within | |
191 | * the range specified by lxc.tty.max to allocate a specific tty. | |
22926b39 | 192 | */ |
e9a55b51 | 193 | extern int lxc_terminal_getfd(struct lxc_container *c, int *ttynum, |
b5159817 | 194 | int *masterfd); |
22926b39 | 195 | |
e9a55b51 CB |
196 | /** |
197 | * Make fd a duplicate of the standard file descriptors. The fd is made a | |
198 | * duplicate of a specific standard file descriptor iff the standard file | |
199 | * descriptor refers to a terminal. | |
22926b39 | 200 | */ |
ae6d3913 | 201 | extern int lxc_terminal_set_stdfds(int fd); |
22926b39 | 202 | |
e9a55b51 CB |
203 | /** |
204 | * Handler for events on the stdin fd of the terminal. To be registered via the | |
22926b39 | 205 | * corresponding functions declared and defined in mainloop.{c,h} or |
093bce5f | 206 | * lxc_terminal_mainloop_add(). |
22926b39 CB |
207 | * This function exits the loop cleanly when an EPOLLHUP event is received. |
208 | */ | |
52f9292f CB |
209 | extern int lxc_terminal_stdin_cb(int fd, uint32_t events, void *cbdata, |
210 | struct lxc_epoll_descr *descr); | |
22926b39 | 211 | |
e9a55b51 CB |
212 | /** |
213 | * Handler for events on the master fd of the terminal. To be registered via | |
214 | * the corresponding functions declared and defined in mainloop.{c,h} or | |
093bce5f | 215 | * lxc_terminal_mainloop_add(). |
22926b39 CB |
216 | * This function exits the loop cleanly when an EPOLLHUP event is received. |
217 | */ | |
ee9102ff CB |
218 | extern int lxc_terminal_master_cb(int fd, uint32_t events, void *cbdata, |
219 | struct lxc_epoll_descr *descr); | |
22926b39 | 220 | |
e9a55b51 | 221 | /** |
22926b39 CB |
222 | * Setup new terminal properties. The old terminal settings are stored in |
223 | * oldtios. | |
224 | */ | |
0d4137cc | 225 | extern int lxc_setup_tios(int fd, struct termios *oldtios); |
22926b39 CB |
226 | |
227 | ||
e9a55b51 | 228 | /** |
4e9c0330 | 229 | * lxc_terminal_winsz: propagate winsz from one terminal to another |
22926b39 | 230 | * |
e9a55b51 CB |
231 | * @srcfd |
232 | * - terminal to get size from (typically a slave pty) | |
233 | * @dstfd | |
234 | * - terminal to set size on (typically a master pty) | |
22926b39 | 235 | */ |
4e9c0330 | 236 | extern void lxc_terminal_winsz(int srcfd, int dstfd); |
22926b39 CB |
237 | |
238 | /* | |
dc8c7883 | 239 | * lxc_terminal_signal_init: install signal handler |
22926b39 | 240 | * |
e9a55b51 CB |
241 | * @srcfd |
242 | * - src for winsz in SIGWINCH handler | |
243 | * @dstfd | |
244 | * - dst for winsz in SIGWINCH handler | |
22926b39 | 245 | * |
e9a55b51 CB |
246 | * Returns lxc_terminal_state structure on success or NULL on failure. The |
247 | * sigfd member of the returned lxc_terminal_state can be | |
248 | * select()/poll()ed/epoll()ed on (i.e. added to a mainloop) for signals. | |
22926b39 | 249 | * |
e9a55b51 CB |
250 | * Must be called with process_lock held to protect the lxc_ttys list, or from |
251 | * a non-threaded context. | |
22926b39 | 252 | * |
f1e56364 | 253 | * Note that the signal handler isn't installed as a classic asynchronous |
0519b5cc CB |
254 | * handler, rather signalfd(2) is used so that we can handle the signal when |
255 | * we're ready for it. This avoids deadlocks since a signal handler (ie | |
dad4a039 | 256 | * lxc_terminal_sigwinch()) would need to take the thread mutex to prevent |
0519b5cc | 257 | * lxc_ttys list corruption, but using the fd we can provide the tty_state |
9bafc8cb | 258 | * needed to the callback (lxc_terminal_signalfd_cb()). |
22926b39 CB |
259 | * |
260 | * This function allocates memory. It is up to the caller to free it. | |
261 | */ | |
5b55021f | 262 | extern struct lxc_terminal_state *lxc_terminal_signal_init(int srcfd, int dstfd); |
22926b39 | 263 | |
e9a55b51 | 264 | /** |
0519b5cc | 265 | * Handler for signal events. To be registered via the corresponding functions |
093bce5f | 266 | * declared and defined in mainloop.{c,h} or lxc_terminal_mainloop_add(). |
22926b39 | 267 | */ |
9bafc8cb | 268 | extern int lxc_terminal_signalfd_cb(int fd, uint32_t events, void *cbdata, |
0519b5cc | 269 | struct lxc_epoll_descr *descr); |
22926b39 | 270 | |
e9a55b51 | 271 | /** |
a8867251 | 272 | * lxc_terminal_signal_fini: uninstall signal handler |
22926b39 | 273 | * |
e9a55b51 CB |
274 | * @ts |
275 | * - the lxc_terminal_state returned by lxc_terminal_signal_init | |
22926b39 CB |
276 | * |
277 | * Restore the saved signal handler that was in effect at the time | |
dc8c7883 | 278 | * lxc_terminal_signal_init() was called. |
22926b39 CB |
279 | * |
280 | * Must be called with process_lock held to protect the lxc_ttys list, or | |
281 | * from a non-threaded context. | |
282 | */ | |
5b55021f | 283 | extern void lxc_terminal_signal_fini(struct lxc_terminal_state *ts); |
f1a4a029 | 284 | |
e9a55b51 CB |
285 | extern int lxc_terminal_write_ringbuffer(struct lxc_terminal *terminal); |
286 | extern int lxc_terminal_create_log_file(struct lxc_terminal *terminal); | |
de708fb7 | 287 | extern int lxc_terminal_io_cb(int fd, uint32_t events, void *data, |
a529bc25 | 288 | struct lxc_epoll_descr *descr); |
63b74cda | 289 | |
cd0a2b2f | 290 | extern int lxc_make_controlling_terminal(int fd); |
d049f0e9 | 291 | extern int lxc_terminal_prepare_login(int fd); |
e9a55b51 CB |
292 | extern void lxc_terminal_conf_free(struct lxc_terminal *terminal); |
293 | extern void lxc_terminal_info_init(struct lxc_terminal_info *terminal); | |
294 | extern void lxc_terminal_init(struct lxc_terminal *terminal); | |
295 | extern int lxc_terminal_map_ids(struct lxc_conf *c, | |
296 | struct lxc_terminal *terminal); | |
e98affda | 297 | |
e9a55b51 | 298 | #endif /* __LXC_TERMINAL_H */ |