Skip to content

Instantly share code, notes, and snippets.

@saljam
Last active January 22, 2017 20:36
Show Gist options
  • Select an option

  • Save saljam/7022788 to your computer and use it in GitHub Desktop.

Select an option

Save saljam/7022788 to your computer and use it in GitHub Desktop.

Revisions

  1. saljam renamed this gist Oct 17, 2013. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. saljam renamed this gist Oct 17, 2013. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  3. saljam created this gist Oct 17, 2013.
    102 changes: 102 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,102 @@
    // +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)
    }