sorcery-go/pkg/tomb/reanimate.go

93 lines
2.9 KiB
Go
Executable File

// Reanimation: binding an Essence from the Tomb into a Sanctum.
//
// In the Coven mythos, Reanimation is the act of bringing a sealed binary
// back to life inside a Sanctum. A Sanctum can be an LXC container, Podman
// container, Firecracker microVM, or bare-metal chroot.
//
// Technically this means creating reflinks (preferred — zero-copy on
// btrfs/xfs) or hardlinks from the Tomb's blob store into the Sanctum's
// rootfs. If neither is possible (cross-filesystem), we fall back to a
// plain copy.
package tomb
import (
"fmt"
"io"
"os"
"path/filepath"
"syscall"
)
// Reanimate links every file of `essenceID` into `sanctumRoot` so the
// Sanctum can execute them. The caller MUST have already called
// VerifyRoot() (or VerifyBlobs()) on the essence — Reanimate does not
// re-check integrity for performance reasons.
func (t *Tomb) Reanimate(essenceID, sanctumRoot string) error {
s, err := t.GetSarcophagus(essenceID)
if err != nil {
return err
}
for path, hash := range s.Files {
src := t.blobPath(hash)
dst := filepath.Join(sanctumRoot, path)
if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
return fmt.Errorf("reanimate: mkdir %s: %w", filepath.Dir(dst), err)
}
if err := linkOrCopy(src, dst); err != nil {
return fmt.Errorf("reanimate: link %s: %w", dst, err)
}
}
return nil
}
// linkOrCopy tries reflink (btrfs/xfs FICLONE), then hardlink (same
// filesystem), then plain copy (cross-filesystem).
func linkOrCopy(src, dst string) error {
// 1. Reflink (zero-copy on btrfs/xfs).
if err := reflinkFile(src, dst); err == nil {
return nil
}
// 2. Hardlink (fast, same-filesystem only).
if err := os.Link(src, dst); err == nil {
return nil
}
// 3. Plain copy.
return copyFile(src, dst)
}
// reflinkFile wraps the FICLONE ioctl. Returns nil on success.
func reflinkFile(src, dst string) error {
srcF, err := os.Open(src)
if err != nil {
return err
}
defer srcF.Close()
dstF, err := os.Create(dst)
if err != nil {
return err
}
defer dstF.Close()
const FICLONE = 0x40049409
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
dstF.Fd(), uintptr(FICLONE), srcF.Fd())
if errno != 0 {
return fmt.Errorf("FICLONE: %w", errno)
}
return nil
}
func copyFile(src, dst string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, in)
return err
}