Improve filesystem mounting
This commit is contained in:
parent
3cc35fa7ff
commit
ce34b7b21a
@ -1,3 +1,5 @@
|
||||
module enit
|
||||
|
||||
go 1.23.4
|
||||
|
||||
require golang.org/x/sys v0.31.0
|
||||
|
@ -1,4 +1,2 @@
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
|
@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
@ -75,43 +74,45 @@ func setProcessName() error {
|
||||
func mountVirtualFilesystems() {
|
||||
fmt.Print("Mounting virtual filesystems... ")
|
||||
|
||||
commonFlags := uintptr(0 | syscall.MS_NOSUID | syscall.MS_RELATIME)
|
||||
commonOptions := "rw,nosuid,relatime"
|
||||
|
||||
// Mount /proc
|
||||
if err := syscall.Mount("proc", "/proc", "proc", commonFlags|syscall.MS_NODEV|syscall.MS_NOEXEC|syscall.MS_REMOUNT, ""); err != nil {
|
||||
if err := mount("proc", "/proc", "proc", commonOptions+",nodev,noexec", false); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Mount /sys
|
||||
if err := syscall.Mount("sys", "/sys", "sysfs", commonFlags|syscall.MS_NODEV|syscall.MS_NOEXEC|syscall.MS_REMOUNT, ""); err != nil {
|
||||
if err := mount("sys", "/sys", "sysfs", commonOptions+",nodev,noexec", false); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Mount /dev
|
||||
if err := syscall.Mount("dev", "/dev", "devtmpfs", commonFlags|syscall.MS_REMOUNT, "mode=755,inode64"); err != nil {
|
||||
if err := mount("dev", "/dev", "devtmpfs", commonOptions+",mode=755,inode64", false); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Mount /run
|
||||
if err := syscall.Mount("run", "/run", "tmpfs", commonFlags|syscall.MS_NODEV|syscall.MS_REMOUNT, "mode=755,inode64"); err != nil {
|
||||
if err := mount("run", "/run", "tmpfs", commonOptions+",nodev,mode=755,inode64", false); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Mount /dev/pts
|
||||
if err := os.Mkdir("/dev/pts", 0755); err != nil && !errors.Is(err, os.ErrExist) {
|
||||
panic(err)
|
||||
}
|
||||
if err := syscall.Mount("devpts", "/dev/pts", "devpts", commonFlags, "gid=5,mode=620,ptmxmode=000"); err != nil {
|
||||
if err := mount("devpts", "/dev/pts", "devpts", commonOptions+",gid=5,mode=620,ptmxmode=000", true); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Mount /dev/shm
|
||||
if err := os.Mkdir("/dev/shm", 0755); err != nil && !errors.Is(err, os.ErrExist) {
|
||||
panic(err)
|
||||
}
|
||||
if err := syscall.Mount("shm", "/dev/shm", "tmpfs", commonFlags|syscall.MS_NODEV, "inode64"); err != nil {
|
||||
if err := mount("shm", "/dev/shm", "tmpfs", commonOptions+",nodev,inode64", true); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Mount securityfs
|
||||
if err := syscall.Mount("securityfs", "/sys/kernel/security", "securityfs", commonFlags, ""); err != nil {
|
||||
if err := mount("securityfs", "/sys/kernel/security", "securityfs", commonOptions, false); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Mount cgroups v2
|
||||
if err := syscall.Mount("cgroup2", "/sys/fs/cgroup", "cgroup2", commonFlags|syscall.MS_NOEXEC, ""); err != nil {
|
||||
if err := mount("cgroup2", "/sys/fs/cgroup", "cgroup2", commonOptions+",noexec,nsdelegate,memory_recursiveprot", false); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -119,12 +120,9 @@ func mountVirtualFilesystems() {
|
||||
}
|
||||
|
||||
func mountFilesystems() {
|
||||
fmt.Print("Mounting filesystems... ")
|
||||
fmt.Print("Mounting fstab entries... ")
|
||||
|
||||
cmd := exec.Command("/bin/mount", "-a")
|
||||
err := cmd.Run()
|
||||
|
||||
if err != nil {
|
||||
if err := mountFstabEntries(); err != nil {
|
||||
log.Println("Could not mount fstab entries!")
|
||||
panic(err)
|
||||
}
|
||||
|
141
cmd/enit/mount.go
Normal file
141
cmd/enit/mount.go
Normal file
@ -0,0 +1,141 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
"os"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var flagsEquivalence = map[string]uintptr{
|
||||
"dirsync": unix.MS_DIRSYNC,
|
||||
"lazytime": unix.MS_LAZYTIME,
|
||||
"noatime": unix.MS_NOATIME,
|
||||
"nodev": unix.MS_NODEV,
|
||||
"nodiratime": unix.MS_NODIRATIME,
|
||||
"noexec": unix.MS_NOEXEC,
|
||||
"nosuid": unix.MS_NOSUID,
|
||||
"ro": unix.MS_RDONLY,
|
||||
"rw": 0,
|
||||
"relatime": unix.MS_RELATIME,
|
||||
"silent": unix.MS_SILENT,
|
||||
"strictatime": unix.MS_STRICTATIME,
|
||||
"sync": unix.MS_SYNCHRONOUS,
|
||||
"defaults": 0,
|
||||
}
|
||||
|
||||
// Split string flags to mount flags and mount data
|
||||
func convertMountOptions(options string) (flags []uintptr, data string) {
|
||||
for _, flag := range strings.Split(options, ",") {
|
||||
if unixFlag, ok := flagsEquivalence[flag]; ok {
|
||||
flags = append(flags, unixFlag)
|
||||
} else {
|
||||
if data == "" {
|
||||
data = flag
|
||||
} else {
|
||||
data += "," + flag
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return flags, data
|
||||
}
|
||||
|
||||
// Combine a unix flag slice or array into a single uintptr
|
||||
func combineUnixFlags(flagsSlice []uintptr) (flags uintptr) {
|
||||
flags = 0
|
||||
for _, flag := range flagsSlice {
|
||||
flags |= flag
|
||||
}
|
||||
|
||||
return flags
|
||||
}
|
||||
|
||||
// Check whether a certain path is a mountpoint
|
||||
func isMountpoint(mountpoint string) bool {
|
||||
if mountpoint != "/" {
|
||||
mountpoint = strings.TrimRight(mountpoint, "/")
|
||||
}
|
||||
|
||||
if _, err := os.Stat("/proc/mounts"); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
bytes, err := os.ReadFile("/proc/mounts")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, line := range strings.Split(string(bytes), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.Split(line, " ")[1] == mountpoint {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func mount(source, target, fstype string, options string, mkdir bool) error {
|
||||
flags, data := convertMountOptions(options)
|
||||
|
||||
if isMountpoint(target) && !slices.Contains(flags, unix.MS_REMOUNT) {
|
||||
flags = append(flags, unix.MS_REMOUNT)
|
||||
}
|
||||
|
||||
if mkdir {
|
||||
err := os.MkdirAll(target, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := unix.Mount(source, target, fstype, combineUnixFlags(flags), data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func mountFstabEntries() error {
|
||||
if _, err := os.Stat("/etc/fstab"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bytes, err := os.ReadFile("/etc/fstab")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, line := range strings.Split(string(bytes), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if strings.HasPrefix(line, "#") || line == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
source := strings.Split(line, " ")[0]
|
||||
target := strings.Split(line, " ")[1]
|
||||
fstype := strings.Split(line, " ")[2]
|
||||
options := strings.Split(line, " ")[3]
|
||||
|
||||
flags, data := convertMountOptions(options)
|
||||
|
||||
if slices.Contains(strings.Split(data, ","), "noauto") {
|
||||
continue
|
||||
}
|
||||
|
||||
if isMountpoint(target) && !slices.Contains(flags, unix.MS_REMOUNT) {
|
||||
flags = append(flags, unix.MS_REMOUNT)
|
||||
}
|
||||
|
||||
if err := unix.Mount(source, target, fstype, combineUnixFlags(flags), data); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user