Skip to content

Commit

Permalink
Add QEMU support for cgroup and pressure
Browse files Browse the repository at this point in the history
  • Loading branch information
taoky committed Mar 1, 2024
1 parent b3c41f6 commit 9299769
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 17 deletions.
67 changes: 50 additions & 17 deletions cmd/pressure/pressure.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bufio"
"fmt"
"log"
"os"
"sort"
"strings"

Expand All @@ -18,6 +19,13 @@ const (
MEMORY = "memory.pressure"
)

type VmType string

const (
LXC VmType = "LXC"
QEMU VmType = "Qemu"
)

const pressureLineFormat = "avg10=%f avg60=%f avg300=%f total=%d"

type PSILine struct {
Expand All @@ -32,8 +40,14 @@ type PSIStats struct {
Full *PSILine
}

func GetPressure(id string, filename string) (*PSIStats, error) {
f, err := cgroup.OpenLXC(id, filename)
func GetPressure(id idType, filename string) (*PSIStats, error) {
var f *os.File
var err error
if id.vmType == LXC {
f, err = cgroup.OpenLXC(id.id, filename)
} else {
f, err = cgroup.OpenQemu(id.id, filename)
}
if err != nil {
return nil, fmt.Errorf("open %s for %s: %w", filename, id, err)
}
Expand Down Expand Up @@ -63,26 +77,45 @@ func GetPressure(id string, filename string) (*PSIStats, error) {
return stats, nil
}

type idType struct {
id string
vmType VmType
}

func (id idType) String() string {
return fmt.Sprintf("%s (%s)", id.id, id.vmType)
}

type idAndPressure struct {
id string
id idType
pressure *PSIStats
}

func listPressures(filename string, topN int) error {
ids, err := cgroup.ListLXC()
lxcIds, err := cgroup.ListLXC()
if err != nil {
log.Fatal(err)
}
qemuIds, err := cgroup.ListQemu()
if err != nil {
log.Printf("ListQemu error (may not have qemu?): %v", err)
qemuIds = []string{}
}

pressures := make([]idAndPressure, 0, len(ids))
for _, id := range ids {
pressure, err := GetPressure(id, filename)
if err != nil {
log.Printf("GetPressure error for %s: %v", id, err)
continue
pressures := make([]idAndPressure, 0, len(lxcIds)+len(qemuIds))
appendToPressure := func(ids []string, vmType VmType) {
for _, id := range ids {
idtype := idType{id, vmType}
pressure, err := GetPressure(idtype, filename)
if err != nil {
log.Printf("GetPressure error for %s: %v", id, err)
continue
}
pressures = append(pressures, idAndPressure{idtype, pressure})
}
pressures = append(pressures, idAndPressure{id, pressure})
}
appendToPressure(lxcIds, LXC)
appendToPressure(qemuIds, QEMU)
sort.Slice(pressures, func(i, j int) bool {
return pressures[i].pressure.Some.Avg10 > pressures[j].pressure.Some.Avg10
})
Expand All @@ -95,24 +128,24 @@ func listPressures(filename string, topN int) error {
line := fmt.Sprintf("%s | %.1f | %.1f | %.1f", p.id, p.pressure.Some.Avg10, p.pressure.Some.Avg60, p.pressure.Some.Avg300)
lines = append(lines, line)
}
fmt.Printf("Top %d containers with %s\n", topN, filename)
fmt.Printf("Top %d containers/VMs with %s\n", topN, filename)
fmt.Println(columnize.SimpleFormat(lines))
return nil
}

func MakeCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "pressure [-c | --cpu] [-m | --memory] [-i | --io]",
Short: "List LXC with highest pressures",
Short: "List LXC and Qemu with highest pressures",
Aliases: []string{"p"},
Args: cobra.NoArgs,
}
flags := cmd.Flags()
flags.SortFlags = false
pCPU := flags.BoolP("cpu", "c", false, "list LXC with highest CPU pressures")
pMemory := flags.BoolP("memory", "m", false, "list LXC with highest memory pressures")
pIO := flags.BoolP("io", "i", false, "list LXC with highest I/O pressures")
pN := flags.IntP("count", "n", 5, "number of containers to show")
pCPU := flags.BoolP("cpu", "c", false, "list LXC and Qemu with highest CPU pressures")
pMemory := flags.BoolP("memory", "m", false, "list LXC and Qemu with highest memory pressures")
pIO := flags.BoolP("io", "i", false, "list LXC and Qemu with highest I/O pressures")
pN := flags.IntP("count", "n", 5, "number of containers & VMs to show")

cmd.RunE = func(cmd *cobra.Command, args []string) error {
enabled := []bool{*pCPU, *pMemory, *pIO}
Expand Down
24 changes: 24 additions & 0 deletions pkg/cgroup/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
)

const BaseDir = "/sys/fs/cgroup"
Expand All @@ -16,10 +17,18 @@ func OpenLXC(id string, filename string) (*os.File, error) {
return os.Open(GetFilenameLXC(id, filename))
}

func OpenQemu(id string, filename string) (*os.File, error) {
return os.Open(GetFilenameQemu(id, filename))
}

func GetFilenameLXC(id string, filename string) string {
return filepath.Join(BaseDir, "lxc", id, filename)
}

func GetFilenameQemu(id string, filename string) string {
return filepath.Join(BaseDir, "qemu.slice", id+".scope", filename)
}

func ListLXC() ([]string, error) {
entries, err := os.ReadDir(filepath.Join(BaseDir, "lxc"))
if err != nil {
Expand All @@ -34,6 +43,21 @@ func ListLXC() ([]string, error) {
return ids, nil
}

func ListQemu() ([]string, error) {
entries, err := os.ReadDir(filepath.Join(BaseDir, "qemu.slice"))
if err != nil {
return nil, err
}
ids := make([]string, 0, len(entries))
for _, entry := range entries {
if entry.IsDir() {
id := strings.TrimSuffix(entry.Name(), ".scope")
ids = append(ids, id)
}
}
return ids, nil
}

func KillLXC(id string) error {
return os.WriteFile(GetFilenameLXC(id, "cgroup.kill"), []byte("1"), 0)
}
Expand Down

0 comments on commit 9299769

Please sign in to comment.