forked from u-root/u-root
/
mount.go
135 lines (121 loc) · 2.74 KB
/
mount.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright 2012-2017 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Mount a filesystem at the specified path.
//
// Synopsis:
// mount [-r] [-o options] [-t FSTYPE] DEV PATH
//
// Options:
// -r: read only
package main
import (
"flag"
"io/ioutil"
"log"
"os"
"strings"
"github.com/u-root/u-root/pkg/loop"
"github.com/u-root/u-root/pkg/mount"
"golang.org/x/sys/unix"
)
type mountOptions []string
func (o *mountOptions) String() string {
return strings.Join(*o, ",")
}
func (o *mountOptions) Set(value string) error {
for _, option := range strings.Split(value, ",") {
*o = append(*o, option)
}
return nil
}
var (
ro = flag.Bool("r", false, "Read only mount")
fsType = flag.String("t", "", "File system type")
options mountOptions
)
func init() {
flag.Var(&options, "o", "Comma separated list of mount options")
}
func loopSetup(filename string) (loopDevice string, err error) {
loopDevice, err = loop.FindDevice()
if err != nil {
return "", err
}
if err := loop.SetFile(loopDevice, filename); err != nil {
return "", err
}
return loopDevice, nil
}
// extended from boot.go
func getSupportedFilesystem(originFS string) ([]string, bool, error) {
var known bool
var err error
fs, err := ioutil.ReadFile("/proc/filesystems")
if err != nil {
return nil, known, err
}
var returnValue []string
for _, f := range strings.Split(string(fs), "\n") {
n := strings.Fields(f)
last := len(n) - 1
if last < 0 {
continue
}
if n[last] == originFS {
known = true
}
returnValue = append(returnValue, n[last])
}
return returnValue, known, err
}
func informIfUnknownFS(originFS string) {
knownFS, known, err := getSupportedFilesystem(originFS)
if err != nil {
// just don't make things even worse...
return
}
if !known {
log.Printf("Hint: unknown filesystem %s. Known are: %v", originFS, knownFS)
}
}
func main() {
flag.Parse()
a := flag.Args()
if len(a) < 2 {
flag.Usage()
os.Exit(1)
}
dev := a[0]
path := a[1]
var flags uintptr
var data []string
var err error
for _, option := range options {
switch option {
case "loop":
dev, err = loopSetup(dev)
if err != nil {
log.Fatal("Error setting loop device:", err)
}
default:
if f, ok := opts[option]; ok {
flags |= f
} else {
data = append(data, option)
}
}
}
if *ro {
flags |= unix.MS_RDONLY
}
if *fsType == "" {
// mandatory parameter for the moment
log.Fatalf("No file system type provided!\nUsage: mount [-r] [-o mount options] -t fstype dev path")
}
if err := mount.Mount(dev, path, *fsType, strings.Join(data, ","), flags); err != nil {
log.Printf("%v", err)
informIfUnknownFS(*fsType)
os.Exit(1)
}
}