mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-19 01:06:27 +00:00
102 lines
2.4 KiB
Go
102 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"syscall"
|
|
)
|
|
|
|
var (
|
|
dir string
|
|
mount string
|
|
)
|
|
|
|
func init() {
|
|
flag.StringVar(&dir, "dir", "/etc/binfmt.d", "directory with config files")
|
|
flag.StringVar(&mount, "mount", "/proc/sys/fs/binfmt_misc", "binfmt_misc mount point")
|
|
}
|
|
|
|
func binfmt(line []byte) error {
|
|
register := filepath.Join(mount, "register")
|
|
file, err := os.OpenFile(register, os.O_WRONLY, 0)
|
|
if err != nil {
|
|
e, ok := err.(*os.PathError)
|
|
if ok && e.Err == syscall.ENOENT {
|
|
return fmt.Errorf("ENOENT opening %s is it mounted?", register)
|
|
}
|
|
if ok && e.Err == syscall.EPERM {
|
|
return fmt.Errorf("EPERM opening %s check permissions?", register)
|
|
}
|
|
return fmt.Errorf("Cannot open %s: %s", register, err)
|
|
}
|
|
defer file.Close()
|
|
// short writes should not occur on sysfs, cannot usefully recover
|
|
_, err = file.Write(line)
|
|
if err != nil {
|
|
e, ok := err.(*os.PathError)
|
|
if ok && e.Err == syscall.EEXIST {
|
|
// clear existing entry
|
|
split := bytes.SplitN(line[1:], []byte(":"), 2)
|
|
if len(split) == 0 {
|
|
return fmt.Errorf("Cannot determine arch from: %s", line)
|
|
}
|
|
arch := filepath.Join(mount, string(split[0]))
|
|
clear, err := os.OpenFile(arch, os.O_WRONLY, 0)
|
|
if err != nil {
|
|
return fmt.Errorf("Cannot open %s: %s", arch, err)
|
|
}
|
|
defer clear.Close()
|
|
_, err = clear.Write([]byte("-1"))
|
|
if err != nil {
|
|
return fmt.Errorf("Cannot write to %s: %s", arch, err)
|
|
}
|
|
_, err = file.Write(line)
|
|
if err != nil {
|
|
return fmt.Errorf("Cannot write to %s: %s", register, err)
|
|
}
|
|
return nil
|
|
}
|
|
return fmt.Errorf("Cannot write to %s: %s", register, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
if err := syscall.Mount("binfmt_misc", mount, "binfmt_misc", 0, ""); err != nil {
|
|
log.Fatalf("Cannot mount binfmt_misc filesystem at %s: %v", mount, err)
|
|
}
|
|
defer syscall.Unmount(mount, 0)
|
|
|
|
files, err := os.ReadDir(dir)
|
|
if err != nil {
|
|
log.Fatalf("Cannot read directory %s: %s", dir, err)
|
|
}
|
|
|
|
for _, file := range files {
|
|
contents, err := os.ReadFile(filepath.Join(dir, file.Name()))
|
|
if err != nil {
|
|
log.Fatalf("Cannot read file %s: %s", file.Name(), err)
|
|
}
|
|
lines := bytes.Split(contents, []byte("\n"))
|
|
for _, line := range lines {
|
|
if len(line) == 0 {
|
|
continue
|
|
}
|
|
// ignore comments
|
|
if line[0] == '#' {
|
|
continue
|
|
}
|
|
err = binfmt(line)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
}
|