Add code for partition mounting

This commit is contained in:
lordwelch 2020-12-09 13:25:44 -08:00
parent 3483a665c4
commit 4c1e7a4310

166
main.go
View File

@ -1,57 +1,137 @@
package main
import (
"encoding/binary"
"errors"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"syscall"
)
var (
perm = flag.String("perm", "/perm", "new val for perm")
perm = flag.String("perm", "/perm", "new val for perm")
gloaderHome = "/perm/gloader"
)
func main() {
os.MkdirAll("/home/timmy/dltest", 0777)
flag.Parse()
gloaderHome = filepath.Join(*perm, "gloader")
os.MkdirAll(gloaderHome, 0777)
err := mount()
if err != nil {
log.Println(err)
os.Exit(1)
}
d := newDownloader()
d.DataDir = "/home/timmy/dltest"
d.Start("tcp", ":8080")
d.DataDir = filepath.Join(gloaderHome, "data")
d.Start("tcp", ":8844")
}
// func mount() error {
// var (
// partUUID string
// partUUIDb []byte
// err error
// dataStat os.FileInfo
// dataDir = filepath.Join(*perm, "downloader/data")
// )
// partUUIDb, err = ioutil.ReadFile(filepath.Join(*perm, "downloader/partition"))
// if err != nil || string(partUUIDb) == "" {
// return nil
// }
// partUUID = string(partUUIDb)
// dataStat, err = os.Stat(dataDir)
// if err != nil {
// if errors.Is(err, os.ErrNotExist) {
// err = os.MkdirAll(dataDir, 0o755)
// if err != nil {
// return fmt.Errorf("error creating datadir: %w", err)
// }
// } else {
// return fmt.Errorf("error mounting datadir: %w", err)
// }
// }
// if dataStat.IsDir() {
// var folder *os.File
// folder, err = os.Open(dataDir)
// if err != nil {
// return fmt.Errorf("error mounting datadir: %w", err)
// }
// _, err = folder.Readdir(1)
// if errors.Is(err, io.EOF) {
// fmt.Printf("mount %s %s", partUUID, dataDir)
// return nil
// }
// return fmt.Errorf("error mounting datadir: %w", err)
// }
// return fmt.Errorf("error mounting datadir: data dir %s is not a directory", dataDir)
// }
func mount() error {
var (
partUUIDb []byte
partUUID string
dev string
err error
dataStat os.FileInfo
dataDir = filepath.Join(gloaderHome, "data")
)
partUUIDb, err = ioutil.ReadFile(filepath.Join(gloaderHome, "partition"))
partUUID = strings.TrimSpace(string(partUUIDb))
if err != nil || partUUID == "" {
return nil
}
dataStat, err = os.Stat(dataDir)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
err = os.MkdirAll(dataDir, 0o755)
if err != nil {
return fmt.Errorf("error creating datadir: %w", err)
}
dataStat, err = os.Stat(dataDir)
if err != nil {
return fmt.Errorf("error mounting datadir: %w", err)
}
} else {
return fmt.Errorf("error mounting datadir: %w", err)
}
}
if dataStat.IsDir() {
var folder *os.File
folder, err = os.Open(dataDir)
if err != nil {
return fmt.Errorf("error mounting datadir: %w", err)
}
_, err = folder.Readdir(1)
if errors.Is(err, io.EOF) {
fmt.Printf("mount %s %s", partUUID, dataDir)
dev, err = findPartUUID(partUUID)
if err != nil {
return fmt.Errorf("error mounting datadir: %w", err)
}
err = syscall.Mount(dev, dataDir, "ext4", 0, "")
if err != nil {
return fmt.Errorf("error mounting datadir: %w", err)
}
return nil
}
return fmt.Errorf("error mounting datadir: %w", err)
}
return fmt.Errorf("error mounting datadir: data dir %s is not a directory", dataDir)
}
func findPartUUID(uuid string) (string, error) {
var dev string
err := filepath.Walk("/sys/block", func(path string, info os.FileInfo, err error) error {
if err != nil {
log.Printf("findPartUUID: %v", err)
return nil
}
if info.Mode()&os.ModeSymlink == 0 {
return nil
}
devname := "/dev/" + filepath.Base(path)
f, err := os.Open(devname)
if err != nil {
log.Printf("findPartUUID: %v", err)
return nil
}
defer f.Close()
if _, err := f.Seek(440, io.SeekStart); err != nil {
var se syscall.Errno
if errors.As(err, &se) && se == syscall.EINVAL {
// Seek()ing empty loop devices results in EINVAL.
return nil
}
log.Printf("findPartUUID: %v(%T)", err, err.(*os.PathError).Err)
return nil
}
var diskSig struct {
ID uint32
Trailer uint16
}
if err := binary.Read(f, binary.LittleEndian, &diskSig); err != nil {
log.Printf("findPartUUID: %v", err)
return nil
}
if fmt.Sprintf("%08x", diskSig.ID) == uuid && diskSig.Trailer == 0 {
dev = devname
// TODO: abort early with sentinel error code
return nil
}
return nil
})
if err != nil {
return "", err
}
if dev == "" {
return "", fmt.Errorf("PARTUUID=%s not found", uuid)
}
return dev, nil
}