Skip to content

Commit 7e70004

Browse files
cdalarclaude
andcommitted
fix(fc): reflink-copy base rootfs image instead of full byte copy
DebugfsRootfsPreparer.Prepare did a plain io.Copy of the entire base rootfs image on every Deploy, dominating `onctl up` time for the fc provider (multi-second sys time copying a large image). The cache disk preparer already avoided this cost via a CoW reflink; the rootfs path now does the same, falling back to a full copy on filesystems without reflink support. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PVpF4aLeq6xpokgHiBCy4v
1 parent a94b281 commit 7e70004

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

‎internal/providerfc/common.go‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ func (DebugfsRootfsPreparer) Prepare(baseImage, destPath, sshPublicKey, username
464464
if baseImage == "" {
465465
return errors.New("fc.rootfsImage is not configured")
466466
}
467-
if err := copyFile(baseImage, destPath); err != nil {
467+
if err := copyRootfs(baseImage, destPath); err != nil {
468468
return fmt.Errorf("failed to copy base rootfs %q: %w", baseImage, err)
469469
}
470470
if sshPublicKey == "" {
@@ -595,6 +595,20 @@ func reflinkCopy(src, dst string) error {
595595
return nil
596596
}
597597

598+
// copyRootfs creates dst as a copy of src, preferring a copy-on-write
599+
// reflink (near-instant and disk-space-free regardless of image size) and
600+
// falling back to a full byte-for-byte copy when the host filesystem
601+
// doesn't support reflinks (e.g. plain ext4, or non-Linux). Every Deploy
602+
// calls this once per microVM, so on a CoW filesystem (btrfs, or XFS with
603+
// reflink=1) it turns what was previously a multi-second copy of the whole
604+
// base rootfs image into a near-zero-cost metadata operation.
605+
func copyRootfs(src, dst string) error {
606+
if err := reflinkCopy(src, dst); err == nil {
607+
return nil
608+
}
609+
return copyFile(src, dst)
610+
}
611+
598612
func copyFile(src, dst string) error {
599613
in, err := os.Open(src)
600614
if err != nil {

0 commit comments

Comments
 (0)
⌂ 换网址