seqdiag { // seqdiag -T svg -o doc/mount-osx.svg doc/mount-osx.seq app; fuse [label="bazil.org/fuse"]; fusermount; kernel; mounts; app -> fuse [label="Mount"]; fuse -> fusermount [label="spawn, pass socketpair fd"]; fusermount -> kernel [label="open /dev/fuse"]; fusermount -> kernel [label="mount(2)"]; kernel ->> mounts [label="mount is visible"]; fusermount <-- kernel [label="mount(2) returns"]; fuse <<-- fusermount [diagonal, label="exit, receive /dev/fuse fd", leftnote="on Linux, successful exit here\nmeans the mount has happened,\nthough InitRequest might not have yet"]; app <-- fuse [label="Mount returns\nConn.Ready is already closed", rightnote="InitRequest and StatfsRequest\nmay or may not be seen\nbefore Conn.Ready,\ndepending on platform"]; app -> fuse [label="fs.Serve"]; fuse => kernel [label="read /dev/fuse fd", note="starts with InitRequest"]; fuse => app [label="FS/Node/Handle methods"]; fuse => kernel [label="write /dev/fuse fd"]; ... repeat ... ... shutting down ... app -> fuse [label="Unmount"]; fuse -> fusermount [label="fusermount -u"]; fusermount -> kernel; kernel <<-- mounts; fusermount <-- kernel; fuse <<-- fusermount [diagonal]; app <-- fuse [label="Unmount returns"]; // actually triggers before above fuse <<-- kernel [diagonal, label="/dev/fuse EOF"]; app <-- fuse [label="fs.Serve returns"]; app -> fuse [label="conn.Close"]; fuse -> kernel [label="close /dev/fuse fd"]; fuse <-- kernel; app <-- fuse; }