func linuxMemInfo() (*MemStats, error) { info, err := ioutil.ReadFile("/proc/self/status") if err != nil { return nil, err } var stats MemStats for _, e := range bytes.Split(info, []byte("\n")) { if !bytes.HasPrefix(e, []byte("Vm")) { continue } parts := bytes.Split(e, []byte(":")) if len(parts) != 2 { return nil, fmt.Errorf("unexpected line in proc stats: %q", string(e)) } val := strings.Trim(string(parts[1]), " \n\t") switch string(parts[0]) { case "VmSize": vmsize, err := humanize.ParseBytes(val) if err != nil { return nil, err } stats.Used = vmsize case "VmSwap": swapsize, err := humanize.ParseBytes(val) if err != nil { return nil, err } stats.Swap = swapsize } } return &stats, nil }
func NewGC(n *core.IpfsNode) (*GC, error) { r := n.Repo cfg, err := r.Config() if err != nil { return nil, err } // check if cfg has these fields initialized // TODO: there should be a general check for all of the cfg fields // maybe distinguish between user config file and default struct? if cfg.Datastore.StorageMax == "" { r.SetConfigKey("Datastore.StorageMax", "10GB") cfg.Datastore.StorageMax = "10GB" } if cfg.Datastore.StorageGCWatermark == 0 { r.SetConfigKey("Datastore.StorageGCWatermark", 90) cfg.Datastore.StorageGCWatermark = 90 } storageMax, err := humanize.ParseBytes(cfg.Datastore.StorageMax) if err != nil { return nil, err } storageGC := storageMax * uint64(cfg.Datastore.StorageGCWatermark) / 100 // calculate the slack space between StorageMax and StorageGCWatermark // used to limit GC duration slackGB := (storageMax - storageGC) / 10e9 if slackGB < 1 { slackGB = 1 } return &GC{ Node: n, Repo: r, StorageMax: storageMax, StorageGC: storageGC, SlackGB: slackGB, }, nil }