1+ // Copyright 2019 The Prometheus Authors
2+ // Licensed under the Apache License, Version 2.0 (the "License");
3+ // you may not use this file except in compliance with the License.
4+ // You may obtain a copy of the License at
5+ //
6+ // http://www.apache.org/licenses/LICENSE-2.0
7+ //
8+ // Unless required by applicable law or agreed to in writing, software
9+ // distributed under the License is distributed on an "AS IS" BASIS,
10+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+ // See the License for the specific language governing permissions and
12+ // limitations under the License.
13+
14+ // Package btrfs provides access to statistics exposed by ext4 filesystems.
15+ package ext4
16+
17+ import (
18+ "strings"
19+ "path/filepath"
20+
21+ "github.com/prometheus/procfs/internal/fs"
22+ "github.com/prometheus/procfs/internal/util"
23+ )
24+
25+ const (
26+ sysPath = "sys"
27+ sysFSPath = "fs"
28+ )
29+
30+ // Stats contains statistics for a single Btrfs filesystem.
31+ // See Linux fs/btrfs/sysfs.c for more information.
32+ type Stats struct {
33+ Name string
34+
35+ Errors uint64
36+ Warnings uint64
37+ Messages uint64
38+ }
39+
40+ // FS represents the pseudo-filesystems proc and sys, which provides an
41+ // interface to kernel data structures.
42+ type FS struct {
43+ proc * fs.FS
44+ sys * fs.FS
45+ }
46+
47+ // NewDefaultFS returns a new blockdevice fs using the default mountPoints for proc and sys.
48+ // It will error if either of these mount points can't be read.
49+ func NewDefaultFS () (FS , error ) {
50+ return NewFS (fs .DefaultProcMountPoint , fs .DefaultSysMountPoint )
51+ }
52+
53+ // NewFS returns a new XFS handle using the given proc and sys mountPoints. It will error
54+ // if either of the mounts point can't be read.
55+ func NewFS (procMountPoint string , sysMountPoint string ) (FS , error ) {
56+ if strings .TrimSpace (procMountPoint ) == "" {
57+ procMountPoint = fs .DefaultProcMountPoint
58+ }
59+ procfs , err := fs .NewFS (procMountPoint )
60+ if err != nil {
61+ return FS {}, err
62+ }
63+ if strings .TrimSpace (sysMountPoint ) == "" {
64+ sysMountPoint = fs .DefaultSysMountPoint
65+ }
66+ sysfs , err := fs .NewFS (sysMountPoint )
67+ if err != nil {
68+ return FS {}, err
69+ }
70+ return FS {& procfs , & sysfs }, nil
71+ }
72+
73+ // ProcStat returns stats for the filesystem.
74+ func (fs FS ) ProcStat () ([]* Stats , error ) {
75+ matches , err := filepath .Glob (fs .sys .Path ("fs/ext4/*" ))
76+ if (err != nil ) {
77+ return nil , err
78+ }
79+
80+ stats := make ([]* Stats , 0 , len (matches ))
81+ for _ , m := range matches {
82+ s := & Stats {}
83+ for file , p := range map [string ]* uint64 {
84+ "errors_count" : & s .Errors ,
85+ "warning_count" : & s .Warnings ,
86+ "msg_count" : & s .Messages ,
87+ } {
88+ var val uint64
89+ val , err = util .ReadUintFromFile (fs .sys .Path (m , file ))
90+ if err != nil {
91+ return nil , err
92+ }
93+ * p = val
94+ }
95+
96+ // "*" used in glob above indicates the name of the filesystem.
97+ name := filepath .Base (filepath .Dir (filepath .Dir (m )))
98+ s .Name = name
99+ stats = append (stats , s )
100+ }
101+
102+ return stats , nil
103+ }
0 commit comments