github.com/boomhut/fiber/v2@v2.0.0-20230603160335-b65c856e57d3/internal/gopsutil/mem/mem_solaris.go (about) 1 package mem 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "os/exec" 8 "regexp" 9 "strconv" 10 "strings" 11 12 "github.com/boomhut/fiber/v2/internal/gopsutil/common" 13 ) 14 15 // VirtualMemory for Solaris is a minimal implementation which only returns 16 // what Nomad needs. It does take into account global vs zone, however. 17 func VirtualMemory() (*VirtualMemoryStat, error) { 18 return VirtualMemoryWithContext(context.Background()) 19 } 20 21 func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { 22 result := &VirtualMemoryStat{} 23 24 zoneName, err := zoneName() 25 if err != nil { 26 return nil, err 27 } 28 29 if zoneName == "global" { 30 cap, err := globalZoneMemoryCapacity() 31 if err != nil { 32 return nil, err 33 } 34 result.Total = cap 35 } else { 36 cap, err := nonGlobalZoneMemoryCapacity() 37 if err != nil { 38 return nil, err 39 } 40 result.Total = cap 41 } 42 43 return result, nil 44 } 45 46 func SwapMemory() (*SwapMemoryStat, error) { 47 return SwapMemoryWithContext(context.Background()) 48 } 49 50 func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { 51 return nil, common.ErrNotImplementedError 52 } 53 54 func zoneName() (string, error) { 55 zonename, err := exec.LookPath("zonename") 56 if err != nil { 57 return "", err 58 } 59 60 ctx := context.Background() 61 out, err := invoke.CommandWithContext(ctx, zonename) 62 if err != nil { 63 return "", err 64 } 65 66 return strings.TrimSpace(string(out)), nil 67 } 68 69 var globalZoneMemoryCapacityMatch = regexp.MustCompile(`memory size: ([\d]+) Megabytes`) 70 71 func globalZoneMemoryCapacity() (uint64, error) { 72 prtconf, err := exec.LookPath("prtconf") 73 if err != nil { 74 return 0, err 75 } 76 77 ctx := context.Background() 78 out, err := invoke.CommandWithContext(ctx, prtconf) 79 if err != nil { 80 return 0, err 81 } 82 83 match := globalZoneMemoryCapacityMatch.FindAllStringSubmatch(string(out), -1) 84 if len(match) != 1 { 85 return 0, errors.New("memory size not contained in output of /usr/sbin/prtconf") 86 } 87 88 totalMB, err := strconv.ParseUint(match[0][1], 10, 64) 89 if err != nil { 90 return 0, err 91 } 92 93 return totalMB * 1024 * 1024, nil 94 } 95 96 var kstatMatch = regexp.MustCompile(`([^\s]+)[\s]+([^\s]*)`) 97 98 func nonGlobalZoneMemoryCapacity() (uint64, error) { 99 kstat, err := exec.LookPath("kstat") 100 if err != nil { 101 return 0, err 102 } 103 104 ctx := context.Background() 105 out, err := invoke.CommandWithContext(ctx, kstat, "-p", "-c", "zone_memory_cap", "memory_cap:*:*:physcap") 106 if err != nil { 107 return 0, err 108 } 109 110 kstats := kstatMatch.FindAllStringSubmatch(string(out), -1) 111 if len(kstats) != 1 { 112 return 0, fmt.Errorf("expected 1 kstat, found %d", len(kstats)) 113 } 114 115 memSizeBytes, err := strconv.ParseUint(kstats[0][2], 10, 64) 116 if err != nil { 117 return 0, err 118 } 119 120 return memSizeBytes, nil 121 }