解决在clone之后立即删除pause标志文件导致出错的问题

main
阳光少年 1 year ago
parent 239da495eb
commit 3f48637ab0

@ -262,10 +262,15 @@ fn init_container_mount() -> Result<()> {
fn init_container_log(log: bool) -> Result<()> { fn init_container_log(log: bool) -> Result<()> {
let log_path = Path::new("logs"); let log_path = Path::new("logs");
create_dir(log_path, true)?; create_dir(log_path, true)?;
let log_fd = fs::File::create(log_path.join("log"))?; let log_file = fs::OpenOptions::new()
.create(true)
.append(true)
.write(true)
.read(true)
.open(log_path.join("log"))?;
if log { if log {
unsafe { unsafe {
let log_fd_raw = log_fd.as_raw_fd(); let log_fd_raw = log_file.as_raw_fd();
dup2(log_fd_raw, 1)?; dup2(log_fd_raw, 1)?;
dup2(log_fd_raw, 2)?; dup2(log_fd_raw, 2)?;
} }
@ -309,28 +314,25 @@ fn init_exec_ns(pid: i32) -> Result<()>{
Ok(()) Ok(())
} }
fn create_pause() -> Result<()> { fn create_pause(container_root_pause_path: &Path) -> Result<()> {
fs::OpenOptions::new() fs::OpenOptions::new()
.write(true) .write(true)
.create(true) .create(true)
.read(true) .read(true)
.open("/pause")?; .open(container_root_pause_path)?;
Ok(()) Ok(())
} }
fn check_pause<P: AsRef<Path>>(pause_path: P) -> bool {
// 判断该文件还在不在
pause_path.as_ref().exists()
}
fn start(is_wait: bool, cb: CloneCb, clong_flags: CloneFlags, container_id: &String, container_merged_pause_path: &PathBuf) -> Result<i32>{ fn start(is_wait: bool, cb: CloneCb, clong_flags: CloneFlags, container_id: &String, container_merged_pause_path: &PathBuf) -> Result<i32>{
match unsafe {clone(cb, STACK.as_mut_slice(), clong_flags, None)} { match unsafe {clone(cb, STACK.as_mut_slice(), clong_flags, None)} {
Ok(child_pid) => { Ok(child_pid) => {
println!("clone ok: {child_pid:?}"); println!("clone ok: {child_pid:?}");
// exec之前的步骤 // exec之前的步骤
create_network(container_id, child_pid.as_raw()); create_network(container_id, child_pid.as_raw());
// 删除 container_merged_pause_path 解开阻塞 // 删除 pause标志文件, 解开阻塞, 使其执行exec
std::fs::remove_file(container_merged_pause_path)?; while std::fs::remove_file(container_merged_pause_path).is_err(){
std::thread::sleep(std::time::Duration::from_millis(10));
}
// 检查是否执行exec了 // 检查是否执行exec了
let mut cnt = 0; let mut cnt = 0;
@ -373,25 +375,23 @@ fn run_container(_container_id: &String, cmd: &String, args: &RockerArgs, volume
} }
let clone_flags; let clone_flags;
let container_work_path = Path::new(WORKSPACE).join("containers").join(&_container_id); let container_work_path = Path::new(WORKSPACE).join("containers").join(&_container_id);
let container_upper_path = container_work_path.join("upper"); let container_upper_path = container_work_path.join("upper");
let container_merged_path = container_work_path.join("merged"); let container_merged_path = container_work_path.join("merged");
let container_merged_pause_path = container_work_path.join("merged").join("pause"); let container_merged_pause_path = container_work_path.join("merged").join("pause");
let container_root_pause_path = Path::new("/pause");
let rocker_user_info = User::from_name(USER_NAME)?.ok_or(RockerError::OtherError(format!("没找到 用户: {USER_NAME}")))?; let rocker_user_info = User::from_name(USER_NAME)?.ok_or(RockerError::OtherError(format!("没找到 用户: {USER_NAME}")))?;
let rocker_uid = rocker_user_info.uid; let rocker_uid = rocker_user_info.uid;
let rocker_gid = rocker_user_info.gid; let rocker_gid = rocker_user_info.gid;
let _cb = if is_exec { let _cb = if is_exec {
let _cb = || { let _cb = || {
dbg!(1);
let container_info = get_container_info(_container_id).unwrap(); let container_info = get_container_info(_container_id).unwrap();
init_exec_ns(container_info.pid).unwrap(); init_exec_ns(container_info.pid).unwrap();
init_container_env(None).unwrap(); init_container_env(None).unwrap();
init_container_user(rocker_uid, rocker_gid).unwrap(); init_container_user(rocker_uid, rocker_gid).unwrap();
dbg!(2); create_pause(container_root_pause_path).unwrap();
create_pause().unwrap();
while container_merged_pause_path.exists() { while container_merged_pause_path.exists() {
std::thread::sleep(std::time::Duration::from_millis(10)); std::thread::sleep(std::time::Duration::from_millis(10));
} }
@ -424,8 +424,8 @@ fn run_container(_container_id: &String, cmd: &String, args: &RockerArgs, volume
init_container_log(args.log).unwrap(); init_container_log(args.log).unwrap();
init_container_user(rocker_uid, rocker_gid).unwrap(); init_container_user(rocker_uid, rocker_gid).unwrap();
create_pause().unwrap(); create_pause(&container_root_pause_path).unwrap();
while container_merged_pause_path.exists() { while container_root_pause_path.exists() {
std::thread::sleep(std::time::Duration::from_millis(10)); std::thread::sleep(std::time::Duration::from_millis(10));
} }
@ -618,21 +618,15 @@ fn main() -> Result<()>{
let cmd; let cmd;
match (&args.run, &args.image, &args.restart) { match (&args.run, &args.image, &args.restart) {
(Some(_cmd), Some(image_name), None) => { (Some(_cmd), Some(image_name), None) => {
dbg!(100);
volume_path = extend_image(image_name)?; volume_path = extend_image(image_name)?;
dbg!(101);
container_id = uuid::Uuid::new_v4().to_string()[0..8].to_string(); container_id = uuid::Uuid::new_v4().to_string()[0..8].to_string();
dbg!(102);
cmd = _cmd.clone(); cmd = _cmd.clone();
} }
(None, None, Some(_container_id)) => { (None, None, Some(_container_id)) => {
dbg!(211);
let container_info = get_container_info(_container_id)?; let container_info = get_container_info(_container_id)?;
dbg!(210);
volume_path = extend_image(&container_info.image)?; volume_path = extend_image(&container_info.image)?;
container_id = _container_id.clone(); container_id = _container_id.clone();
cmd = container_info.run; cmd = container_info.run;
dbg!(200);
args.run = Some(cmd.clone()); args.run = Some(cmd.clone());
args.image = Some(container_info.image); args.image = Some(container_info.image);
args.log = container_info.log; args.log = container_info.log;
@ -642,14 +636,12 @@ fn main() -> Result<()>{
if container_info.env.len() > 0 { if container_info.env.len() > 0 {
args.env = Some(container_info.env); args.env = Some(container_info.env);
} }
dbg!(201);
stop_container(&container_id, false)?; stop_container(&container_id, false)?;
} }
_ => { _ => {
unreachable!() unreachable!()
} }
} }
dbg!(3);
match run_container(&container_id, &cmd, &args, &volume_path, false) { match run_container(&container_id, &cmd, &args, &volume_path, false) {
Ok(child_pid) => { Ok(child_pid) => {
save_container_info(&args, &container_id, child_pid)?; save_container_info(&args, &container_id, child_pid)?;

@ -52,9 +52,9 @@ fn set_slave_ip(slave_veth_name: &str, addr: &str, pid: &str) -> bool {
true true
} }
fn set_snat(gateway_addr: &str, bridge_name: &str) -> bool { fn set_snat(gateway_addr: &str, bridge_name: &str, action: &str) -> bool {
// sudo iptables -t nat -A POSTROUTING -s 172.18.0.0/24 ! -o br0 -j MASQUERADE // sudo iptables -t nat -A POSTROUTING -s 172.18.0.0/24 ! -o br0 -j MASQUERADE
let args = ["-t", "nat", "-A", "POSTROUTING", "-s", &format!("{gateway_addr}/24"), "!", "-o", bridge_name, "-j", "MASQUERADE"]; let args = ["-t", "nat", action, "POSTROUTING", "-s", &format!("{gateway_addr}/24"), "!", "-o", bridge_name, "-j", "MASQUERADE"];
let out = std::process::Command::new("iptables") let out = std::process::Command::new("iptables")
.args(args) .args(args)
.output() .output()
@ -386,7 +386,7 @@ pub fn create_network(uuid_name: &str, pid: i32) -> bool {
// 设置转发规则 // 设置转发规则
set_iptables_forward() && set_iptables_forward() &&
// 设置snat // 设置snat
set_snat(&network.gateway_addr, &network.bridge_name) { set_snat(&network.gateway_addr, &network.bridge_name, "-A") {
println!("create_network success"); println!("create_network success");
true true
} else { } else {
@ -397,23 +397,32 @@ pub fn create_network(uuid_name: &str, pid: i32) -> bool {
} }
fn remove_network(uuid_name: &str,) { fn remove_network(uuid_name: &str) {
let bridge_name = format!("ro_{uuid_name}_1");
let master_veth_name = format!("ro_{uuid_name}_2");
let slave_veth_name = format!("ro_{uuid_name}_3");
//
let mut all_network = get_all_network(); let mut all_network = get_all_network();
// 删除 bridge_name 对应的 NetWork let mut network = None;
all_network.retain(|n|n.bridge_name != bridge_name); all_network = all_network.into_iter()
// todo 回写到文件中 .filter_map(|n| {
if n.bridge_name.contains(uuid_name) {
network = Some(n);
None
} else {
Some(n)
}
}).collect::<Vec<NetWrok>>();
if let Some(network) = network {
}
// todo 回写到文件中
// write_network_info(all_network);
} }
fn main(){ fn main(){
let container_id = uuid::Uuid::new_v4().to_string()[0..8].to_string(); let container_id = uuid::Uuid::new_v4().to_string()[0..8].to_string();
create_network(&container_id, 17543); // create_network(&container_id, 17543);
remove_network("ac1aca8d");
return; return;
let addr = "192.168.124.1"; let addr = "192.168.124.1";

Loading…
Cancel
Save