Skip to content

Commit b35c1bd

Browse files
authored
Merge pull request #10 from sarus-suite/efficient-mirror
Mirror mechanism that enables parallelFS of store has been upgraded to avoid copying the squash directory. With this upgrade, only the store metadata used by the containers/storage library are mirrored into local storage, while the squash data is kept in parallelFS with mirror access via symlink. This approach avoids the copy of the squash images, saving local space and large data transfers.
2 parents c024edd + bed5c56 commit b35c1bd

File tree

2 files changed

+39
-8
lines changed

2 files changed

+39
-8
lines changed

cmd/migration.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,6 @@ func createSquashSidecarFromMount(srcDir, link string, cfg common.Config) error
331331

332332
squashPath := filepath.Join(cfg.RoStoragePath, "squash", link+".squash")
333333
if _, err := os.Stat(squashPath); errors.Is(err, os.ErrNotExist) {
334-
if err := os.MkdirAll(filepath.Dir(squashPath), 0o755); err != nil {
335-
return err
336-
}
337334

338335
// Choose default or user provided flags
339336
defaultFlags := []string {

common/rsync-mirror.go

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"os"
66
"os/exec"
77
"path/filepath"
8+
9+
log "github.com/sirupsen/logrus"
810
)
911

1012
// Mirror creates a writable mirror of srcDir in a temp directory.
@@ -13,23 +15,55 @@ import (
1315
//
1416
// Note: this requires the "rsync" binary to be installed and in PATH.
1517
func Mirror(srcDir string) (mirrorDir string, cleanup func() error, err error) {
18+
log.Infof("Mirror: creating temp dir for %q", srcDir)
19+
1620
mp, err := os.MkdirTemp("", "rsync-mirror-")
1721
if err != nil {
18-
return "", nil, fmt.Errorf("failed to create temp dir: %w", err)
22+
return "", nil, fmt.Errorf("Failed to create temp dir: %w", err)
1923
}
2024

21-
// Ensure the srcDir path ends with a trailing slash for rsync behavior
25+
2226
srcPath := filepath.Clean(srcDir) + string(os.PathSeparator)
2327
mirrorPath := filepath.Clean(mp) + string(os.PathSeparator)
28+
log.Infof("Mirror: rsync from %s to %s (no squash/)", srcPath, mirrorPath)
2429

25-
cmd := exec.Command("rsync", "-a", srcPath, mirrorPath)
30+
// Setup mirror but skip squash/ dir
31+
cmd := exec.Command("rsync",
32+
"-a",
33+
"--exclude=squash/",
34+
srcPath, mirrorPath,
35+
)
2636
if out, err2 := cmd.CombinedOutput(); err2 != nil {
2737
os.RemoveAll(mp)
28-
return "", nil, fmt.Errorf("initial rsync failed: %v\n%s", err2, out)
38+
return "", nil, fmt.Errorf("Initial rsync failed: %v\n%s", err2, out)
2939
}
3040

41+
// In case srcDir is not init, we might not have a squash dir, lets create it
42+
realSquash := filepath.Join(srcDir, "squash")
43+
linkName := filepath.Join(mirrorPath, "squash")
44+
log.Infof("Mirror: creating squash symlink %s to %s", linkName, realSquash)
45+
if err := os.MkdirAll(realSquash, 0o755); err != nil {
46+
return "", nil, fmt.Errorf("Failed to create real squash dir %q: %w", realSquash, err)
47+
}
48+
if err2 := os.Symlink(realSquash, linkName); err2 != nil {
49+
os.RemoveAll(mp)
50+
return "", nil, fmt.Errorf("Squash symlink failed: %w", err2)
51+
}
52+
53+
// On cleanup we remove link then rsync back
3154
cleanup = func() error {
32-
cmdBack := exec.Command("rsync", "-a", "--delete", mirrorPath, srcPath)
55+
log.Infof("Mirror-cleanup: remove mirror’s squash symlink")
56+
if err := os.Remove(filepath.Join(mirrorPath, "squash")); err != nil {
57+
return fmt.Errorf("Failed to remove squash symlink: %w", err)
58+
}
59+
60+
log.Infof("Mirror-cleanup: rsync back from %s to %s (excluding squash/)", mirrorPath, srcPath)
61+
cmdBack := exec.Command("rsync",
62+
"-a",
63+
"--exclude=squash/",
64+
"--delete",
65+
mirrorPath, srcPath,
66+
)
3367
if out, err2 := cmdBack.CombinedOutput(); err2 != nil {
3468
return fmt.Errorf("rsync back failed: %v\n%s", err2, out)
3569
}

0 commit comments

Comments
 (0)