From 3f48637ab0f3f9a46e59b7923df8db7643912c29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=B3=E5=85=89=E5=B0=91=E5=B9=B4?= <849317537@qq.com> Date: Sat, 10 Aug 2024 03:30:42 +0000 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=9C=A8clone=E4=B9=8B?= =?UTF-8?q?=E5=90=8E=E7=AB=8B=E5=8D=B3=E5=88=A0=E9=99=A4pause=E6=A0=87?= =?UTF-8?q?=E5=BF=97=E6=96=87=E4=BB=B6=E5=AF=BC=E8=87=B4=E5=87=BA=E9=94=99?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.rs | 44 ++++++++++++++++++-------------------------- src/network.rs | 35 ++++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/src/main.rs b/src/main.rs index 4d7c39a..ae043c5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -262,10 +262,15 @@ fn init_container_mount() -> Result<()> { fn init_container_log(log: bool) -> Result<()> { let log_path = Path::new("logs"); 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 { 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, 2)?; } @@ -309,28 +314,25 @@ fn init_exec_ns(pid: i32) -> Result<()>{ Ok(()) } -fn create_pause() -> Result<()> { +fn create_pause(container_root_pause_path: &Path) -> Result<()> { fs::OpenOptions::new() .write(true) .create(true) .read(true) - .open("/pause")?; + .open(container_root_pause_path)?; Ok(()) } -fn check_pause>(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{ match unsafe {clone(cb, STACK.as_mut_slice(), clong_flags, None)} { Ok(child_pid) => { println!("clone ok: {child_pid:?}"); // exec之前的步骤 create_network(container_id, child_pid.as_raw()); - // 删除 container_merged_pause_path 解开阻塞 - std::fs::remove_file(container_merged_pause_path)?; + // 删除 pause标志文件, 解开阻塞, 使其执行exec + while std::fs::remove_file(container_merged_pause_path).is_err(){ + std::thread::sleep(std::time::Duration::from_millis(10)); + } // 检查是否执行exec了 let mut cnt = 0; @@ -373,25 +375,23 @@ fn run_container(_container_id: &String, cmd: &String, args: &RockerArgs, volume } let clone_flags; - let container_work_path = Path::new(WORKSPACE).join("containers").join(&_container_id); let container_upper_path = container_work_path.join("upper"); let container_merged_path = container_work_path.join("merged"); 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_uid = rocker_user_info.uid; let rocker_gid = rocker_user_info.gid; - + let _cb = if is_exec { let _cb = || { - dbg!(1); let container_info = get_container_info(_container_id).unwrap(); init_exec_ns(container_info.pid).unwrap(); init_container_env(None).unwrap(); init_container_user(rocker_uid, rocker_gid).unwrap(); - dbg!(2); - create_pause().unwrap(); + create_pause(container_root_pause_path).unwrap(); while container_merged_pause_path.exists() { 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_user(rocker_uid, rocker_gid).unwrap(); - create_pause().unwrap(); - while container_merged_pause_path.exists() { + create_pause(&container_root_pause_path).unwrap(); + while container_root_pause_path.exists() { std::thread::sleep(std::time::Duration::from_millis(10)); } @@ -618,21 +618,15 @@ fn main() -> Result<()>{ let cmd; match (&args.run, &args.image, &args.restart) { (Some(_cmd), Some(image_name), None) => { - dbg!(100); volume_path = extend_image(image_name)?; - dbg!(101); container_id = uuid::Uuid::new_v4().to_string()[0..8].to_string(); - dbg!(102); cmd = _cmd.clone(); } (None, None, Some(_container_id)) => { - dbg!(211); let container_info = get_container_info(_container_id)?; - dbg!(210); volume_path = extend_image(&container_info.image)?; container_id = _container_id.clone(); cmd = container_info.run; - dbg!(200); args.run = Some(cmd.clone()); args.image = Some(container_info.image); args.log = container_info.log; @@ -642,14 +636,12 @@ fn main() -> Result<()>{ if container_info.env.len() > 0 { args.env = Some(container_info.env); } - dbg!(201); stop_container(&container_id, false)?; } _ => { unreachable!() } } - dbg!(3); match run_container(&container_id, &cmd, &args, &volume_path, false) { Ok(child_pid) => { save_container_info(&args, &container_id, child_pid)?; diff --git a/src/network.rs b/src/network.rs index 144a802..5733179 100644 --- a/src/network.rs +++ b/src/network.rs @@ -52,9 +52,9 @@ fn set_slave_ip(slave_veth_name: &str, addr: &str, pid: &str) -> bool { 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 - 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") .args(args) .output() @@ -386,7 +386,7 @@ pub fn create_network(uuid_name: &str, pid: i32) -> bool { // 设置转发规则 set_iptables_forward() && // 设置snat - set_snat(&network.gateway_addr, &network.bridge_name) { + set_snat(&network.gateway_addr, &network.bridge_name, "-A") { println!("create_network success"); true } else { @@ -397,23 +397,32 @@ pub fn create_network(uuid_name: &str, pid: i32) -> bool { } -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"); - - // +fn remove_network(uuid_name: &str) { let mut all_network = get_all_network(); - // 删除 bridge_name 对应的 NetWork - all_network.retain(|n|n.bridge_name != bridge_name); - // todo 回写到文件中 + let mut network = None; + all_network = all_network.into_iter() + .filter_map(|n| { + if n.bridge_name.contains(uuid_name) { + network = Some(n); + None + } else { + Some(n) + } + }).collect::>(); + + if let Some(network) = network { + + } + // todo 回写到文件中 + // write_network_info(all_network); } fn main(){ 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; let addr = "192.168.124.1";