Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change fifo Io to PIPE in shim , just do like go shim. Resovled the much io case problem. #276

Open
jokemanfire opened this issue May 29, 2024 · 2 comments

Comments

@jokemanfire
Copy link
Contributor

jokemanfire commented May 29, 2024

disscustion in containerd
I have told this question to containerd . But looks like containerd will not change. So I will take a pr to change fifo to pipe.
I have complete this code , after some ci test ,I will submit this pr.

@jokemanfire
Copy link
Contributor Author

I found another two problem, when use fifo directly.

  1. ctr run -d busybox:latest test , it status will be stopping directly , but go shim will not.
  2. when containerd service is stop , all rshim io will broken, but not go shim.

This is a method to get this error.
1、Get a image
Dockerfile like this:

FROM busybox:latest

COPY test.sh /

ENTRYPOINT ["sh","/test.sh"]

test.sh is blow this:

while true; do 
    sleep 3
    echo "hello"
    result=$?
    if [ $result -ne 0 ]; then
        date >> log.txt
        echo "echo faile . Result : $result" >> /log.txt
    fi
done

docker build get this image.
use ctr import this image.
2、run a container
then use rshim to run a container.
3、get this error
stop containerd service . you can see the error message in this container. but go shim will not be influenced.
So I think use a pipe in shim may be completely needed. This pr which I test can resolve this problem #278

friendly ping , @fuweid @mxpv @Burning1020 . Looking forward to your reply.

@jokemanfire
Copy link
Contributor Author

jokemanfire commented Sep 29, 2024

I try to use two method to resolve the pipe io's problem . And in my case ,the io problem have been resolved.Add an io monitor service to check if the inode+dev of io has been changed, use read_buf instead of tokio-copy in spawn_copy, and add timeout and put it in a loop.
My code like this

fn spawn_copy<R, W, F>(
    from: R,
    to: W,
    exit_signal: Arc<ExitSignal>,
    on_close: Option<F>,
    mut r: tokio::sync::mpsc::Receiver<i64>,
) where
    R: AsyncRead + Send + Unpin + 'static,
    W: AsyncWrite + Send + Unpin + 'static,
    F: FnOnce() + Send + 'static,
{
    let mut src = from;
    let mut dst = to;

    tokio::spawn(async move {
        let mut buffer: Vec<u8> = vec![0u8; 1024];
        //Change to loop and use time out, to make sure the read_buf will not hangon forever
        loop {
            let mut if_cn = true;
            let result = tokio::time::timeout(tokio::time::Duration::from_secs(5), async {
                tokio::select! {
                    _ = exit_signal.wait() =>{
                        debug!("container exit");
                        if_cn = false;
                    }
                    r = src.read_buf(&mut buffer) => {
                        match r{
                            //Read n=0 but read_buf not close means pipe close
                            Ok(n) => {
                                if n == 0{
                                    if_cn = false;
                                }else{
                                    //Need sure the dist write complete?
                                    let d_w = dst.write_all(&buffer).await;
                                    if d_w.is_err(){
                                        if_cn = false;
                                    }
                                    buffer.clear();
                                }
                            },
                            Err(_) => {
                                debug!("read exit");
                                if_cn = false;
                            },
                        }
                    }
                    c = r.recv() =>{
                        debug!("fd error io exit!! recv {:?}",c);
                        if_cn = false;
                    }
                }
            });
            //Timeout will continue unitl recv the io close
            let _ = result.await;
            if !if_cn {
                break;
            }
        }
        if let Some(f) = on_close {
            f();
        }
    });
}

I will pull this pr next week.

@jokemanfire jokemanfire changed the title Change fifo Io to PIPE in shim , just do like go shim Change fifo Io to PIPE in shim , just do like go shim. Resovled the much io case problem. Sep 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant