conmon: Add control fifo for terminal resize handling
Signed-off-by: Mrunal Patel <mpatel@redhat.com>
This commit is contained in:
parent
065f12490c
commit
1a6825758c
1 changed files with 101 additions and 0 deletions
101
conmon/conmon.c
101
conmon/conmon.c
|
@ -12,10 +12,12 @@
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/eventfd.h>
|
#include <sys/eventfd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -439,6 +441,7 @@ int main(int argc, char *argv[])
|
||||||
char cwd[PATH_MAX];
|
char cwd[PATH_MAX];
|
||||||
char default_pid_file[PATH_MAX];
|
char default_pid_file[PATH_MAX];
|
||||||
char attach_sock_path[PATH_MAX];
|
char attach_sock_path[PATH_MAX];
|
||||||
|
char ctl_fifo_path[PATH_MAX];
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
_cleanup_free_ char *contents;
|
_cleanup_free_ char *contents;
|
||||||
int cpid = -1;
|
int cpid = -1;
|
||||||
|
@ -798,6 +801,40 @@ int main(int argc, char *argv[])
|
||||||
pexit("Failed to listen on attach socket: %s", attach_sock_path);
|
pexit("Failed to listen on attach socket: %s", attach_sock_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Setup fifo for reading in terminal resize and other stdio control messages */
|
||||||
|
_cleanup_close_ int ctlfd = -1;
|
||||||
|
_cleanup_close_ int dummyfd = -1;
|
||||||
|
int ctl_msg_type = -1;
|
||||||
|
int height = -1;
|
||||||
|
int width = -1;
|
||||||
|
struct winsize ws;
|
||||||
|
#define CTLBUFSZ 200
|
||||||
|
char ctlbuf[CTLBUFSZ];
|
||||||
|
char *readptr = ctlbuf;
|
||||||
|
int readsz = CTLBUFSZ - 1;
|
||||||
|
int cp_rem = 0;
|
||||||
|
if (!exec) {
|
||||||
|
snprintf(ctl_fifo_path, PATH_MAX, "%s/ctl", bundle_path);
|
||||||
|
ninfo("ctl fifo path: %s", ctl_fifo_path);
|
||||||
|
|
||||||
|
if (mkfifo(ctl_fifo_path, 0666) == -1)
|
||||||
|
pexit("Failed to mkfifo at %s", ctl_fifo_path);
|
||||||
|
|
||||||
|
ctlfd = open(ctl_fifo_path, O_RDONLY|O_NONBLOCK|O_CLOEXEC);
|
||||||
|
if (ctlfd == -1)
|
||||||
|
pexit("Failed to open control fifo");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open a dummy writer to prevent getting flood of POLLHUPs when
|
||||||
|
* last writer closes.
|
||||||
|
*/
|
||||||
|
dummyfd = open(ctl_fifo_path, O_WRONLY|O_CLOEXEC);
|
||||||
|
if (dummyfd == -1)
|
||||||
|
pexit("Failed to open dummy writer for fifo");
|
||||||
|
|
||||||
|
ninfo("ctlfd: %d", ctlfd);
|
||||||
|
}
|
||||||
|
|
||||||
/* Send the container pid back to parent */
|
/* Send the container pid back to parent */
|
||||||
if (sync_pipe_fd > 0 && !exec) {
|
if (sync_pipe_fd > 0 && !exec) {
|
||||||
len = snprintf(buf, BUF_SIZE, "{\"pid\": %d}\n", cpid);
|
len = snprintf(buf, BUF_SIZE, "{\"pid\": %d}\n", cpid);
|
||||||
|
@ -870,6 +907,13 @@ int main(int argc, char *argv[])
|
||||||
pexit("Failed to add attach socket fd to epoll");
|
pexit("Failed to add attach socket fd to epoll");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add control fifo fd to epoll */
|
||||||
|
if (ctlfd > 0) {
|
||||||
|
ev.data.fd = ctlfd;
|
||||||
|
if (epoll_ctl(epfd, EPOLL_CTL_ADD, ev.data.fd, &ev) < 0)
|
||||||
|
pexit("Failed to add control fifo fd to epoll");
|
||||||
|
}
|
||||||
|
|
||||||
/* Log all of the container's output. */
|
/* Log all of the container's output. */
|
||||||
while (num_stdio_fds > 0) {
|
while (num_stdio_fds > 0) {
|
||||||
int ready = epoll_wait(epfd, evlist, MAX_EVENTS, -1);
|
int ready = epoll_wait(epfd, evlist, MAX_EVENTS, -1);
|
||||||
|
@ -903,6 +947,59 @@ int main(int argc, char *argv[])
|
||||||
pexit("Failed to add client socket fd to epoll");
|
pexit("Failed to add client socket fd to epoll");
|
||||||
}
|
}
|
||||||
ninfo("Accepted connection");
|
ninfo("Accepted connection");
|
||||||
|
} else if (!exec && evlist[i].data.fd == ctlfd) {
|
||||||
|
num_read = read(ctlfd, readptr, readsz);
|
||||||
|
if (num_read <= 0) {
|
||||||
|
nwarn("Failed to read from control fd");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
readptr[num_read] = '\0';
|
||||||
|
ninfo("Got ctl message: %s\n", ctlbuf);
|
||||||
|
|
||||||
|
char *beg = ctlbuf;
|
||||||
|
char *newline = strchrnul(beg, '\n');
|
||||||
|
/* Process each message which ends with a line */
|
||||||
|
while (*newline != '\0') {
|
||||||
|
ret = sscanf(ctlbuf, "%d %d %d\n", &ctl_msg_type, &height, &width);
|
||||||
|
if (ret != 3) {
|
||||||
|
nwarn("Failed to sscanf message");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ninfo("Message type: %d, Height: %d, Width: %d", ctl_msg_type, height, width);
|
||||||
|
ret = ioctl(masterfd_stdout, TIOCGWINSZ, &ws);
|
||||||
|
ninfo("Existing size: %d %d", ws.ws_row, ws.ws_col);
|
||||||
|
ws.ws_row = height;
|
||||||
|
ws.ws_col = width;
|
||||||
|
ret = ioctl(masterfd_stdout, TIOCSWINSZ, &ws);
|
||||||
|
if (ret == -1) {
|
||||||
|
nwarn("Failed to set process pty terminal size");
|
||||||
|
}
|
||||||
|
beg = newline + 1;
|
||||||
|
newline = strchrnul(beg, '\n');
|
||||||
|
}
|
||||||
|
if (num_read == (CTLBUFSZ - 1) && beg == ctlbuf) {
|
||||||
|
/*
|
||||||
|
* We did not find a newline in the entire buffer.
|
||||||
|
* This shouldn't happen as our buffer is larger than
|
||||||
|
* the message that we expect to receive.
|
||||||
|
*/
|
||||||
|
nwarn("Could not find newline in entire buffer\n");
|
||||||
|
} else if (*beg == '\0') {
|
||||||
|
/* We exhausted all messages that were complete */
|
||||||
|
readptr = ctlbuf;
|
||||||
|
readsz = CTLBUFSZ - 1;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* We copy remaining data to beginning of buffer
|
||||||
|
* and advance readptr after that.
|
||||||
|
*/
|
||||||
|
cp_rem = 0;
|
||||||
|
do {
|
||||||
|
ctlbuf[cp_rem++] = *beg++;
|
||||||
|
} while (*beg != '\0');
|
||||||
|
readptr = ctlbuf + cp_rem;
|
||||||
|
readsz = CTLBUFSZ - 1 - cp_rem;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
num_read = read(masterfd, buf, BUF_SIZE);
|
num_read = read(masterfd, buf, BUF_SIZE);
|
||||||
if (num_read <= 0)
|
if (num_read <= 0)
|
||||||
|
@ -932,6 +1029,10 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (evlist[i].events & (EPOLLHUP | EPOLLERR)) {
|
} else if (evlist[i].events & (EPOLLHUP | EPOLLERR)) {
|
||||||
|
if (!exec && evlist[i].data.fd == ctlfd) {
|
||||||
|
ninfo("Remote writer to control fd closed");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
printf("closing fd %d\n", evlist[i].data.fd);
|
printf("closing fd %d\n", evlist[i].data.fd);
|
||||||
if (close(evlist[i].data.fd) < 0)
|
if (close(evlist[i].data.fd) < 0)
|
||||||
pexit("close");
|
pexit("close");
|
||||||
|
|
Loading…
Reference in a new issue