Initial commit
This commit is contained in:
157
cmd/dkl-system-init/lvm.go
Normal file
157
cmd/dkl-system-init/lvm.go
Normal file
@ -0,0 +1,157 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"novit.nc/direktil/pkg/config"
|
||||
"novit.nc/direktil/pkg/log"
|
||||
)
|
||||
|
||||
const (
|
||||
pDevName = "DEVNAME="
|
||||
)
|
||||
|
||||
func init() {
|
||||
go services.WaitPath("/run/lvm/lvmetad.socket")
|
||||
|
||||
services.Register(
|
||||
&CommandService{
|
||||
Name: "lvmetad",
|
||||
Restart: StdRestart,
|
||||
Needs: []string{"service:devfs"},
|
||||
Command: []string{"lvmetad", "-f"},
|
||||
PreExec: func() error {
|
||||
mkdir("/run/lvm", 0700)
|
||||
mkdir("/run/lock/lvm", 0700)
|
||||
|
||||
if !dmInProc() {
|
||||
run("modprobe", "dm-mod")
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
},
|
||||
&CommandService{
|
||||
Name: "lvm",
|
||||
Needs: []string{"file:/run/lvm/lvmetad.socket"},
|
||||
Command: []string{"/bin/sh", "-c", `set -ex
|
||||
/sbin/lvm pvscan
|
||||
/sbin/lvm vgscan --mknodes
|
||||
/sbin/lvm vgchange --sysinit -a ly
|
||||
`},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func isDir(path string) bool {
|
||||
s, err := os.Stat(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
fatal("failed to query ", path, ": ", err)
|
||||
}
|
||||
|
||||
return s.IsDir()
|
||||
}
|
||||
|
||||
func dmInProc() bool {
|
||||
for _, f := range []string{"devices", "misc"} {
|
||||
c, err := ioutil.ReadFile("/proc/" + f)
|
||||
if err != nil {
|
||||
fatalf("failed to read %s: %v", f, err)
|
||||
}
|
||||
if !bytes.Contains(c, []byte("device-mapper")) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func setupVG(udevMatch string) {
|
||||
dev := ""
|
||||
try := 0
|
||||
|
||||
retry:
|
||||
paths, err := filepath.Glob("/sys/class/block/*")
|
||||
if err != nil {
|
||||
fatal("failed to list block devices: ", err)
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
// ignore loop devices
|
||||
if strings.HasPrefix("loop", filepath.Base(path)) {
|
||||
continue
|
||||
}
|
||||
|
||||
// fetch udev informations
|
||||
out, err := exec.Command("udevadm", "info", "-q", "property", path).CombinedOutput()
|
||||
if err != nil {
|
||||
initLog.Taintf(log.Warning, "udev query of %q failed: %v\n%s", path, err, string(out))
|
||||
continue
|
||||
}
|
||||
|
||||
propertyLines := strings.Split(strings.TrimSpace(string(out)), "\n")
|
||||
|
||||
devPath := ""
|
||||
matches := false
|
||||
|
||||
for _, line := range propertyLines {
|
||||
if strings.HasPrefix(line, pDevName) {
|
||||
devPath = line[len(pDevName):]
|
||||
}
|
||||
|
||||
if line == udevMatch {
|
||||
matches = true
|
||||
}
|
||||
|
||||
if devPath != "" && matches {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if devPath != "" && matches {
|
||||
dev = devPath
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if dev == "" {
|
||||
time.Sleep(1 * time.Second)
|
||||
try++
|
||||
if try > 30 {
|
||||
fatal("storage device not found after 30s, failing.")
|
||||
}
|
||||
goto retry
|
||||
}
|
||||
|
||||
initLog.Taint(log.Info, "found storage device at ", dev)
|
||||
|
||||
run("pvcreate", dev)
|
||||
run("vgcreate", "storage", dev)
|
||||
}
|
||||
|
||||
func setupLV(volume config.VolumeDef) {
|
||||
if volume.Extents != "" {
|
||||
run("lvcreate", "-l", volume.Extents, "-n", volume.Name, "storage")
|
||||
} else {
|
||||
run("lvcreate", "-L", volume.Size, "-n", volume.Name, "storage")
|
||||
}
|
||||
|
||||
args := make([]string, 0)
|
||||
|
||||
switch volume.FS {
|
||||
case "btrfs":
|
||||
args = append(args, "-f")
|
||||
case "ext4":
|
||||
args = append(args, "-F")
|
||||
}
|
||||
|
||||
run("mkfs."+volume.FS, append(args, "/dev/storage/"+volume.Name)...)
|
||||
}
|
||||
Reference in New Issue
Block a user