Files

60 lines
1.5 KiB
Go

package trafficappmarks
import (
"fmt"
"os"
"path/filepath"
"strings"
"syscall"
)
func ResolveCgroupV2PathForNft(input string, cgroupRootPath string) (rel string, level int, inodeID uint64, abs string, err error) {
raw := strings.TrimSpace(input)
if raw == "" {
return "", 0, 0, "", fmt.Errorf("empty cgroup")
}
rel = NormalizeCgroupRelOnly(raw)
if rel == "" {
return "", 0, 0, raw, fmt.Errorf("invalid cgroup path: %s", raw)
}
inodeID, err = CgroupDirInode(cgroupRootPath, rel)
if err != nil {
return "", 0, 0, raw, err
}
level = strings.Count(rel, "/") + 1
abs = "/" + rel
return rel, level, inodeID, abs, nil
}
func NormalizeCgroupRelOnly(raw string) string {
rel := strings.TrimSpace(raw)
rel = strings.TrimPrefix(rel, "/")
rel = filepath.Clean(rel)
if rel == "." || rel == "" {
return ""
}
if strings.HasPrefix(rel, "..") || strings.Contains(rel, "../") {
return ""
}
return rel
}
func CgroupDirInode(cgroupRootPath, rel string) (uint64, error) {
full := filepath.Join(cgroupRootPath, strings.TrimPrefix(rel, "/"))
fi, err := os.Stat(full)
if err != nil || fi == nil || !fi.IsDir() {
return 0, fmt.Errorf("cgroup not found: %s", "/"+strings.TrimPrefix(rel, "/"))
}
st, ok := fi.Sys().(*syscall.Stat_t)
if !ok || st == nil {
return 0, fmt.Errorf("cannot stat cgroup: %s", "/"+strings.TrimPrefix(rel, "/"))
}
if st.Ino == 0 {
return 0, fmt.Errorf("invalid cgroup inode id: %s", "/"+strings.TrimPrefix(rel, "/"))
}
return st.Ino, nil
}