]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/terminal.c
Merge pull request #2499 from brauner/lxc/master
[mirror_lxc.git] / src / lxc / terminal.c
1 /*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <daniel.lezcano at free.fr>
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
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #define _GNU_SOURCE
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <lxc/lxccontainer.h>
28 #include <pthread.h>
29 #include <signal.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <sys/epoll.h>
33 #include <sys/types.h>
34 #include <termios.h>
35 #include <unistd.h>
36
37 #include "af_unix.h"
38 #include "caps.h"
39 #include "commands.h"
40 #include "conf.h"
41 #include "config.h"
42 #include "log.h"
43 #include "lxclock.h"
44 #include "mainloop.h"
45 #include "start.h"
46 #include "terminal.h"
47 #include "utils.h"
48
49 #if HAVE_PTY_H
50 #include <pty.h>
51 #else
52 #include <../include/openpty.h>
53 #endif
54
55 #define LXC_TERMINAL_BUFFER_SIZE 1024
56
57 lxc_log_define(terminal, lxc);
58
59 static struct lxc_list lxc_ttys;
60
61 typedef void (*sighandler_t)(int);
62
63 __attribute__((constructor)) void lxc_terminal_init_global(void)
64 {
65 lxc_list_init(&lxc_ttys);
66 }
67
68 void lxc_terminal_winsz(int srcfd, int dstfd)
69 {
70 int ret;
71 struct winsize wsz;
72
73 if (!isatty(srcfd))
74 return;
75
76 ret = ioctl(srcfd, TIOCGWINSZ, &wsz);
77 if (ret < 0) {
78 WARN("Failed to get window size");
79 return;
80 }
81
82 ret = ioctl(dstfd, TIOCSWINSZ, &wsz);
83 if (ret < 0)
84 WARN("Failed to set window size");
85 else
86 DEBUG("Set window size to %d columns and %d rows", wsz.ws_col,
87 wsz.ws_row);
88
89 return;
90 }
91
92 static void lxc_terminal_winch(struct lxc_terminal_state *ts)
93 {
94 lxc_terminal_winsz(ts->stdinfd, ts->masterfd);
95
96 if (ts->winch_proxy)
97 lxc_cmd_terminal_winch(ts->winch_proxy, ts->winch_proxy_lxcpath);
98 }
99
100 void lxc_terminal_sigwinch(int sig)
101 {
102 struct lxc_list *it;
103 struct lxc_terminal_state *ts;
104
105 lxc_list_for_each(it, &lxc_ttys) {
106 ts = it->elem;
107 lxc_terminal_winch(ts);
108 }
109 }
110
111 int lxc_terminal_signalfd_cb(int fd, uint32_t events, void *cbdata,
112 struct lxc_epoll_descr *descr)
113 {
114 ssize_t ret;
115 struct signalfd_siginfo siginfo;
116 struct lxc_terminal_state *ts = cbdata;
117
118 ret = lxc_read_nointr(fd, &siginfo, sizeof(siginfo));
119 if (ret < 0 || (size_t)ret < sizeof(siginfo)) {
120 ERROR("Failed to read signal info");
121 return LXC_MAINLOOP_ERROR;
122 }
123
124 if (siginfo.ssi_signo == SIGTERM) {
125 DEBUG("Received SIGTERM. Detaching from the terminal");
126 return LXC_MAINLOOP_CLOSE;
127 }
128
129 if (siginfo.ssi_signo == SIGWINCH)
130 lxc_terminal_winch(ts);
131
132 return LXC_MAINLOOP_CONTINUE;
133 }
134
135 struct lxc_terminal_state *lxc_terminal_signal_init(int srcfd, int dstfd)
136 {
137 int ret;
138 bool istty = false;
139 sigset_t mask;
140 struct lxc_terminal_state *ts;
141
142 ts = malloc(sizeof(*ts));
143 if (!ts)
144 return NULL;
145
146 memset(ts, 0, sizeof(*ts));
147 ts->stdinfd = srcfd;
148 ts->masterfd = dstfd;
149 ts->sigfd = -1;
150
151 ret = sigemptyset(&mask);
152 if (ret < 0) {
153 SYSERROR("Failed to initialize an empty signal set");
154 goto on_error;
155 }
156
157 istty = (isatty(srcfd) == 1);
158 if (!istty) {
159 INFO("fd %d does not refer to a tty device", srcfd);
160 } else {
161 /* Add tty to list to be scanned at SIGWINCH time. */
162 lxc_list_add_elem(&ts->node, ts);
163 lxc_list_add_tail(&lxc_ttys, &ts->node);
164 ret = sigaddset(&mask, SIGWINCH);
165 if (ret < 0)
166 SYSNOTICE("Failed to add SIGWINCH to signal set");
167 }
168
169 /* Exit the mainloop cleanly on SIGTERM. */
170 ret = sigaddset(&mask, SIGTERM);
171 if (ret < 0) {
172 SYSERROR("Failed to add SIGWINCH to signal set");
173 goto on_error;
174 }
175
176 ret = pthread_sigmask(SIG_BLOCK, &mask, &ts->oldmask);
177 if (ret < 0) {
178 WARN("Failed to block signals");
179 goto on_error;
180 }
181
182 ts->sigfd = signalfd(-1, &mask, SFD_CLOEXEC);
183 if (ts->sigfd < 0) {
184 WARN("Failed to create signal fd");
185 (void)pthread_sigmask(SIG_SETMASK, &ts->oldmask, NULL);
186 goto on_error;
187 }
188
189 DEBUG("Created signal fd %d", ts->sigfd);
190 return ts;
191
192 on_error:
193 ERROR("Failed to create signal fd");
194 if (ts->sigfd >= 0) {
195 close(ts->sigfd);
196 ts->sigfd = -1;
197 }
198
199 if (istty)
200 lxc_list_del(&ts->node);
201
202 return ts;
203 }
204
205 void lxc_terminal_signal_fini(struct lxc_terminal_state *ts)
206 {
207 if (ts->sigfd >= 0) {
208 close(ts->sigfd);
209
210 if (pthread_sigmask(SIG_SETMASK, &ts->oldmask, NULL) < 0)
211 SYSWARN("Failed to restore signal mask");
212 }
213
214 if (isatty(ts->stdinfd))
215 lxc_list_del(&ts->node);
216
217 free(ts);
218 }
219
220 static int lxc_terminal_truncate_log_file(struct lxc_terminal *terminal)
221 {
222 /* be very certain things are kosher */
223 if (!terminal->log_path || terminal->log_fd < 0)
224 return -EBADF;
225
226 return lxc_unpriv(ftruncate(terminal->log_fd, 0));
227 }
228
229 static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal)
230 {
231 int ret;
232 size_t len;
233 char *tmp;
234
235 if (!terminal->log_path || terminal->log_rotate == 0)
236 return -EOPNOTSUPP;
237
238 /* be very certain things are kosher */
239 if (terminal->log_fd < 0)
240 return -EBADF;
241
242 len = strlen(terminal->log_path) + sizeof(".1");
243 tmp = alloca(len);
244
245 ret = snprintf(tmp, len, "%s.1", terminal->log_path);
246 if (ret < 0 || (size_t)ret >= len)
247 return -EFBIG;
248
249 close(terminal->log_fd);
250 terminal->log_fd = -1;
251 ret = lxc_unpriv(rename(terminal->log_path, tmp));
252 if (ret < 0)
253 return ret;
254
255 return lxc_terminal_create_log_file(terminal);
256 }
257
258 static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf,
259 int bytes_read)
260 {
261 int ret;
262 struct stat st;
263 int64_t space_left = -1;
264
265 if (terminal->log_fd < 0)
266 return 0;
267
268 /* A log size <= 0 means that there's no limit on the size of the log
269 * file at which point we simply ignore whether the log is supposed to
270 * be rotated or not.
271 */
272 if (terminal->log_size <= 0)
273 return lxc_write_nointr(terminal->log_fd, buf, bytes_read);
274
275 /* Get current size of the log file. */
276 ret = fstat(terminal->log_fd, &st);
277 if (ret < 0) {
278 SYSERROR("Failed to stat the terminal log file descriptor");
279 return -1;
280 }
281
282 /* handle non-regular files */
283 if ((st.st_mode & S_IFMT) != S_IFREG) {
284 /* This isn't a regular file. so rotating the file seems a
285 * dangerous thing to do, size limits are also very
286 * questionable. Let's not risk anything and tell the user that
287 * he's requesting us to do weird stuff.
288 */
289 if (terminal->log_rotate > 0 || terminal->log_size > 0)
290 return -EINVAL;
291
292 /* I mean, sure log wherever you want to. */
293 return lxc_write_nointr(terminal->log_fd, buf, bytes_read);
294 }
295
296 space_left = terminal->log_size - st.st_size;
297
298 /* User doesn't want to rotate the log file and there's no more space
299 * left so simply truncate it.
300 */
301 if (space_left <= 0 && terminal->log_rotate <= 0) {
302 ret = lxc_terminal_truncate_log_file(terminal);
303 if (ret < 0)
304 return ret;
305
306 if (bytes_read <= terminal->log_size)
307 return lxc_write_nointr(terminal->log_fd, buf, bytes_read);
308
309 /* Write as much as we can into the buffer and loose the rest. */
310 return lxc_write_nointr(terminal->log_fd, buf, terminal->log_size);
311 }
312
313 /* There's enough space left. */
314 if (bytes_read <= space_left)
315 return lxc_write_nointr(terminal->log_fd, buf, bytes_read);
316
317 /* There's not enough space left but at least write as much as we can
318 * into the old log file.
319 */
320 ret = lxc_write_nointr(terminal->log_fd, buf, space_left);
321 if (ret < 0)
322 return -1;
323
324 /* Calculate how many bytes we still need to write. */
325 bytes_read -= space_left;
326
327 /* There'd be more to write but we aren't instructed to rotate the log
328 * file so simply return. There's no error on our side here.
329 */
330 if (terminal->log_rotate > 0)
331 ret = lxc_terminal_rotate_log_file(terminal);
332 else
333 ret = lxc_terminal_truncate_log_file(terminal);
334 if (ret < 0)
335 return ret;
336
337 if (terminal->log_size < bytes_read) {
338 /* Well, this is unfortunate because it means that there is more
339 * to write than the user has granted us space. There are
340 * multiple ways to handle this but let's use the simplest one:
341 * write as much as we can, tell the user that there was more
342 * stuff to write and move on.
343 * Note that this scenario shouldn't actually happen with the
344 * standard pty-based terminal that LXC allocates since it will
345 * be switched into raw mode. In raw mode only 1 byte at a time
346 * should be read and written.
347 */
348 WARN("Size of terminal log file is smaller than the bytes to write");
349 ret = lxc_write_nointr(terminal->log_fd, buf, terminal->log_size);
350 if (ret < 0)
351 return -1;
352 bytes_read -= ret;
353 return bytes_read;
354 }
355
356 /* Yay, we made it. */
357 ret = lxc_write_nointr(terminal->log_fd, buf, bytes_read);
358 if (ret < 0)
359 return -1;
360 bytes_read -= ret;
361 return bytes_read;
362 }
363
364 int lxc_terminal_io_cb(int fd, uint32_t events, void *data,
365 struct lxc_epoll_descr *descr)
366 {
367 struct lxc_terminal *terminal = data;
368 char buf[LXC_TERMINAL_BUFFER_SIZE];
369 int r, w, w_log, w_rbuf;
370
371 w = r = lxc_read_nointr(fd, buf, sizeof(buf));
372 if (r <= 0) {
373 INFO("Terminal client on fd %d has exited", fd);
374 lxc_mainloop_del_handler(descr, fd);
375
376 if (fd == terminal->master) {
377 terminal->master = -EBADF;
378 } else if (fd == terminal->peer) {
379 if (terminal->tty_state) {
380 lxc_terminal_signal_fini(terminal->tty_state);
381 terminal->tty_state = NULL;
382 }
383 terminal->peer = -EBADF;
384 } else {
385 ERROR("Handler received unexpected file descriptor");
386 }
387 close(fd);
388
389 return LXC_MAINLOOP_CLOSE;
390 }
391
392 if (fd == terminal->peer)
393 w = lxc_write_nointr(terminal->master, buf, r);
394
395 w_rbuf = w_log = 0;
396 if (fd == terminal->master) {
397 /* write to peer first */
398 if (terminal->peer >= 0)
399 w = lxc_write_nointr(terminal->peer, buf, r);
400
401 /* write to terminal ringbuffer */
402 if (terminal->buffer_size > 0)
403 w_rbuf = lxc_ringbuf_write(&terminal->ringbuf, buf, r);
404
405 /* write to terminal log */
406 if (terminal->log_fd >= 0)
407 w_log = lxc_terminal_write_log_file(terminal, buf, r);
408 }
409
410 if (w != r)
411 WARN("Short write on terminal r:%d != w:%d", r, w);
412
413 if (w_rbuf < 0) {
414 errno = -w_rbuf;
415 SYSTRACE("Failed to write %d bytes to terminal ringbuffer", r);
416 }
417
418 if (w_log < 0)
419 TRACE("Failed to write %d bytes to terminal log", r);
420
421 return LXC_MAINLOOP_CONTINUE;
422 }
423
424 static int lxc_terminal_mainloop_add_peer(struct lxc_terminal *terminal)
425 {
426 int ret;
427
428 if (terminal->peer >= 0) {
429 ret = lxc_mainloop_add_handler(terminal->descr, terminal->peer,
430 lxc_terminal_io_cb, terminal);
431 if (ret < 0) {
432 WARN("Failed to add terminal peer handler to mainloop");
433 return -1;
434 }
435 }
436
437 if (!terminal->tty_state || terminal->tty_state->sigfd < 0)
438 return 0;
439
440 ret = lxc_mainloop_add_handler(terminal->descr, terminal->tty_state->sigfd,
441 lxc_terminal_signalfd_cb, terminal->tty_state);
442 if (ret < 0) {
443 WARN("Failed to add signal handler to mainloop");
444 return -1;
445 }
446
447 return 0;
448 }
449
450 int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr,
451 struct lxc_terminal *terminal)
452 {
453 int ret;
454
455 if (terminal->master < 0) {
456 INFO("Terminal is not initialized");
457 return 0;
458 }
459
460 ret = lxc_mainloop_add_handler(descr, terminal->master,
461 lxc_terminal_io_cb, terminal);
462 if (ret < 0) {
463 ERROR("Failed to add handler for terminal master fd %d to "
464 "mainloop", terminal->master);
465 return -1;
466 }
467
468 /* We cache the descr so that we can add an fd to it when someone
469 * does attach to it in lxc_terminal_allocate().
470 */
471 terminal->descr = descr;
472
473 return lxc_terminal_mainloop_add_peer(terminal);
474 }
475
476 int lxc_setup_tios(int fd, struct termios *oldtios)
477 {
478 int ret;
479 struct termios newtios;
480
481 if (!isatty(fd)) {
482 ERROR("File descriptor %d does not refert to a terminal", fd);
483 return -1;
484 }
485
486 /* Get current termios. */
487 ret = tcgetattr(fd, oldtios);
488 if (ret < 0) {
489 SYSERROR("Failed to get current terminal settings");
490 return -1;
491 }
492
493 /* ensure we don't end up in an endless loop:
494 * The kernel might fire SIGTTOU while an
495 * ioctl() in tcsetattr() is executed. When the ioctl()
496 * is resumed and retries, the signal handler interrupts it again.
497 */
498 signal (SIGTTIN, SIG_IGN);
499 signal (SIGTTOU, SIG_IGN);
500
501 newtios = *oldtios;
502
503 /* We use the same settings that ssh does. */
504 newtios.c_iflag |= IGNPAR;
505 newtios.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF);
506 #ifdef IUCLC
507 newtios.c_iflag &= ~IUCLC;
508 #endif
509 newtios.c_lflag &= ~(TOSTOP | ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL);
510 #ifdef IEXTEN
511 newtios.c_lflag &= ~IEXTEN;
512 #endif
513 newtios.c_oflag &= ~ONLCR;
514 newtios.c_oflag |= OPOST;
515 newtios.c_cc[VMIN] = 1;
516 newtios.c_cc[VTIME] = 0;
517
518 /* Set new attributes. */
519 ret = tcsetattr(fd, TCSAFLUSH, &newtios);
520 if (ret < 0) {
521 ERROR("Failed to set new terminal settings");
522 return -1;
523 }
524
525 return 0;
526 }
527
528 static void lxc_terminal_peer_proxy_free(struct lxc_terminal *terminal)
529 {
530 if (terminal->tty_state) {
531 lxc_terminal_signal_fini(terminal->tty_state);
532 terminal->tty_state = NULL;
533 }
534
535 close(terminal->proxy.master);
536 terminal->proxy.master = -1;
537
538 close(terminal->proxy.slave);
539 terminal->proxy.slave = -1;
540
541 terminal->proxy.busy = -1;
542
543 terminal->proxy.name[0] = '\0';
544
545 terminal->peer = -1;
546 }
547
548 static int lxc_terminal_peer_proxy_alloc(struct lxc_terminal *terminal,
549 int sockfd)
550 {
551 int ret;
552 struct termios oldtermio;
553 struct lxc_terminal_state *ts;
554
555 if (terminal->master < 0) {
556 ERROR("Terminal not set up");
557 return -1;
558 }
559
560 if (terminal->proxy.busy != -1 || terminal->peer != -1) {
561 NOTICE("Terminal already in use");
562 return -1;
563 }
564
565 if (terminal->tty_state) {
566 ERROR("Terminal has already been initialized");
567 return -1;
568 }
569
570 /* This is the proxy terminal that will be given to the client, and
571 * that the real terminal master will send to / recv from.
572 */
573 ret = openpty(&terminal->proxy.master, &terminal->proxy.slave, NULL,
574 NULL, NULL);
575 if (ret < 0) {
576 SYSERROR("Failed to open proxy terminal");
577 return -1;
578 }
579
580 ret = ttyname_r(terminal->proxy.slave, terminal->proxy.name,
581 sizeof(terminal->proxy.name));
582 if (ret < 0) {
583 SYSERROR("Failed to retrieve name of proxy terminal slave");
584 goto on_error;
585 }
586
587 ret = fd_cloexec(terminal->proxy.master, true);
588 if (ret < 0) {
589 SYSERROR("Failed to set FD_CLOEXEC flag on proxy terminal master");
590 goto on_error;
591 }
592
593 ret = fd_cloexec(terminal->proxy.slave, true);
594 if (ret < 0) {
595 SYSERROR("Failed to set FD_CLOEXEC flag on proxy terminal slave");
596 goto on_error;
597 }
598
599 ret = lxc_setup_tios(terminal->proxy.slave, &oldtermio);
600 if (ret < 0)
601 goto on_error;
602
603 ts = lxc_terminal_signal_init(terminal->proxy.master, terminal->master);
604 if (!ts)
605 goto on_error;
606
607 terminal->tty_state = ts;
608 terminal->peer = terminal->proxy.slave;
609 terminal->proxy.busy = sockfd;
610 ret = lxc_terminal_mainloop_add_peer(terminal);
611 if (ret < 0)
612 goto on_error;
613
614 NOTICE("Opened proxy terminal with master fd %d and slave fd %d",
615 terminal->proxy.master, terminal->proxy.slave);
616 return 0;
617
618 on_error:
619 lxc_terminal_peer_proxy_free(terminal);
620 return -1;
621 }
622
623 int lxc_terminal_allocate(struct lxc_conf *conf, int sockfd, int *ttyreq)
624 {
625 int ttynum;
626 int masterfd = -1;
627 struct lxc_tty_info *ttys = &conf->ttys;
628 struct lxc_terminal *terminal = &conf->console;
629
630 if (*ttyreq == 0) {
631 int ret;
632
633 ret = lxc_terminal_peer_proxy_alloc(terminal, sockfd);
634 if (ret < 0)
635 goto out;
636
637 masterfd = terminal->proxy.master;
638 goto out;
639 }
640
641 if (*ttyreq > 0) {
642 if (*ttyreq > ttys->max)
643 goto out;
644
645 if (ttys->tty[*ttyreq - 1].busy)
646 goto out;
647
648 /* The requested tty is available. */
649 ttynum = *ttyreq;
650 goto out_tty;
651 }
652
653 /* Search for next available tty, fixup index tty1 => [0]. */
654 for (ttynum = 1; ttynum <= ttys->max && ttys->tty[ttynum - 1].busy; ttynum++) {
655 ;
656 }
657
658 /* We didn't find any available slot for tty. */
659 if (ttynum > ttys->max)
660 goto out;
661
662 *ttyreq = ttynum;
663
664 out_tty:
665 ttys->tty[ttynum - 1].busy = sockfd;
666 masterfd = ttys->tty[ttynum - 1].master;
667
668 out:
669 return masterfd;
670 }
671
672 void lxc_terminal_free(struct lxc_conf *conf, int fd)
673 {
674 int i;
675 struct lxc_tty_info *ttys = &conf->ttys;
676 struct lxc_terminal *terminal = &conf->console;
677
678 for (i = 0; i < ttys->max; i++)
679 if (ttys->tty[i].busy == fd)
680 ttys->tty[i].busy = 0;
681
682 if (terminal->proxy.busy != fd)
683 return;
684
685 lxc_mainloop_del_handler(terminal->descr, terminal->proxy.slave);
686 lxc_terminal_peer_proxy_free(terminal);
687 }
688
689 static int lxc_terminal_peer_default(struct lxc_terminal *terminal)
690 {
691 struct lxc_terminal_state *ts;
692 const char *path;
693 int ret = 0;
694
695 if (terminal->path)
696 path = terminal->path;
697 else
698 path = "/dev/tty";
699
700 terminal->peer = lxc_unpriv(open(path, O_RDWR | O_CLOEXEC));
701 if (terminal->peer < 0) {
702 if (!terminal->path) {
703 errno = ENODEV;
704 SYSDEBUG("The process does not have a controlling terminal");
705 goto on_succes;
706 }
707
708 SYSERROR("Failed to open proxy terminal \"%s\"", path);
709 return -ENOTTY;
710 }
711 DEBUG("Using terminal \"%s\" as proxy", path);
712
713 if (!isatty(terminal->peer)) {
714 ERROR("File descriptor for \"%s\" does not refer to a terminal", path);
715 goto on_error_free_tios;
716 }
717
718 ts = lxc_terminal_signal_init(terminal->peer, terminal->master);
719 terminal->tty_state = ts;
720 if (!ts) {
721 WARN("Failed to install signal handler");
722 goto on_error_free_tios;
723 }
724
725 lxc_terminal_winsz(terminal->peer, terminal->master);
726
727 terminal->tios = malloc(sizeof(*terminal->tios));
728 if (!terminal->tios)
729 goto on_error_free_tios;
730
731 ret = lxc_setup_tios(terminal->peer, terminal->tios);
732 if (ret < 0)
733 goto on_error_close_peer;
734 else
735 goto on_succes;
736
737 on_error_free_tios:
738 free(terminal->tios);
739 terminal->tios = NULL;
740
741 on_error_close_peer:
742 close(terminal->peer);
743 terminal->peer = -1;
744 ret = -ENOTTY;
745
746 on_succes:
747 return ret;
748 }
749
750 int lxc_terminal_write_ringbuffer(struct lxc_terminal *terminal)
751 {
752 char *r_addr;
753 ssize_t ret;
754 uint64_t used;
755 struct lxc_ringbuf *buf = &terminal->ringbuf;
756
757 /* There's not log file where we can dump the ringbuffer to. */
758 if (terminal->log_fd < 0)
759 return 0;
760
761 used = lxc_ringbuf_used(buf);
762 if (used == 0)
763 return 0;
764
765 ret = lxc_terminal_truncate_log_file(terminal);
766 if (ret < 0)
767 return ret;
768
769 /* Write as much as we can without exceeding the limit. */
770 if (terminal->log_size < used)
771 used = terminal->log_size;
772
773 r_addr = lxc_ringbuf_get_read_addr(buf);
774 ret = lxc_write_nointr(terminal->log_fd, r_addr, used);
775 if (ret < 0)
776 return -EIO;
777
778 return 0;
779 }
780
781 void lxc_terminal_delete(struct lxc_terminal *terminal)
782 {
783 int ret;
784
785 ret = lxc_terminal_write_ringbuffer(terminal);
786 if (ret < 0)
787 WARN("Failed to write terminal log to disk");
788
789 if (terminal->tios && terminal->peer >= 0) {
790 ret = tcsetattr(terminal->peer, TCSAFLUSH, terminal->tios);
791 if (ret < 0)
792 SYSWARN("Failed to set old terminal settings");
793 }
794 free(terminal->tios);
795 terminal->tios = NULL;
796
797 if (terminal->peer >= 0)
798 close(terminal->peer);
799 terminal->peer = -1;
800
801 if (terminal->master >= 0)
802 close(terminal->master);
803 terminal->master = -1;
804
805 if (terminal->slave >= 0)
806 close(terminal->slave);
807 terminal->slave = -1;
808
809 if (terminal->log_fd >= 0)
810 close(terminal->log_fd);
811 terminal->log_fd = -1;
812 }
813
814 /**
815 * Note that this function needs to run before the mainloop starts. Since we
816 * register a handler for the terminal's masterfd when we create the mainloop
817 * the terminal handler needs to see an allocated ringbuffer.
818 */
819 static int lxc_terminal_create_ringbuf(struct lxc_terminal *terminal)
820 {
821 int ret;
822 struct lxc_ringbuf *buf = &terminal->ringbuf;
823 uint64_t size = terminal->buffer_size;
824
825 /* no ringbuffer previously allocated and no ringbuffer requested */
826 if (!buf->addr && size <= 0)
827 return 0;
828
829 /* ringbuffer allocated but no new ringbuffer requested */
830 if (buf->addr && size <= 0) {
831 lxc_ringbuf_release(buf);
832 buf->addr = NULL;
833 buf->r_off = 0;
834 buf->w_off = 0;
835 buf->size = 0;
836 TRACE("Deallocated terminal ringbuffer");
837 return 0;
838 }
839
840 if (size <= 0)
841 return 0;
842
843 /* check wether the requested size for the ringbuffer has changed */
844 if (buf->addr && buf->size != size) {
845 TRACE("Terminal ringbuffer size changed from %" PRIu64
846 " to %" PRIu64 " bytes. Deallocating terminal ringbuffer",
847 buf->size, size);
848 lxc_ringbuf_release(buf);
849 }
850
851 ret = lxc_ringbuf_create(buf, size);
852 if (ret < 0) {
853 ERROR("Failed to setup %" PRIu64 " byte terminal ringbuffer", size);
854 return -1;
855 }
856
857 TRACE("Allocated %" PRIu64 " byte terminal ringbuffer", size);
858 return 0;
859 }
860
861 /**
862 * This is the terminal log file. Please note that the terminal log file is
863 * (implementation wise not content wise) independent of the terminal ringbuffer.
864 */
865 int lxc_terminal_create_log_file(struct lxc_terminal *terminal)
866 {
867 if (!terminal->log_path)
868 return 0;
869
870 terminal->log_fd = lxc_unpriv(open(terminal->log_path, O_CLOEXEC | O_RDWR | O_CREAT | O_APPEND, 0600));
871 if (terminal->log_fd < 0) {
872 SYSERROR("Failed to open terminal log file \"%s\"", terminal->log_path);
873 return -1;
874 }
875
876 DEBUG("Using \"%s\" as terminal log file", terminal->log_path);
877 return 0;
878 }
879
880 int lxc_terminal_create(struct lxc_terminal *terminal)
881 {
882 int ret;
883
884 ret = openpty(&terminal->master, &terminal->slave, NULL, NULL, NULL);
885 if (ret < 0) {
886 SYSERROR("Failed to open terminal");
887 return -1;
888 }
889
890 ret = ttyname_r(terminal->slave, terminal->name, sizeof(terminal->name));
891 if (ret < 0) {
892 SYSERROR("Failed to retrieve name of terminal slave");
893 goto err;
894 }
895
896 ret = fd_cloexec(terminal->master, true);
897 if (ret < 0) {
898 SYSERROR("Failed to set FD_CLOEXEC flag on terminal master");
899 goto err;
900 }
901
902 ret = fd_cloexec(terminal->slave, true);
903 if (ret < 0) {
904 SYSERROR("Failed to set FD_CLOEXEC flag on terminal slave");
905 goto err;
906 }
907
908 ret = lxc_terminal_peer_default(terminal);
909 if (ret < 0) {
910 ERROR("Failed to allocate proxy terminal");
911 goto err;
912 }
913
914 return 0;
915
916 err:
917 lxc_terminal_delete(terminal);
918 return -ENODEV;
919 }
920
921 int lxc_terminal_setup(struct lxc_conf *conf)
922 {
923 int ret;
924 struct lxc_terminal *terminal = &conf->console;
925
926 if (terminal->path && strcmp(terminal->path, "none") == 0) {
927 INFO("No terminal requested");
928 return 0;
929 }
930
931 ret = lxc_terminal_create(terminal);
932 if (ret < 0)
933 return -1;
934
935 ret = lxc_terminal_create_log_file(terminal);
936 if (ret < 0)
937 goto err;
938
939 ret = lxc_terminal_create_ringbuf(terminal);
940 if (ret < 0)
941 goto err;
942
943 return 0;
944
945 err:
946 lxc_terminal_delete(terminal);
947 return -ENODEV;
948 }
949
950 static bool __terminal_dup2(int duplicate, int original)
951 {
952 int ret;
953
954 if (!isatty(original))
955 return true;
956
957 ret = dup2(duplicate, original);
958 if (ret < 0) {
959 SYSERROR("Failed to dup2(%d, %d)", duplicate, original);
960 return false;
961 }
962
963 return true;
964 }
965
966 int lxc_terminal_set_stdfds(int fd)
967 {
968 int i;
969
970 if (fd < 0)
971 return 0;
972
973 for (i = 0; i < 3; i++)
974 if (!__terminal_dup2(fd, (int[]){STDIN_FILENO, STDOUT_FILENO,
975 STDERR_FILENO}[i]))
976 return -1;
977
978 return 0;
979 }
980
981 int lxc_terminal_stdin_cb(int fd, uint32_t events, void *cbdata,
982 struct lxc_epoll_descr *descr)
983 {
984 int ret;
985 char c;
986 struct lxc_terminal_state *ts = cbdata;
987
988 if (fd != ts->stdinfd)
989 return LXC_MAINLOOP_CLOSE;
990
991 ret = lxc_read_nointr(ts->stdinfd, &c, 1);
992 if (ret <= 0)
993 return LXC_MAINLOOP_CLOSE;
994
995 if (ts->escape >= 1) {
996 /* we want to exit the terminal with Ctrl+a q */
997 if (c == ts->escape && !ts->saw_escape) {
998 ts->saw_escape = 1;
999 return LXC_MAINLOOP_CONTINUE;
1000 }
1001
1002 if (c == 'q' && ts->saw_escape)
1003 return LXC_MAINLOOP_CLOSE;
1004
1005 ts->saw_escape = 0;
1006 }
1007
1008 ret = lxc_write_nointr(ts->masterfd, &c, 1);
1009 if (ret <= 0)
1010 return LXC_MAINLOOP_CLOSE;
1011
1012 return LXC_MAINLOOP_CONTINUE;
1013 }
1014
1015 int lxc_terminal_master_cb(int fd, uint32_t events, void *cbdata,
1016 struct lxc_epoll_descr *descr)
1017 {
1018 int r, w;
1019 char buf[LXC_TERMINAL_BUFFER_SIZE];
1020 struct lxc_terminal_state *ts = cbdata;
1021
1022 if (fd != ts->masterfd)
1023 return LXC_MAINLOOP_CLOSE;
1024
1025 r = lxc_read_nointr(fd, buf, sizeof(buf));
1026 if (r <= 0)
1027 return LXC_MAINLOOP_CLOSE;
1028
1029 w = lxc_write_nointr(ts->stdoutfd, buf, r);
1030 if (w <= 0 || w != r)
1031 return LXC_MAINLOOP_CLOSE;
1032
1033 return LXC_MAINLOOP_CONTINUE;
1034 }
1035
1036 int lxc_terminal_getfd(struct lxc_container *c, int *ttynum, int *masterfd)
1037 {
1038 return lxc_cmd_console(c->name, ttynum, masterfd, c->config_path);
1039 }
1040
1041 int lxc_console(struct lxc_container *c, int ttynum,
1042 int stdinfd, int stdoutfd, int stderrfd,
1043 int escape)
1044 {
1045 int masterfd, ret, ttyfd;
1046 struct lxc_epoll_descr descr;
1047 struct termios oldtios;
1048 struct lxc_terminal_state *ts;
1049 int istty = 0;
1050
1051 ttyfd = lxc_cmd_console(c->name, &ttynum, &masterfd, c->config_path);
1052 if (ttyfd < 0)
1053 return -1;
1054
1055 ret = setsid();
1056 if (ret < 0)
1057 TRACE("Process is already group leader");
1058
1059 ts = lxc_terminal_signal_init(stdinfd, masterfd);
1060 if (!ts) {
1061 ret = -1;
1062 goto close_fds;
1063 }
1064 ts->escape = escape;
1065 ts->winch_proxy = c->name;
1066 ts->winch_proxy_lxcpath = c->config_path;
1067 ts->stdoutfd = stdoutfd;
1068
1069 istty = isatty(stdinfd);
1070 if (istty) {
1071 lxc_terminal_winsz(stdinfd, masterfd);
1072 lxc_cmd_terminal_winch(ts->winch_proxy, ts->winch_proxy_lxcpath);
1073 } else {
1074 INFO("File descriptor %d does not refer to a terminal", stdinfd);
1075 }
1076
1077 ret = lxc_mainloop_open(&descr);
1078 if (ret) {
1079 ERROR("Failed to create mainloop");
1080 goto sigwinch_fini;
1081 }
1082
1083 if (ts->sigfd != -1) {
1084 ret = lxc_mainloop_add_handler(&descr, ts->sigfd,
1085 lxc_terminal_signalfd_cb, ts);
1086 if (ret < 0) {
1087 ERROR("Failed to add signal handler to mainloop");
1088 goto close_mainloop;
1089 }
1090 }
1091
1092 ret = lxc_mainloop_add_handler(&descr, ts->stdinfd,
1093 lxc_terminal_stdin_cb, ts);
1094 if (ret < 0) {
1095 ERROR("Failed to add stdin handler");
1096 goto close_mainloop;
1097 }
1098
1099 ret = lxc_mainloop_add_handler(&descr, ts->masterfd,
1100 lxc_terminal_master_cb, ts);
1101 if (ret < 0) {
1102 ERROR("Failed to add master handler");
1103 goto close_mainloop;
1104 }
1105
1106 if (ts->escape >= 1) {
1107 fprintf(stderr,
1108 "\n"
1109 "Connected to tty %1$d\n"
1110 "Type <Ctrl+%2$c q> to exit the console, "
1111 "<Ctrl+%2$c Ctrl+%2$c> to enter Ctrl+%2$c itself\n",
1112 ttynum, 'a' + escape - 1);
1113 }
1114
1115 if (istty) {
1116 ret = lxc_setup_tios(stdinfd, &oldtios);
1117 if (ret < 0)
1118 goto close_mainloop;
1119 }
1120
1121 ret = lxc_mainloop(&descr, -1);
1122 if (ret < 0) {
1123 ERROR("The mainloop returned an error");
1124 goto restore_tios;
1125 }
1126
1127 ret = 0;
1128
1129 restore_tios:
1130 if (istty) {
1131 istty = tcsetattr(stdinfd, TCSAFLUSH, &oldtios);
1132 if (istty < 0)
1133 SYSWARN("Failed to restore terminal properties");
1134 }
1135
1136 close_mainloop:
1137 lxc_mainloop_close(&descr);
1138
1139 sigwinch_fini:
1140 lxc_terminal_signal_fini(ts);
1141
1142 close_fds:
1143 close(masterfd);
1144 close(ttyfd);
1145
1146 return ret;
1147 }
1148
1149 int lxc_make_controlling_terminal(int fd)
1150 {
1151 int ret;
1152
1153 setsid();
1154
1155 ret = ioctl(fd, TIOCSCTTY, (char *)NULL);
1156 if (ret < 0)
1157 return -1;
1158
1159 return 0;
1160 }
1161
1162 int lxc_terminal_prepare_login(int fd)
1163 {
1164 int ret;
1165
1166 ret = lxc_make_controlling_terminal(fd);
1167 if (ret < 0)
1168 return -1;
1169
1170 ret = lxc_terminal_set_stdfds(fd);
1171 if (ret < 0)
1172 return -1;
1173
1174 if (fd > STDERR_FILENO)
1175 close(fd);
1176
1177 return 0;
1178 }
1179
1180 void lxc_terminal_info_init(struct lxc_terminal_info *terminal)
1181 {
1182 terminal->name[0] = '\0';
1183 terminal->master = -EBADF;
1184 terminal->slave = -EBADF;
1185 terminal->busy = -1;
1186 }
1187
1188 void lxc_terminal_init(struct lxc_terminal *terminal)
1189 {
1190 memset(terminal, 0, sizeof(*terminal));
1191 terminal->slave = -EBADF;
1192 terminal->master = -EBADF;
1193 terminal->peer = -EBADF;
1194 terminal->log_fd = -EBADF;
1195 lxc_terminal_info_init(&terminal->proxy);
1196 }
1197
1198 void lxc_terminal_conf_free(struct lxc_terminal *terminal)
1199 {
1200 free(terminal->log_path);
1201 free(terminal->path);
1202 if (terminal->buffer_size > 0 && terminal->ringbuf.addr)
1203 lxc_ringbuf_release(&terminal->ringbuf);
1204 }
1205
1206 int lxc_terminal_map_ids(struct lxc_conf *c, struct lxc_terminal *terminal)
1207 {
1208 int ret;
1209
1210 if (lxc_list_empty(&c->id_map))
1211 return 0;
1212
1213 if (strcmp(terminal->name, "") == 0)
1214 return 0;
1215
1216 ret = chown_mapped_root(terminal->name, c);
1217 if (ret < 0) {
1218 ERROR("Failed to chown terminal \"%s\"", terminal->name);
1219 return -1;
1220 }
1221
1222 TRACE("Chowned terminal \"%s\"", terminal->name);
1223
1224 return 0;
1225 }