lxd/util/resources.go
func MemoryResource() (*api.ResourcesMemory, error) {
	var buffers uint64
	var cached uint64
	var free uint64
	var total uint64

	f, err := os.Open("/proc/meminfo")
	if err != nil {
		return nil, err
	}
	defer f.Close()

	cleanLine := func(l string) (string, error) {
		l = strings.TrimSpace(l)
		idx := strings.LastIndex(l, "kB")
		if idx < 0 {
			return "", fmt.Errorf(`Failed to detect "kB" suffix`)
		}

		return strings.TrimSpace(l[:idx]), nil
	}

	mem := api.ResourcesMemory{}
	scanner := bufio.NewScanner(f)
	found := 0
	for scanner.Scan() {
		var err error
		line := scanner.Text()

		if strings.HasPrefix(line, "MemTotal:") {
			line, err = cleanLine(line[len("MemTotal:"):])
			if err != nil {
				return nil, err
			}

			total, err = strconv.ParseUint(line, 10, 64)
			if err != nil {
				return nil, err
			}

			found++
		} else if strings.HasPrefix(line, "MemFree:") {
			line, err = cleanLine(line[len("MemFree:"):])
			if err != nil {
				return nil, err
			}

			free, err = strconv.ParseUint(line, 10, 64)
			if err != nil {
				return nil, err
			}

			found++
		} else if strings.HasPrefix(line, "Cached:") {
			line, err = cleanLine(line[len("Cached:"):])
			if err != nil {
				return nil, err
			}

			cached, err = strconv.ParseUint(line, 10, 64)
			if err != nil {
				return nil, err
			}

			found++
		} else if strings.HasPrefix(line, "Buffers:") {
			line, err = cleanLine(line[len("Buffers:"):])
			if err != nil {
				return nil, err
			}

			buffers, err = strconv.ParseUint(line, 10, 64)
			if err != nil {
				return nil, err
			}

			found++
		}

		if found == 4 {
			break
		}
	}

	mem.Total = total * 1024
	mem.Used = (total - free - cached - buffers) * 1024

	return &mem, err
}
func MemoryResource() (*api.ResourcesMemory, error) {
	var buffers uint64
	var cached uint64
	var free uint64
	var total uint64

	f, err := os.Open("/proc/meminfo")
	if err != nil {
		return nil, err
	}
	defer f.Close()

	cleanLine := func(l string) (string, error) {
		l = strings.TrimSpace(l)
		idx := strings.LastIndex(l, "kB")
		if idx < 0 {
			return "", fmt.Errorf(`Failed to detect "kB" suffix`)
		}

		return strings.TrimSpace(l[:idx]), nil
	}

	mem := api.ResourcesMemory{}
	scanner := bufio.NewScanner(f)
	found := 0
	for scanner.Scan() {
		var err error
		line := scanner.Text()

		if strings.HasPrefix(line, "MemTotal:") {
			line, err = cleanLine(line[len("MemTotal:"):])
			if err != nil {
				return nil, err
			}

			total, err = strconv.ParseUint(line, 10, 64)
			if err != nil {
				return nil, err
			}

			found++
		} else if strings.HasPrefix(line, "MemFree:") {
			line, err = cleanLine(line[len("MemFree:"):])
			if err != nil {
				return nil, err
			}

			free, err = strconv.ParseUint(line, 10, 64)
			if err != nil {
				return nil, err
			}

			found++
		} else if strings.HasPrefix(line, "Cached:") {
			line, err = cleanLine(line[len("Cached:"):])
			if err != nil {
				return nil, err
			}

			cached, err = strconv.ParseUint(line, 10, 64)
			if err != nil {
				return nil, err
			}

			found++
		} else if strings.HasPrefix(line, "Buffers:") {
			line, err = cleanLine(line[len("Buffers:"):])
			if err != nil {
				return nil, err
			}

			buffers, err = strconv.ParseUint(line, 10, 64)
			if err != nil {
				return nil, err
			}

			found++
		}

		if found == 4 {
			break
		}
	}

	mem.Total = total * 1024
	mem.Used = (total - free - cached - buffers) * 1024

	return &mem, err
}
// MemoryResource returns the system memory information