From 3b181aba17cbb414249703bcbada4d36170de212 Mon Sep 17 00:00:00 2001
From: Song Zhang <zhangsong34@huawei.com>
Date: Wed, 6 Dec 2023 20:21:43 +0800
Subject: [PATCH] [Huawei]lxcfs-tools: support lxcfs reliability for docker
 containers

Signed-off-by: Song Zhang <zhangsong34@huawei.com>
---
 libmount/container_work.go | 29 ++++++++++++-------------
 remountcmd.go              | 43 +++++++++++++++++++++++++++++++++++---
 umountcmd.go               |  4 +++-
 3 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/libmount/container_work.go b/libmount/container_work.go
index f10a547..e1cb5ac 100644
--- a/libmount/container_work.go
+++ b/libmount/container_work.go
@@ -26,7 +26,7 @@ import (
 )
 
 var (
-    lxcfsPath = "/var/lib/lxc/lxcfs/cgroup"
+	lxcfsPath = "/var/lib/lxc/lxcfs/cgroup"
 )
 
 func init() {
@@ -99,13 +99,13 @@ func doMount(pipe *os.File) error {
 		return err
 	}
 
-    // remount lxcfs cgroup path readonly
-    if err := syscall.Mount(mount.Rootfs+lxcfsPath, mount.Rootfs+lxcfsPath, "none", syscall.MS_BIND, ""); err != nil {
-        return err
-    }
-    if err := syscall.Mount(mount.Rootfs+lxcfsPath, mount.Rootfs+lxcfsPath, "none", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY, ""); err != nil {
-        return err
-    }
+	// remount lxcfs cgroup path readonly
+	if err := syscall.Mount(mount.Rootfs+lxcfsPath, mount.Rootfs+lxcfsPath, "none", syscall.MS_BIND, ""); err != nil {
+		return err
+	}
+	if err := syscall.Mount(mount.Rootfs+lxcfsPath, mount.Rootfs+lxcfsPath, "none", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY, ""); err != nil {
+		return err
+	}
 	for i := 0; i < len(mount.SrcPaths) && i < len(mount.DestPaths); i++ {
 		if err := syscall.Mount(mount.SrcPaths[i], mount.DestPaths[i], "none", syscall.MS_BIND, ""); err != nil {
 			return err
@@ -121,15 +121,16 @@ func doUmount(pipe *os.File) error {
 	}
 	for i := 0; i < len(umount.Paths); i++ {
 		if err := syscall.Unmount(umount.Paths[i], syscall.MNT_DETACH); err != nil {
-			if !strings.Contains(err.Error(), "invalid argument") {
+			if !strings.Contains(err.Error(), "invalid argument") &&
+				!strings.Contains(err.Error(), "no such file or directory") {
 				return err
 			}
 		}
 	}
-    if err := syscall.Unmount(lxcfsPath, 0); err != nil {
-        if !strings.Contains(err.Error(), "invalid argument") {
-            return err
-        }
-    }
+	if err := syscall.Unmount(lxcfsPath, 0); err != nil {
+		if !strings.Contains(err.Error(), "invalid argument") {
+			return err
+		}
+	}
 	return nil
 }
diff --git a/remountcmd.go b/remountcmd.go
index 868d423..55a2599 100644
--- a/remountcmd.go
+++ b/remountcmd.go
@@ -22,6 +22,8 @@ import (
 	"lxcfs-tools/libmount"
 	"os"
 	"os/exec"
+	"encoding/json"
+	"strconv"
 	"strings"
 	"sync"
 	"syscall"
@@ -213,11 +215,45 @@ func remountAll(initMountns, initUserns string) error {
 	return nil
 }
 
+var (
+	runcStateDir = "/run/docker/runtime-runc/moby"
+)
+
+type runcState struct {
+	Id string `json:"id"`
+	Pid int `json:"pid"`
+}
+
+func getRuncContainerIDAndPid() ([]string, error) {
+	out, err := execCommond("runc", []string{"--root", runcStateDir, "list", "--format", "json"})
+	if err != nil {
+		return nil ,err
+	}
+	if out[0] == "" {
+		return out, nil
+	}
+	// get runc states
+	var states []runcState
+	var res []string
+	if err = json.Unmarshal([]byte(out[0]), &states); err != nil {
+		return nil, err
+	}
+	for _, st := range states {
+		res = append(res, st.Id+" "+strconv.Itoa(st.Pid))
+	}
+	return res, nil
+}
+
 func getContainerIDAndPid() ([]string, error) {
 	var (
 		out []string
 		err error
 	)
+
+	if _, err := exec.LookPath("isula"); err != nil {
+		return getRuncContainerIDAndPid()
+	}
+
 	for i := 0; i < 10; i++ {
 		out, err = execCommond("isula", []string{"ps", "--format", "{{.ID}} {{.Pid}}"})
 		if err == nil {
@@ -262,6 +298,9 @@ func remountToContainer(initMountns, initUserns, containerid string, pid string,
 		valueMountPaths = append(valueMountPaths, fmt.Sprintf("/var/lib/lxc/lxcfs/proc/%s", value.Name()))
 	}
 
+	valuePaths = append(valuePaths, "/sys/devices/system/cpu")
+	valueMountPaths = append(valueMountPaths, "/var/lib/lxc/lxcfs/sys/devices/system/cpu")
+
 	if err := libmount.NsExecUmount(pid, valuePaths); err != nil {
 		lxcfs_log.Errorf("unmount %v for container error: %v", valuePaths, err)
 	}
@@ -298,9 +337,7 @@ func isContainerExsit(containerid string) (string, error) {
 
 func execCommond(command string, params []string) ([]string, error) {
 	cmd := exec.Command(command, params...)
-	res := []string{
-		" ",
-	}
+	res := []string{}
 	lxcfs_log.Info("exec cmd :", cmd.Args)
 
 	stdout, err := cmd.StdoutPipe()
diff --git a/umountcmd.go b/umountcmd.go
index 8fd08ea..b988e21 100644
--- a/umountcmd.go
+++ b/umountcmd.go
@@ -85,7 +85,7 @@ var umountContainer = cli.Command{
 
 func umountAll(initMountns, initUserns string) error {
 	lxcfs_log.Info("begin umount All runing container...")
-	out, err := execCommond("isula", []string{"ps", "--format", "{{.ID}} {{.Pid}}"})
+	out, err := getContainerIDAndPid()
 	if err != nil {
 		return err
 	}
@@ -148,6 +148,8 @@ func umountForContainer(initMountns, initUserns, containerid string, pid string,
 		valuePaths = append(valuePaths, fmt.Sprintf("/proc/%s", value.Name()))
 	}
 
+	valuePaths = append(valuePaths, "/sys/devices/system/cpu")
+
 	if err := libmount.NsExecUmount(pid, valuePaths); err != nil {
 		lxcfs_log.Errorf("unmount %v for container %s error: %v", valuePaths, containerid, err)
 		return err
-- 
2.33.0

