From 1efb88fbf554f3977a1a8aa1c79bc70cc1b66953 Mon Sep 17 00:00:00 2001 From: jiangpengfei Date: Sat, 25 Jul 2020 09:22:08 +0800 Subject: [PATCH 02/50] kata-runtime: fix kata-runtime skip read lines in /proc/mounts file problem reason: Since /proc/mounts is a virtual file which is changed dynamically by kernel, if we use file pointer to read content in this file line by line, we may miss read some lines. So we retry read /proc/mounts file again to fix this problem. Signed-off-by: jiangpengfei --- virtcontainers/utils/utils_linux.go | 58 +++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/virtcontainers/utils/utils_linux.go b/virtcontainers/utils/utils_linux.go index ad870d63..6cef4cfb 100644 --- a/virtcontainers/utils/utils_linux.go +++ b/virtcontainers/utils/utils_linux.go @@ -7,15 +7,18 @@ package utils import ( "bufio" + "bytes" "crypto/rand" "fmt" "io" + "io/ioutil" "math/big" "os" "strings" "syscall" "unsafe" + "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) @@ -93,6 +96,7 @@ const ( procMountsFile = "/proc/mounts" fieldsPerLine = 6 + maxRetryTimes = 5 ) const ( @@ -109,35 +113,45 @@ func GetDevicePathAndFsType(mountPoint string) (devicePath, fsType string, err e return } - var file *os.File + var retry int = 0 - file, err = os.Open(procMountsFile) - if err != nil { - return - } - - defer file.Close() + for retry <= maxRetryTimes { + var content []byte - reader := bufio.NewReader(file) - for { - var line string - - line, err = reader.ReadString('\n') - if err == io.EOF { - err = fmt.Errorf("Mount %s not found", mountPoint) + content, err = ioutil.ReadFile(procMountsFile) + if err != nil { return } - fields := strings.Fields(line) - if len(fields) != fieldsPerLine { - err = fmt.Errorf("Incorrect no of fields (expected %d, got %d)) :%s", fieldsPerLine, len(fields), line) - return + bytesReader := bytes.NewReader(content) + reader := bufio.NewReader(bytesReader) + + for { + var line string + + line, err = reader.ReadString('\n') + if err == io.EOF { + err = fmt.Errorf("Mount %s not found", mountPoint) + break + } + + fields := strings.Fields(line) + if len(fields) != fieldsPerLine { + err = fmt.Errorf("Incorrect no of fields (expected %d, got %d)) :%s", fieldsPerLine, len(fields), line) + return + } + + if mountPoint == fields[procPathIndex] { + devicePath = fields[procDeviceIndex] + fsType = fields[procTypeIndex] + return + } } - if mountPoint == fields[procPathIndex] { - devicePath = fields[procDeviceIndex] - fsType = fields[procTypeIndex] - return + retry = retry + 1 + if retry <= maxRetryTimes { + logrus.Warnf("can not find %s in %s, retry %d times again......", mountPoint, procMountsFile, retry) } } + return "", "", fmt.Errorf("retry %d times fail to get devicePath adn fs type", maxRetryTimes) } -- 2.14.3 (Apple Git-98)