conmon: Add unix domain socket for attach
Signed-off-by: Mrunal Patel <mpatel@redhat.com>
This commit is contained in:
parent
5c383d13d2
commit
065f12490c
3 changed files with 104 additions and 5 deletions
104
conmon/conmon.c
104
conmon/conmon.c
|
@ -93,6 +93,7 @@ static inline void strv_cleanup(char ***strv)
|
||||||
|
|
||||||
static bool terminal = false;
|
static bool terminal = false;
|
||||||
static char *cid = NULL;
|
static char *cid = NULL;
|
||||||
|
static char *cuuid = NULL;
|
||||||
static char *runtime_path = NULL;
|
static char *runtime_path = NULL;
|
||||||
static char *bundle_path = NULL;
|
static char *bundle_path = NULL;
|
||||||
static char *pid_file = NULL;
|
static char *pid_file = NULL;
|
||||||
|
@ -104,6 +105,7 @@ static GOptionEntry entries[] =
|
||||||
{
|
{
|
||||||
{ "terminal", 't', 0, G_OPTION_ARG_NONE, &terminal, "Terminal", NULL },
|
{ "terminal", 't', 0, G_OPTION_ARG_NONE, &terminal, "Terminal", NULL },
|
||||||
{ "cid", 'c', 0, G_OPTION_ARG_STRING, &cid, "Container ID", NULL },
|
{ "cid", 'c', 0, G_OPTION_ARG_STRING, &cid, "Container ID", NULL },
|
||||||
|
{ "cuuid", 'u', 0, G_OPTION_ARG_STRING, &cuuid, "Container UUID", NULL },
|
||||||
{ "runtime", 'r', 0, G_OPTION_ARG_STRING, &runtime_path, "Runtime path", NULL },
|
{ "runtime", 'r', 0, G_OPTION_ARG_STRING, &runtime_path, "Runtime path", NULL },
|
||||||
{ "bundle", 'b', 0, G_OPTION_ARG_STRING, &bundle_path, "Bundle path", NULL },
|
{ "bundle", 'b', 0, G_OPTION_ARG_STRING, &bundle_path, "Bundle path", NULL },
|
||||||
{ "pidfile", 'p', 0, G_OPTION_ARG_STRING, &pid_file, "PID file", NULL },
|
{ "pidfile", 'p', 0, G_OPTION_ARG_STRING, &pid_file, "PID file", NULL },
|
||||||
|
@ -436,6 +438,7 @@ int main(int argc, char *argv[])
|
||||||
int ret, runtime_status;
|
int ret, runtime_status;
|
||||||
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];
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
_cleanup_free_ char *contents;
|
_cleanup_free_ char *contents;
|
||||||
int cpid = -1;
|
int cpid = -1;
|
||||||
|
@ -470,6 +473,9 @@ int main(int argc, char *argv[])
|
||||||
int wb;
|
int wb;
|
||||||
uint64_t oom_event;
|
uint64_t oom_event;
|
||||||
|
|
||||||
|
/* Used for attach */
|
||||||
|
_cleanup_close_ int conn_sock = -1;
|
||||||
|
|
||||||
/* Command line parameters */
|
/* Command line parameters */
|
||||||
context = g_option_context_new("- conmon utility");
|
context = g_option_context_new("- conmon utility");
|
||||||
g_option_context_add_main_entries(context, entries, "conmon");
|
g_option_context_add_main_entries(context, entries, "conmon");
|
||||||
|
@ -481,6 +487,9 @@ int main(int argc, char *argv[])
|
||||||
if (cid == NULL)
|
if (cid == NULL)
|
||||||
nexit("Container ID not provided. Use --cid");
|
nexit("Container ID not provided. Use --cid");
|
||||||
|
|
||||||
|
if (!exec && cuuid == NULL)
|
||||||
|
nexit("Container UUID not provided. Use --cuuid");
|
||||||
|
|
||||||
if (runtime_path == NULL)
|
if (runtime_path == NULL)
|
||||||
nexit("Runtime path not provided. Use --runtime");
|
nexit("Runtime path not provided. Use --runtime");
|
||||||
|
|
||||||
|
@ -553,7 +562,7 @@ int main(int argc, char *argv[])
|
||||||
csfd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
|
csfd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
|
||||||
if (csfd < 0)
|
if (csfd < 0)
|
||||||
pexit("Failed to create console-socket");
|
pexit("Failed to create console-socket");
|
||||||
if (fchmod(csfd, 0700))
|
if (fchmod(csfd, 0700))
|
||||||
pexit("Failed to change console-socket permissions");
|
pexit("Failed to change console-socket permissions");
|
||||||
/* XXX: This should be handled with a rename(2). */
|
/* XXX: This should be handled with a rename(2). */
|
||||||
if (unlink(csname) < 0)
|
if (unlink(csname) < 0)
|
||||||
|
@ -745,6 +754,50 @@ int main(int argc, char *argv[])
|
||||||
cpid = atoi(contents);
|
cpid = atoi(contents);
|
||||||
ninfo("container PID: %d", cpid);
|
ninfo("container PID: %d", cpid);
|
||||||
|
|
||||||
|
/* Setup endpoint for attach */
|
||||||
|
char attach_symlink_dir_path[PATH_MAX];
|
||||||
|
struct sockaddr_un attach_addr = {0};
|
||||||
|
_cleanup_close_ int afd = -1;
|
||||||
|
|
||||||
|
if (!exec) {
|
||||||
|
attach_addr.sun_family = AF_UNIX;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a symlink so we don't exceed unix domain socket
|
||||||
|
* path length limit.
|
||||||
|
*/
|
||||||
|
snprintf(attach_symlink_dir_path, PATH_MAX, "/var/run/crio/%s", cuuid);
|
||||||
|
if (unlink(attach_symlink_dir_path) == -1 && errno != ENOENT) {
|
||||||
|
pexit("Failed to remove existing symlink for attach socket directory");
|
||||||
|
}
|
||||||
|
if (symlink(bundle_path, attach_symlink_dir_path) == -1)
|
||||||
|
pexit("Failed to create symlink for attach socket");
|
||||||
|
|
||||||
|
snprintf(attach_sock_path, PATH_MAX, "/var/run/crio/%s/attach", cuuid);
|
||||||
|
ninfo("attach sock path: %s", attach_sock_path);
|
||||||
|
|
||||||
|
strncpy(attach_addr.sun_path, attach_sock_path, sizeof(attach_addr.sun_path) - 1);
|
||||||
|
ninfo("addr{sun_family=AF_UNIX, sun_path=%s}", attach_addr.sun_path);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We make the socket non-blocking to avoid a race where client aborts connection
|
||||||
|
* before the server gets a chance to call accept. In that scenario, the server
|
||||||
|
* accept blocks till a new client connection comes in.
|
||||||
|
*/
|
||||||
|
afd = socket(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0);
|
||||||
|
if (afd == -1)
|
||||||
|
pexit("Failed to create attach socket");
|
||||||
|
|
||||||
|
if (fchmod(afd, 0700))
|
||||||
|
pexit("Failed to change attach socket permissions");
|
||||||
|
|
||||||
|
if (bind(afd, (struct sockaddr *)&attach_addr, sizeof(struct sockaddr_un)) == -1)
|
||||||
|
pexit("Failed to bind attach socket: %s", attach_sock_path);
|
||||||
|
|
||||||
|
if (listen(afd, 10) == -1)
|
||||||
|
pexit("Failed to listen on attach socket: %s", attach_sock_path);
|
||||||
|
}
|
||||||
|
|
||||||
/* 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);
|
||||||
|
@ -810,6 +863,13 @@ int main(int argc, char *argv[])
|
||||||
pexit("Failed to add OOM eventfd to epoll");
|
pexit("Failed to add OOM eventfd to epoll");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add the attach socket to epoll */
|
||||||
|
if (afd > 0) {
|
||||||
|
ev.data.fd = afd;
|
||||||
|
if (epoll_ctl(epfd, EPOLL_CTL_ADD, ev.data.fd, &ev) < 0)
|
||||||
|
pexit("Failed to add attach socket 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);
|
||||||
|
@ -831,10 +891,28 @@ int main(int argc, char *argv[])
|
||||||
if (open("oom", O_CREAT, 0666) < 0) {
|
if (open("oom", O_CREAT, 0666) < 0) {
|
||||||
nwarn("Failed to write oom file");
|
nwarn("Failed to write oom file");
|
||||||
}
|
}
|
||||||
}
|
} else if (evlist[i].data.fd == afd) {
|
||||||
else {
|
conn_sock = accept(afd, NULL, NULL);
|
||||||
nwarn("unknown pipe fd");
|
if (conn_sock == -1) {
|
||||||
goto out;
|
nwarn("Failed to accept client connection on attach socket");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ev.events = EPOLLIN;
|
||||||
|
ev.data.fd = conn_sock;
|
||||||
|
if (epoll_ctl(epfd, EPOLL_CTL_ADD, ev.data.fd, &ev) == -1) {
|
||||||
|
pexit("Failed to add client socket fd to epoll");
|
||||||
|
}
|
||||||
|
ninfo("Accepted connection");
|
||||||
|
} else {
|
||||||
|
num_read = read(masterfd, buf, BUF_SIZE);
|
||||||
|
if (num_read <= 0)
|
||||||
|
goto out;
|
||||||
|
ninfo("got data on connection: %d", num_read);
|
||||||
|
if (terminal) {
|
||||||
|
if (write_all(masterfd_stdout, buf, num_read) < 0) {
|
||||||
|
nwarn("Failed to write to master pty");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (masterfd == masterfd_stdout || masterfd == masterfd_stderr) {
|
if (masterfd == masterfd_stdout || masterfd == masterfd_stderr) {
|
||||||
|
@ -846,11 +924,21 @@ int main(int argc, char *argv[])
|
||||||
nwarn("write_k8s_log failed");
|
nwarn("write_k8s_log failed");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (conn_sock > 0) {
|
||||||
|
if (write_all(conn_sock, buf, num_read) < 0) {
|
||||||
|
nwarn("Failed to write to socket");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (evlist[i].events & (EPOLLHUP | EPOLLERR)) {
|
} else if (evlist[i].events & (EPOLLHUP | EPOLLERR)) {
|
||||||
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");
|
||||||
|
if (!exec && evlist[i].data.fd == conn_sock) {
|
||||||
|
conn_sock = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
num_stdio_fds--;
|
num_stdio_fds--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -906,5 +994,11 @@ out:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!exec) {
|
||||||
|
if (unlink(attach_symlink_dir_path) == -1 && errno != ENOENT) {
|
||||||
|
pexit("Failed to remove symlink for attach socket directory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,6 +114,7 @@ func (r *Runtime) CreateContainer(c *Container, cgroupParent string) error {
|
||||||
args = append(args, "-s")
|
args = append(args, "-s")
|
||||||
}
|
}
|
||||||
args = append(args, "-c", c.name)
|
args = append(args, "-c", c.name)
|
||||||
|
args = append(args, "-u", c.id)
|
||||||
args = append(args, "-r", r.Path(c))
|
args = append(args, "-r", r.Path(c))
|
||||||
args = append(args, "-b", c.bundlePath)
|
args = append(args, "-b", c.bundlePath)
|
||||||
args = append(args, "-p", filepath.Join(c.bundlePath, "pidfile"))
|
args = append(args, "-p", filepath.Join(c.bundlePath, "pidfile"))
|
||||||
|
|
|
@ -555,6 +555,10 @@ func New(config *Config) (*Server, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := os.MkdirAll("/var/run/crio", 0755); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
r, err := oci.New(config.Runtime, config.RuntimeHostPrivileged, config.Conmon, config.ConmonEnv, config.CgroupManager)
|
r, err := oci.New(config.Runtime, config.RuntimeHostPrivileged, config.Conmon, config.ConmonEnv, config.CgroupManager)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue