@@ -30,6 +30,7 @@ import (
3030 "time"
3131
3232 "github.com/golang/glog"
33+ cadvisorapiv2 "github.com/google/cadvisor/info/v2"
3334 "github.com/opencontainers/runc/libcontainer/cgroups"
3435 "github.com/opencontainers/runc/libcontainer/cgroups/fs"
3536 "github.com/opencontainers/runc/libcontainer/configs"
@@ -219,30 +220,12 @@ func NewContainerManager(mountUtil mount.Interface, cadvisorInterface cadvisor.I
219220 var capacity = v1.ResourceList {}
220221 // It is safe to invoke `MachineInfo` on cAdvisor before logically initializing cAdvisor here because
221222 // 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
222224 if info , err := cadvisorInterface .MachineInfo (); err == nil {
223225 capacity = cadvisor .CapacityFromMachineInfo (info )
224226 } else {
225227 return nil , err
226228 }
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- }
246229
247230 cgroupRoot := nodeConfig .CgroupRoot
248231 cgroupManager := NewCgroupManager (subsystems , nodeConfig .CgroupDriver )
@@ -551,6 +534,44 @@ func (cm *containerManagerImpl) Start(node *v1.Node, activePods ActivePodsFunc)
551534 }, 5 * time .Minute , wait .NeverStop )
552535 }
553536
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 ()
554575 return nil
555576}
556577
@@ -809,6 +830,8 @@ func getDockerAPIVersion(cadvisor cadvisor.Interface) *utilversion.Version {
809830 return dockerAPIVersion
810831}
811832
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
814837}
0 commit comments