93 lines
2.9 KiB
Go
Executable File
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
|
|
}
|