@@ -30,6 +30,7 @@ import (
30
30
"time"
31
31
32
32
"github.com/golang/glog"
33
+ cadvisorapiv2 "github.com/google/cadvisor/info/v2"
33
34
"github.com/opencontainers/runc/libcontainer/cgroups"
34
35
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
35
36
"github.com/opencontainers/runc/libcontainer/configs"
@@ -219,30 +220,12 @@ func NewContainerManager(mountUtil mount.Interface, cadvisorInterface cadvisor.I
219
220
var capacity = v1.ResourceList {}
220
221
// It is safe to invoke `MachineInfo` on cAdvisor before logically initializing cAdvisor here because
221
222
// machine info is computed and cached once as part of cAdvisor object creation.
223
+ // But `RootFsInfo` and `ImagesFsInfo` are not available at this moment so they will be called later during manager starts
222
224
if info , err := cadvisorInterface .MachineInfo (); err == nil {
223
225
capacity = cadvisor .CapacityFromMachineInfo (info )
224
226
} else {
225
227
return nil , err
226
228
}
227
- rootfs , err := cadvisorInterface .RootFsInfo ()
228
- if err != nil {
229
- capacity [v1 .ResourceStorageScratch ] = resource .MustParse ("0Gi" )
230
- } else {
231
- for rName , rCap := range cadvisor .StorageScratchCapacityFromFsInfo (rootfs ) {
232
- capacity [rName ] = rCap
233
- }
234
- }
235
-
236
- if hasDedicatedImageFs , _ := cadvisorInterface .HasDedicatedImageFs (); hasDedicatedImageFs {
237
- imagesfs , err := cadvisorInterface .ImagesFsInfo ()
238
- if err != nil {
239
- glog .Errorf ("Failed to get Image filesystem information: %v" , err )
240
- } else {
241
- for rName , rCap := range cadvisor .StorageOverlayCapacityFromFsInfo (imagesfs ) {
242
- capacity [rName ] = rCap
243
- }
244
- }
245
- }
246
229
247
230
cgroupRoot := nodeConfig .CgroupRoot
248
231
cgroupManager := NewCgroupManager (subsystems , nodeConfig .CgroupDriver )
@@ -551,6 +534,44 @@ func (cm *containerManagerImpl) Start(node *v1.Node, activePods ActivePodsFunc)
551
534
}, 5 * time .Minute , wait .NeverStop )
552
535
}
553
536
537
+ // Local storage filesystem information from `RootFsInfo` and `ImagesFsInfo` is available at a later time
538
+ // depending on the time when cadvisor manager updates container stats. Therefore use a go routine to keep
539
+ // retrieving the information until it is available.
540
+ stopChan := make (chan struct {})
541
+ go wait .Until (func () {
542
+ if err := cm .setFsCapacity (); err != nil {
543
+ glog .Errorf ("[ContainerManager]: %v" , err )
544
+ return
545
+ }
546
+ close (stopChan )
547
+ }, time .Second , stopChan )
548
+ return nil
549
+ }
550
+
551
+ func (cm * containerManagerImpl ) setFsCapacity () error {
552
+ rootfs , err := cm .cadvisorInterface .RootFsInfo ()
553
+ if err != nil {
554
+ return fmt .Errorf ("Fail to get rootfs information %v" , err )
555
+ }
556
+ hasDedicatedImageFs , _ := cm .cadvisorInterface .HasDedicatedImageFs ()
557
+ var imagesfs cadvisorapiv2.FsInfo
558
+ if hasDedicatedImageFs {
559
+ imagesfs , err = cm .cadvisorInterface .ImagesFsInfo ()
560
+ if err != nil {
561
+ return fmt .Errorf ("Fail to get imagefs information %v" , err )
562
+ }
563
+ }
564
+
565
+ cm .Lock ()
566
+ for rName , rCap := range cadvisor .StorageScratchCapacityFromFsInfo (rootfs ) {
567
+ cm .capacity [rName ] = rCap
568
+ }
569
+ if hasDedicatedImageFs {
570
+ for rName , rCap := range cadvisor .StorageOverlayCapacityFromFsInfo (imagesfs ) {
571
+ cm .capacity [rName ] = rCap
572
+ }
573
+ }
574
+ cm .Unlock ()
554
575
return nil
555
576
}
556
577
@@ -809,6 +830,8 @@ func getDockerAPIVersion(cadvisor cadvisor.Interface) *utilversion.Version {
809
830
return dockerAPIVersion
810
831
}
811
832
812
- func (m * containerManagerImpl ) GetCapacity () v1.ResourceList {
813
- return m .capacity
833
+ func (cm * containerManagerImpl ) GetCapacity () v1.ResourceList {
834
+ cm .RLock ()
835
+ defer cm .RUnlock ()
836
+ return cm .capacity
814
837
}
0 commit comments