@@ -37,15 +37,21 @@ type FsUsage struct {
3737 InodeUsage uint64
3838}
3939
40+ type FsUsageProvider interface {
41+ // Usage returns the fs usage
42+ Usage () (* FsUsage , error )
43+ // Targets returns where the fs usage metric is collected,it maybe a directory, a file or some
44+ // information about the snapshotter(for containerd)
45+ Targets () []string
46+ }
47+
4048type realFsHandler struct {
4149 sync.RWMutex
42- lastUpdate time.Time
43- usage FsUsage
44- period time.Duration
45- minPeriod time.Duration
46- rootfs string
47- extraDir string
48- fsInfo fs.FsInfo
50+ lastUpdate time.Time
51+ usage FsUsage
52+ period time.Duration
53+ minPeriod time.Duration
54+ usageProvider FsUsageProvider
4955 // Tells the container to stop.
5056 stopChan chan struct {}
5157}
@@ -58,56 +64,33 @@ const DefaultPeriod = time.Minute
5864
5965var _ FsHandler = & realFsHandler {}
6066
61- func NewFsHandler (period time.Duration , rootfs , extraDir string , fsInfo fs. FsInfo ) FsHandler {
67+ func NewFsHandler (period time.Duration , provider FsUsageProvider ) FsHandler {
6268 return & realFsHandler {
63- lastUpdate : time.Time {},
64- usage : FsUsage {},
65- period : period ,
66- minPeriod : period ,
67- rootfs : rootfs ,
68- extraDir : extraDir ,
69- fsInfo : fsInfo ,
70- stopChan : make (chan struct {}, 1 ),
69+ lastUpdate : time.Time {},
70+ usage : FsUsage {},
71+ period : period ,
72+ minPeriod : period ,
73+ usageProvider : provider ,
74+ stopChan : make (chan struct {}, 1 ),
7175 }
7276}
7377
7478func (fh * realFsHandler ) update () error {
75- var (
76- rootUsage , extraUsage fs.UsageInfo
77- rootErr , extraErr error
78- )
79- // TODO(vishh): Add support for external mounts.
80- if fh .rootfs != "" {
81- rootUsage , rootErr = fh .fsInfo .GetDirUsage (fh .rootfs )
82- }
8379
84- if fh .extraDir != "" {
85- extraUsage , extraErr = fh .fsInfo .GetDirUsage (fh .extraDir )
80+ usage , err := fh .usageProvider .Usage ()
81+
82+ if err != nil {
83+ return err
8684 }
8785
88- // Wait to handle errors until after all operartions are run.
89- // An error in one will not cause an early return, skipping others
9086 fh .Lock ()
9187 defer fh .Unlock ()
9288 fh .lastUpdate = time .Now ()
93- if fh .rootfs != "" && rootErr == nil {
94- fh .usage .InodeUsage = rootUsage .Inodes
95- fh .usage .BaseUsageBytes = rootUsage .Bytes
96- fh .usage .TotalUsageBytes = rootUsage .Bytes
97- }
98- if fh .extraDir != "" && extraErr == nil {
99- if fh .rootfs != "" {
100- fh .usage .TotalUsageBytes += extraUsage .Bytes
101- } else {
102- // rootfs is empty, totalUsageBytes use extra usage bytes
103- fh .usage .TotalUsageBytes = extraUsage .Bytes
104- }
105- }
10689
107- // Combine errors into a single error to return
108- if rootErr != nil || extraErr != nil {
109- return fmt . Errorf ( "rootDiskErr: %v, extraDiskErr: %v" , rootErr , extraErr )
110- }
90+ fh . usage . InodeUsage = usage . InodeUsage
91+ fh . usage . BaseUsageBytes = usage . BaseUsageBytes
92+ fh . usage . TotalUsageBytes = usage . TotalUsageBytes
93+
11194 return nil
11295}
11396
@@ -130,7 +113,8 @@ func (fh *realFsHandler) trackUsage() {
130113 // if the long duration is persistent either because of slow
131114 // disk or lots of containers.
132115 longOp = longOp + time .Second
133- klog .V (2 ).Infof ("fs: disk usage and inodes count on following dirs took %v: %v; will not log again for this container unless duration exceeds %v" , duration , []string {fh .rootfs , fh .extraDir }, longOp )
116+ klog .V (2 ).Infof (`fs: disk usage and inodes count on targets took %v: %v; ` +
117+ `will not log again for this container unless duration exceeds %v` , duration , fh .usageProvider .Targets (), longOp )
134118 }
135119 select {
136120 case <- fh .stopChan :
@@ -153,3 +137,56 @@ func (fh *realFsHandler) Usage() FsUsage {
153137 defer fh .RUnlock ()
154138 return fh .usage
155139}
140+
141+ type fsUsageProvider struct {
142+ fsInfo fs.FsInfo
143+ rootFs string
144+ // The directory consumed by the container but outside rootFs, e.g. directory of saving logs
145+ extraDir string
146+ }
147+
148+ func NewGeneralFsUsageProvider (fsInfo fs.FsInfo , rootFs , extraDir string ) FsUsageProvider {
149+ return & fsUsageProvider {
150+ fsInfo : fsInfo ,
151+ rootFs : rootFs ,
152+ extraDir : extraDir ,
153+ }
154+ }
155+
156+ func (f * fsUsageProvider ) Targets () []string {
157+ return []string {f .rootFs , f .extraDir }
158+ }
159+
160+ func (f * fsUsageProvider ) Usage () (* FsUsage , error ) {
161+ var (
162+ rootUsage , extraUsage fs.UsageInfo
163+ rootErr , extraErr error
164+ )
165+
166+ if f .rootFs != "" {
167+ rootUsage , rootErr = f .fsInfo .GetDirUsage (f .rootFs )
168+ }
169+
170+ if f .extraDir != "" {
171+ extraUsage , extraErr = f .fsInfo .GetDirUsage (f .extraDir )
172+ }
173+
174+ usage := & FsUsage {}
175+
176+ if f .rootFs != "" && rootErr == nil {
177+ usage .InodeUsage = rootUsage .Inodes
178+ usage .BaseUsageBytes = rootUsage .Bytes
179+ usage .TotalUsageBytes = rootUsage .Bytes
180+ }
181+
182+ if f .extraDir != "" && extraErr == nil {
183+ usage .TotalUsageBytes += extraUsage .Bytes
184+ }
185+
186+ // Combine errors into a single error to return
187+ if rootErr != nil || extraErr != nil {
188+ return nil , fmt .Errorf ("failed to obtain filesystem usage; rootDiskErr: %v, extraDiskErr: %v" , rootErr , extraErr )
189+ }
190+
191+ return usage , nil
192+ }
0 commit comments