Skip to content

Instantly share code, notes, and snippets.

@saljam
Last active January 22, 2017 20:36
Show Gist options
  • Save saljam/7022788 to your computer and use it in GitHub Desktop.
Save saljam/7022788 to your computer and use it in GitHub Desktop.
Camlistore-booting Init in Go.
// +build linux
package main
import (
"log"
"time"
"syscall"
"errors"
"os"
"os/exec"
)
func nuke(path string) error {
f, err := os.Open(path)
defer f.Close()
if err != nil {
return err
}
fi, err := f.Stat()
if err != nil {
return err
}
dev := fi.Sys().(*syscall.Stat_t).Dev
if fi.IsDir() == false {
return errors.New("not a diectory")
}
ents, err := f.Readdir(0)
if err != nil {
return err
}
for _, e := range ents {
st := e.Sys().(*syscall.Stat_t)
// skip mount points
if st.Dev != dev {
continue
}
if e.IsDir() {
err = nuke(path + string(os.PathSeparator) + e.Name())
if err != nil {
return err
}
}
os.Remove(path + string(os.PathSeparator) + e.Name())
}
return nil
}
var shareUrl = os.Getenv("camliroot")
var mountPoint = "/root"
func must(err error) {
if err != nil {
log.Fatal(err)
}
}
func main() {
log.Println("init starting")
must(syscall.Mount("devtmpfs", "/dev", "devtmpfs", 0, ""))
must(syscall.Mount("procfs", "/proc", "proc", 0, ""))
must(syscall.Mount("tmpfs", "/tmp", "tmpfs", 0, ""))
log.Println("mounting camlifs")
c := exec.Cmd{
Path: "/bin/cammount",
Args: []string{"cammount", mountPoint, shareUrl},
Env: []string{"PATH=/bin"},
}
must(c.Start())
time.Sleep(time.Second * 5)
must(syscall.Mount("devtmpfs", "/root/dev", "devtmpfs", 0, ""))
must(syscall.Mount("procfs", "/root/proc", "proc", 0, ""))
must(syscall.Mount("sysfs", "/root/sys", "sysfs", 0, ""))
must(syscall.Mount("tmpfs", "/root/run", "tmpfs", 0, ""))
log.Println("switching root")
// From here more or less the same idea as run-init.c
must(os.Chdir("/root"))
must(syscall.Mount(".", "/", "", syscall.MS_MOVE, ""))
must(syscall.Chroot("."))
must(os.Chdir("/"))
console, err := syscall.Open("/dev/console", syscall.O_RDWR, 0777)
if err != nil {
log.Println(err)
}
syscall.Dup2(console, 0)
syscall.Dup2(console, 1)
syscall.Dup2(console, 2)
syscall.Close(console)
err = syscall.Exec("/sbin/init", []string{"/sbin/init"}, []string{})
log.Println("failed to run init:", err)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment