Skip to content

Commit 17a036d

Browse files
authored
Merge pull request #89 from utam0k/tty-refactor
clean up around the tty.
2 parents ea5b8f9 + 11810e7 commit 17a036d

File tree

6 files changed

+47
-65
lines changed

6 files changed

+47
-65
lines changed

Diff for: src/cgroups/v2/manager.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ impl Manager {
102102
Ok(controllers)
103103
}
104104

105-
fn write_controllers(path: &Path, controllers: &Vec<String>) -> Result<()> {
105+
fn write_controllers(path: &Path, controllers: &[String]) -> Result<()> {
106106
for controller in controllers {
107107
common::write_cgroup_file_str(path.join(CGROUP_SUBTREE_CONTROL), controller)?;
108108
}

Diff for: src/create.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub struct Create {
3333
bundle: PathBuf,
3434
/// Unix socket (file) path , which will receive file descriptor of the writing end of the pseudoterminal
3535
#[clap(short, long)]
36-
console_socket: Option<String>,
36+
console_socket: Option<PathBuf>,
3737
/// name of the container instance to be started
3838
pub container_id: String,
3939
}
@@ -86,16 +86,13 @@ impl Create {
8686
let mut notify_socket: NotifyListener = NotifyListener::new(&container_dir)?;
8787
// convert path of root file system of the container to absolute path
8888
let rootfs = fs::canonicalize(&spec.root.path)?;
89+
8990
// if socket file path is given in commandline options,
90-
// get file descriptors of console and console socket
91-
let (csocketfd, _consolefd) = {
92-
if let Some(console_socket) = &self.console_socket {
93-
let (csocketfd, consolefd) =
94-
tty::load_console_sockets(&container_dir, console_socket)?;
95-
(Some(csocketfd), Some(consolefd))
96-
} else {
97-
(None, None)
98-
}
91+
// get file descriptors of console socket
92+
let csocketfd = if let Some(console_socket) = &self.console_socket {
93+
Some(tty::setup_console_socket(&container_dir, console_socket)?)
94+
} else {
95+
None
9996
};
10097

10198
let process = run_container(
@@ -162,7 +159,7 @@ fn run_container<P: AsRef<Path>>(
162159

163160
// set up tty if specified
164161
if let Some(csocketfd) = csocketfd {
165-
tty::ready(csocketfd)?;
162+
tty::setup_console(csocketfd)?;
166163
}
167164

168165
// set namespaces

Diff for: src/main.rs

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
//! Container Runtime written in Rust, inspired by [railcar](https://github.com/oracle/railcar)
33
//! This crate provides a container runtime which can be used by a high-level container runtime to run containers.
44
5-
use procfs;
65
use std::fs;
76
use std::path::{Path, PathBuf};
87

Diff for: src/namespaces.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! Process (processes in a namespace have two PIDs, one for the global PID,
44
//! which is used by the main system and the second one is for the child within the process tree),
55
//! Interprocess Communication (Control or communication between processes),
6-
//! Network (which network devices can be seen by the processes in the namespace), User (User configs),
6+
//! Network (which network devices can be seen by the processes in the namespace), User (User configs),
77
//! UTS (hostname and domain information, processes will think they're running on servers with different names),
88
//! Cgroup (Resource limits, execution priority etc.)
99

Diff for: src/tty.rs

+33-44
Original file line numberDiff line numberDiff line change
@@ -6,44 +6,21 @@ use std::path::Path;
66

77
use anyhow::{bail, Result};
88
use nix::errno::Errno;
9-
use nix::fcntl;
109
use nix::sys::socket;
11-
use nix::sys::stat;
10+
use nix::sys::uio;
1211
use nix::unistd::{close, setsid};
1312

1413
use crate::stdio;
1514
use crate::stdio::FileDescriptor;
1615

17-
pub fn ready(console_fd: FileDescriptor) -> Result<()> {
18-
let openpty_result = nix::pty::openpty(None, None)?;
19-
let data: &[u8] = b"/dev/ptmx";
20-
let iov = [nix::sys::uio::IoVec::from_slice(data)];
21-
let fds = [openpty_result.master];
22-
let cmsg = socket::ControlMessage::ScmRights(&fds);
23-
socket::sendmsg(
24-
console_fd.as_raw_fd(),
25-
&iov,
26-
&[cmsg],
27-
socket::MsgFlags::empty(),
28-
None,
29-
)?;
16+
// TODO: Handling when there isn't console-socket.
3017

31-
setsid()?;
32-
if unsafe { libc::ioctl(openpty_result.slave, libc::TIOCSCTTY) } < 0 {
33-
log::warn!("could not TIOCSCTTY");
34-
};
35-
let slave = FileDescriptor::from(openpty_result.slave);
36-
stdio::connect_stdio(&slave, &slave, &slave).expect("could not dup tty to stderr");
37-
close(console_fd.as_raw_fd())?;
38-
Ok(())
39-
}
40-
41-
pub fn load_console_sockets(
18+
pub fn setup_console_socket(
4219
container_dir: &Path,
43-
console_socket: &str,
44-
) -> Result<(FileDescriptor, FileDescriptor)> {
45-
let csocket = "console-stdout";
46-
symlink(console_socket, container_dir.join(csocket))?;
20+
console_socket_path: &Path,
21+
) -> Result<FileDescriptor> {
22+
let csocket = "console-socket";
23+
symlink(console_socket_path, container_dir.join(csocket))?;
4724

4825
let mut csocketfd = socket::socket(
4926
socket::AddressFamily::Unix,
@@ -63,19 +40,31 @@ pub fn load_console_sockets(
6340
}
6441
Ok(()) => csocketfd,
6542
};
66-
let console = "console";
67-
let consolefd = match fcntl::open(
68-
&*console,
69-
fcntl::OFlag::O_NOCTTY | fcntl::OFlag::O_RDWR,
70-
stat::Mode::empty(),
71-
) {
72-
Err(e) => {
73-
if e != ::nix::Error::Sys(Errno::ENOENT) {
74-
bail!("failed to open {}", console);
75-
}
76-
-1
77-
}
78-
Ok(fd) => fd,
43+
Ok(csocketfd.into())
44+
}
45+
46+
pub fn setup_console(console_fd: FileDescriptor) -> Result<()> {
47+
// You can also access pty master, but it is better to use the API.
48+
// ref. https://github.com/containerd/containerd/blob/261c107ffc4ff681bc73988f64e3f60c32233b37/vendor/github.com/containerd/go-runc/console.go#L139-L154
49+
let openpty_result = nix::pty::openpty(None, None)?;
50+
let pty_name: &[u8] = b"/dev/ptmx";
51+
let iov = [uio::IoVec::from_slice(pty_name)];
52+
let fds = [openpty_result.master];
53+
let cmsg = socket::ControlMessage::ScmRights(&fds);
54+
socket::sendmsg(
55+
console_fd.as_raw_fd(),
56+
&iov,
57+
&[cmsg],
58+
socket::MsgFlags::empty(),
59+
None,
60+
)?;
61+
62+
setsid()?;
63+
if unsafe { libc::ioctl(openpty_result.slave, libc::TIOCSCTTY) } < 0 {
64+
log::warn!("could not TIOCSCTTY");
7965
};
80-
Ok((csocketfd.into(), consolefd.into()))
66+
let slave = FileDescriptor::from(openpty_result.slave);
67+
stdio::connect_stdio(&slave, &slave, &slave).expect("could not dup tty to stderr");
68+
close(console_fd.as_raw_fd())?;
69+
Ok(())
8170
}

Diff for: src/utils.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,10 @@ pub fn do_exec(path: impl AsRef<Path>, args: &[String], envs: &[String]) -> Resu
4646
env::vars().for_each(|(key, _value)| std::env::remove_var(key));
4747
// set env vars
4848
envs.iter().for_each(|e| {
49-
let mut split = e.split("=");
50-
match split.next() {
51-
Some(key) => {
52-
let value: String = split.collect::<Vec<&str>>().join("=");
53-
env::set_var(key, value)
54-
}
55-
None => {}
49+
let mut split = e.split('=');
50+
if let Some(key) = split.next() {
51+
let value: String = split.collect::<Vec<&str>>().join("=");
52+
env::set_var(key, value)
5653
};
5754
});
5855

0 commit comments

Comments
 (0)