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;
}
