golang:sshfs -o reconnect fails when used inside docker container with “reading directory .: Input/output error”

I am trying to mount a directory located on a host from a docker container using sshfs. The problem I am having is that once the golang app finishes executing the mountpoint disappears whereas it suppose to persist (the same steps performed manually are producing persistent results.

The ssh client code:

  • Cluster takes a few minutes to service requests when node goes down
  • How to add couchdb server into docker creation file
  • The relation between “docker/swarm” and “docker/swarmkit”
  • swift build faild due to “database is locked” in docker contianer?
  • How to change the bash prompt of a spawned child bash? Specifically a docker shell
  • Docker: how to set up file ownership in a data-only container?
  • package main
    
    import (
     //"bytes"
    "code.google.com/p/go.crypto/ssh"
    //"fmt"
    "io"
    "log"
    "os"
    )
    
    var (
    server = "172.17.42.1:49155"
    username = "root"
    password = clientPassword("orobix2013")
    )
    
    type clientPassword string
    
    func (p clientPassword) Password(user string) (string, error) {
    return string(p), nil
    }
    
    type TerminalModes map[uint8]uint32
    
    const (
    VINTR = 1
    VQUIT = 2
    VERASE = 3
    VKILL = 4
    VEOF = 5
    VEOL = 6
    VEOL2 = 7
    VSTART = 8
    VSTOP = 9
    VSUSP = 10
    VDSUSP = 11
    VREPRINT = 12
    VWERASE = 13
    VLNEXT = 14
    VFLUSH = 15
    VSWTCH = 16
    VSTATUS = 17
    VDISCARD = 18
    IGNPAR = 30
    PARMRK = 31
    INPCK = 32
    ISTRIP = 33
    INLCR = 34
    IGNCR = 35
    ICRNL = 36
    IUCLC = 37
    IXON = 38
    IXANY = 39
    IXOFF = 40
    IMAXBEL = 41
    ISIG = 50
    ICANON = 51
    XCASE = 52
    ECHO = 53
    ECHOE = 54
    ECHOK = 55
    ECHONL = 56
    NOFLSH = 57
    TOSTOP = 58
    IEXTEN = 59
    ECHOCTL = 60
    ECHOKE = 61
    PENDIN = 62
    OPOST = 70
    OLCUC = 71
    ONLCR = 72
    OCRNL = 73
    ONOCR = 74
    ONLRET = 75
    CS7 = 90
    CS8 = 91
    PARENB = 92
    PARODD = 93
    TTY_OP_ISPEED = 128
    TTY_OP_OSPEED = 129
    )
    
    func main() {
    // An SSH client is represented with a slete). Currently only
    // the "password" authentication method is supported.
    //
    // To authenticate with the remote server you must pass at least one
    // implementation of ClientAuth via the Auth field in ClientConfig.
    
    config := &ssh.ClientConfig{
    User: username,
    Auth: []ssh.ClientAuth{
    // ClientAuthPassword wraps a ClientPassword implementation
    // in a type that implements ClientAuth.
    ssh.ClientAuthPassword(password),
    },
    }
    client, err := ssh.Dial("tcp", "172.17.42.1:49155", config)
    if err != nil {
    panic("Failed to dial: " + err.Error())
    }
    
    // Each ClientConn can support multiple interactive sessions,
    // represented by a Session.
    defer client.Close()
    // Create a session
    session, err := client.NewSession()
    if err != nil {
    log.Fatalf("unable to create session: %s", err)
    }
    defer session.Close()
    // Set up terminal modes
    modes := ssh.TerminalModes{
    ECHO: 0, // disable echoing
    TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
    TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
    }
    // Request pseudo terminal
    if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
    log.Fatalf("request for pseudo terminal failed: %s", err)
    }
    //var b bytes.Buffer
    //session.Stdout = &bi
    
    stdin, _ := session.StdinPipe()
    
    stdout, _ := session.StdoutPipe()
    
    go io.Copy(os.Stdout, stdout)
    go io.Copy(stdin, os.Stdin)
    //go io.Copy(os.Stderr, stderr)
    if err := session.Run("/bin/bash -c \"sshfs piotr@172.17.42.1:/home/piotr/helloworld/ /mnt -o idmap=user -o reconnect;touch /mnt/ofoo\""); err != nil {
    panic("Failed to run: " + err.Error())
    }
    

    The container is running in the background (-d) and I ssh into it to confrim that the mountpoint(/mnt/) is still there and this is what I am getting:

    root@654b8fa08b9e:~# mount
    none on / type aufs (rw,relatime,si=77b99811b9d139a9)
    /dev/disk/by-uuid/7e1d6bab-b3f2-4ac3-8bff-0779f5bf40f2 on /etc/hostname type ext4 (ro,relatime,errors=remount-ro,data=ordered)
    /dev/disk/by-uuid/7e1d6bab-b3f2-4ac3-8bff-0779f5bf40f2 on /etc/hosts type ext4 (ro,relatime,errors=remount-ro,data=ordered)
    proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
    sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
    shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k)
    /dev/disk/by-uuid/7e1d6bab-b3f2-4ac3-8bff-0779f5bf40f2 on /.dockerinit type ext4 (ro,relatime,errors=remount-ro,data=ordered)
    /dev/disk/by-uuid/7e1d6bab-b3f2-4ac3-8bff-0779f5bf40f2 on /etc/resolv.conf type ext4 (ro,relatime,errors=remount-ro,data=ordered)
    devpts on /dev/tty1 type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
    devpts on /dev/pts type devpts (rw,relatime,mode=600,ptmxmode=666)
    devpts on /dev/ptmx type devpts (rw,relatime,mode=600,ptmxmode=666)
    piotr@172.17.42.1:/home/piotr/helloworld/ on /mnt type fuse.sshfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,max_read=65536)
    root@654b8fa08b9e:~# cd /mnt/
    root@654b8fa08b9e:/mnt# ls
    ls: reading directory .: Input/output error
    root@654b8fa08b9e:/mnt# 
    

    THe “mount” command shows that the mountpoint is there however when I am trying to access it I am getting:
    ls: reading directory .: Input/output error

    Can someone tell me how I can fix that please? I spend quite a lot of time on this without success, any input is very welcome!

    How to test it:

    I uploaded my testing docker container to the public repository so you can run and test it now yourself:

    First you need to start the container in the background with sshd running:

    sudo docker run -i -t -privileged -dns=172.25.0.10 -p 22 -d orobix/sshfs_startup_key2 /bin/bash -c “/usr/sbin/sshd -D”

    privileged is needed for the sshfs fuse system to work, I use dns option to specify my dns server because I am inside a local network(you might not need to)
    The image(orobix/ssfs_startuo_key2) should be pulled automatically from the public repository.

    Once the container is running you should be able to run the go code(of course ip addresses must be changed).

    You can ssh into container manually with e.g.:

    ssh root@172.17.42.1 -p 49153
    

    Again, ip and ports will be different.

  • What is driver name of docker for mac?
  • Docker multiple environments
  • Elasticsearch-Hadoop library cannot connect to to docker container
  • How does Vagrant automatically install Docker on CentOS?
  • How do you add items to .dockerignore?
  • Docker for windows: how to access container from dev machine (by ip/dns name)
  • One Solution collect form web for “golang:sshfs -o reconnect fails when used inside docker container with “reading directory .: Input/output error””

    Have you ever tried docker 0.8.1? It solved tty problem on run ‘tmux’. Maybe it can solve your problem too.

    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.