From 39ff0ed013102542292f3270ed99babe3964c2a8 Mon Sep 17 00:00:00 2001
From: yangjiaqi <yangjiaqi16@huawei.com>
Date: Fri, 11 Aug 2023 14:47:05 +0800
Subject: [PATCH] use file locks to avoid remounting the sharepath/master dir

Signed-off-by: yangjiaqi <yangjiaqi16@huawei.com>
---
 utils/transfer.go | 40 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/utils/transfer.go b/utils/transfer.go
index 9c6d527..789cb99 100644
--- a/utils/transfer.go
+++ b/utils/transfer.go
@@ -20,17 +20,20 @@ import (
 	"path/filepath"
 	"syscall"
 
-	mymount "isula.org/syscontainer-tools/pkg/mount"
 	"github.com/docker/docker/pkg/mount"
+	"github.com/sirupsen/logrus"
+	"golang.org/x/sys/unix"
 
+	hconfig "isula.org/syscontainer-tools/config"
+	mymount "isula.org/syscontainer-tools/pkg/mount"
 	"isula.org/syscontainer-tools/types"
-	"github.com/sirupsen/logrus"
 )
 
 const (
 	masterPath      = "/.sharedpath/master"
 	midTransferPath = "/.sharedpath/midpath"
 	slavePath       = "/.sharedpath"
+	lockFile        = "master_locker"
 )
 
 /* Add path to container when it is running
@@ -171,17 +174,44 @@ func GetSlavePath() string {
 
 // PrepareHostPath prepare host path
 func PrepareHostPath(id string) error {
+	lockFile := filepath.Join(hconfig.IsuladToolsDir, lockFile)
+	// get lock file handler
+	f, err := os.OpenFile(lockFile, os.O_RDONLY|os.O_CREATE, 0600)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
 
-	if err := os.MkdirAll(masterPath, 0600); err != nil {
-		return fmt.Errorf("create host shared path failed, err: %s", err)
+	// lock
+	if err := unix.Flock(int(f.Fd()), unix.LOCK_EX); err != nil {
+		return fmt.Errorf("fail to lock file %v: %v", f.Name(), err)
 	}
-	if m, _ := mount.Mounted(masterPath); m != true {
+	mountErr := func() error {
+		mounted, err := mount.Mounted(masterPath)
+		if err != nil {
+			return fmt.Errorf("fail to know whether %v is mounted: %v", masterPath, err)
+		}
+		// has mounted
+		if mounted {
+			return nil
+		}
+		// do nothing if the directory has already been existed
+		if err := os.MkdirAll(masterPath, 0600); err != nil {
+			return fmt.Errorf("create host shared path failed, err: %s", err)
+		}
 		if err := mount.Mount("none", masterPath, "tmpfs", "size=16m"); err != nil {
 			return fmt.Errorf("mount host shared path failed:, %s", err)
 		}
 		if err := syscall.Mount("none", masterPath, "none", syscall.MS_SHARED|syscall.MS_REC, ""); err != nil {
 			return fmt.Errorf("failed to make mountpoint shared, err: %s", err)
 		}
+		return nil
+	}()
+	if unlockErr := unix.Flock(int(f.Fd()), unix.LOCK_UN); unlockErr != nil {
+		logrus.Errorf("failed to unlock %v : %v", f.Name(), unlockErr)
+	}
+	if mountErr != nil {
+		return mountErr
 	}
 
 	if err := os.MkdirAll(filepath.Join(masterPath, id), 0600); err != nil {
-- 
2.30.0