| package mount |
| |
| // On Solaris we can't invoke the mount system call directly. First, |
| // the mount system call takes more than 6 arguments, and go doesn't |
| // support invoking system calls that take more than 6 arguments. Past |
| // that, the mount system call is a private interfaces. For example, |
| // the arguments and data structures passed to the kernel to create an |
| // nfs mount are private and can change at any time. The only public |
| // and stable interface for creating mounts on Solaris is the mount.8 |
| // command, so we'll invoke that here. |
| |
| import ( |
| "bytes" |
| "errors" |
| "fmt" |
| "os/exec" |
| "strings" |
| |
| "golang.org/x/sys/unix" |
| ) |
| |
| const ( |
| mountCmd = "/usr/sbin/mount" |
| ) |
| |
| func doMount(arg ...string) error { |
| cmd := exec.Command(mountCmd, arg...) |
| |
| /* Setup Stdin, Stdout, and Stderr */ |
| stderr := new(bytes.Buffer) |
| cmd.Stdin = nil |
| cmd.Stdout = nil |
| cmd.Stderr = stderr |
| |
| /* |
| * Run the command. If the command fails create a new error |
| * object to return that includes stderr output. |
| */ |
| err := cmd.Start() |
| if err != nil { |
| return err |
| } |
| err = cmd.Wait() |
| if err != nil { |
| return errors.New(fmt.Sprintf("%v: %s", err, stderr.String())) |
| } |
| return nil |
| } |
| |
| func (m *Mount) Mount(target string) error { |
| var err error |
| |
| if len(m.Options) == 0 { |
| err = doMount("-F", m.Type, m.Source, target) |
| } else { |
| err = doMount("-F", m.Type, "-o", strings.Join(m.Options, ","), |
| m.Source, target) |
| } |
| return err |
| } |
| |
| func Unmount(mount string, flags int) error { |
| return unix.Unmount(mount, flags) |
| } |
| |
| // UnmountAll repeatedly unmounts the given mount point until there |
| // are no mounts remaining (EINVAL is returned by mount), which is |
| // useful for undoing a stack of mounts on the same mount point. |
| func UnmountAll(mount string, flags int) error { |
| for { |
| if err := Unmount(mount, flags); err != nil { |
| // EINVAL is returned if the target is not a |
| // mount point, indicating that we are |
| // done. It can also indicate a few other |
| // things (such as invalid flags) which we |
| // unfortunately end up squelching here too. |
| if err == unix.EINVAL { |
| return nil |
| } |
| return err |
| } |
| } |
| } |