1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#![allow(deprecated)]
use cmd::{MonitorCall, PortalCall};
use config::portal::Portal;
use jail::JailFn;
use {MONITOR_SOCKET_PATH, PORTAL_SOCKET_PATH};
use self::manager::manager_listen;
use std::fs;
use std::io::ErrorKind;
use std::process::exit;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::Relaxed;
use std::sync::mpsc::{Sender, channel};
use std::thread;
use unix_socket::{UnixListener, UnixStream};
use util::recv;
pub use srv::manager::{DomDesc, GetDotRequest, ManagerAction, NewDomRequest};
mod manager;
fn portal_handle(mut stream: UnixStream, manager_tx: Sender<ManagerAction>) -> Result<(), String> {
let decoded = try!(recv(&mut stream));
debug!("Portal got request: {:?}", decoded);
match decoded {
PortalCall::Run(action) => action.call(stream, manager_tx),
PortalCall::Info(action) => action.call(stream, manager_tx),
}
}
fn monitor_handle(mut stream: UnixStream, cmd_tx: Sender<Box<JailFn>>) -> Result<(), String> {
let decoded = try!(recv(&mut stream));
debug!("Monitor got request: {:?}", decoded);
match decoded {
MonitorCall::Mount(action) => action.call(cmd_tx),
MonitorCall::Shim(action) => action.call(cmd_tx, stream),
}
}
fn portal_ext_listen(manager_tx: Sender<ManagerAction>) {
let server = PORTAL_SOCKET_PATH;
let _ = fs::remove_file(&server);
let stream = match UnixListener::bind(&server) {
Ok(s) => s,
Err(e) => {
error!("Failed to bind to {:?}: {}", server, e);
exit(1);
}
};
for client in stream.incoming() {
match client {
Ok(c) => {
let manager_tx = manager_tx.clone();
thread::spawn(|| {
match portal_handle(c, manager_tx) {
Ok(_) => {},
Err(e) => error!("Error handling portal client: {}", e),
}
});
}
Err(e) => {
warn!("Portal connection error: {}", e);
return;
}
}
}
}
pub fn portal_listen(portal: Portal) -> Result<(), String> {
let (manager_tx, manager_rx) = channel();
thread::spawn(|| portal_ext_listen(manager_tx));
manager_listen(portal, manager_rx);
Ok(())
}
pub fn monitor_listen(cmd_tx: Sender<Box<JailFn>>, quit: Arc<AtomicBool>) {
let server = MONITOR_SOCKET_PATH;
let mut request_count = 0u64;
let _ = fs::remove_file(&server);
let acceptor = match UnixListener::bind(&server) {
Err(e) => {
error!("Failed to bind to {:?}: {}", server, e);
exit(1);
}
Ok(v) => v,
};
while !quit.load(Relaxed) {
match acceptor.accept() {
Ok((s, _)) => {
let client_cmd_fn = cmd_tx.clone();
request_count += 1;
thread::spawn(|| {
match monitor_handle(s, client_cmd_fn) {
Ok(_) => {},
Err(e) => debug!("Error handling monitor client: {}", e),
}
});
}
Err(ref e) if e.kind() == ErrorKind::TimedOut => {}
Err(e) => debug!("Connection error: {}", e),
}
}
info!("Monitor got {} requests", request_count);
}