github.com/hugelgupf/u-root@v0.0.0-20191023214958-4807c632154c/pkg/storage/filesystem.go (about) 1 // Copyright 2017-2019 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package storage 6 7 import ( 8 "fmt" 9 "io/ioutil" 10 "log" 11 "os" 12 "strings" 13 "syscall" 14 ) 15 16 // Mountpoint holds mount point information for a given device 17 type Mountpoint struct { 18 DeviceName string 19 Path string 20 FsType string 21 } 22 23 // GetSupportedFilesystems returns the supported file systems for block devices 24 func GetSupportedFilesystems() (fstypes []string, err error) { 25 return internalGetFilesystems("/proc/filesystems") 26 } 27 28 func internalGetFilesystems(file string) (fstypes []string, err error) { 29 var bytes []byte 30 if bytes, err = ioutil.ReadFile(file); err != nil { 31 return nil, fmt.Errorf("failed to read %s: %v", file, err) 32 } 33 for _, line := range strings.Split(string(bytes), "\n") { 34 //len(fields)==1, 2 possibilites for fs: "nodev" fs and 35 // fs's. "nodev" fs cannot be mounted through devices. 36 // len(fields)==1 prevents this from occurring. 37 if fields := strings.Fields(line); len(fields) == 1 { 38 fstypes = append(fstypes, fields[0]) 39 } 40 } 41 return fstypes, nil 42 } 43 44 // Mount tries to mount a block device on the given mountpoint, trying in order 45 // the provided file system types. It returns a Mountpoint structure, or an error 46 // if the device could not be mounted. If the mount point does not exist, it will 47 // be created. 48 func Mount(devname, mountpath string, filesystems []string) (*Mountpoint, error) { 49 if err := os.MkdirAll(mountpath, 0744); err != nil { 50 return nil, err 51 } 52 for _, fstype := range filesystems { 53 log.Printf(" * trying %s on %s", fstype, devname) 54 // MS_RDONLY should be enough. See mount(2) 55 flags := uintptr(syscall.MS_RDONLY) 56 // no options 57 data := "" 58 if err := syscall.Mount(devname, mountpath, fstype, flags, data); err != nil { 59 log.Printf(" failed with %v", err) 60 continue 61 } 62 log.Printf(" * mounted %s on %s with filesystem type %s", devname, mountpath, fstype) 63 return &Mountpoint{DeviceName: devname, Path: mountpath, FsType: fstype}, nil 64 } 65 return nil, fmt.Errorf("no suitable filesystem type found to mount %s", devname) 66 }