github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/daemon/monitor.go (about) 1 package daemon 2 3 import ( 4 "errors" 5 "fmt" 6 "runtime" 7 "strconv" 8 "time" 9 10 "github.com/Sirupsen/logrus" 11 "github.com/docker/docker/api/types" 12 "github.com/docker/docker/libcontainerd" 13 "github.com/docker/docker/restartmanager" 14 ) 15 16 // StateChanged updates daemon state changes from containerd 17 func (daemon *Daemon) StateChanged(id string, e libcontainerd.StateInfo) error { 18 c := daemon.containers.Get(id) 19 if c == nil { 20 fmt.Println("daemon/monitor.go no such container") 21 return fmt.Errorf("no such container: %s", id) 22 } 23 24 fmt.Println("daemon/monitor.go StateChanged id: ", id) 25 fmt.Println("daemon/monitor.go StateChanged State: ", e.State) 26 fmt.Println("daemon/monitor.go StateChanged Pid: ", e.Pid) 27 fmt.Println("daemon/monitor.go StateChanged ProcessID: ", e.ProcessID) 28 29 switch e.State { 30 case libcontainerd.StateOOM: 31 // StateOOM is Linux specific and should never be hit on Windows 32 if runtime.GOOS == "windows" { 33 return errors.New("Received StateOOM from libcontainerd on Windows. This should never happen.") 34 } 35 daemon.updateHealthMonitor(c) 36 daemon.LogContainerEvent(c, "oom") 37 case libcontainerd.StateExit: 38 // if container's AutoRemove flag is set, remove it after clean up 39 autoRemove := func() { 40 if c.HostConfig.AutoRemove { 41 if err := daemon.ContainerRm(c.ID, &types.ContainerRmConfig{ForceRemove: true, RemoveVolume: true}); err != nil { 42 logrus.Errorf("can't remove container %s: %v", c.ID, err) 43 } 44 } 45 } 46 47 c.Lock() 48 c.StreamConfig.Wait() 49 c.Reset(false) 50 51 restart, wait, err := c.RestartManager().ShouldRestart(e.ExitCode, false, time.Since(c.StartedAt)) 52 if err == nil && restart { 53 c.RestartCount++ 54 c.SetRestarting(platformConstructExitStatus(e)) 55 } else { 56 c.SetStopped(platformConstructExitStatus(e)) 57 defer autoRemove() 58 } 59 60 daemon.updateHealthMonitor(c) 61 attributes := map[string]string{ 62 "exitCode": strconv.Itoa(int(e.ExitCode)), 63 } 64 daemon.LogContainerEventWithAttributes(c, "die", attributes) 65 daemon.Cleanup(c) 66 67 if err == nil && restart { 68 go func() { 69 err := <-wait 70 if err == nil { 71 if err = daemon.containerStart(c, "", "", false); err != nil { 72 logrus.Debugf("failed to restart container: %+v", err) 73 } 74 } 75 if err != nil { 76 c.SetStopped(platformConstructExitStatus(e)) 77 defer autoRemove() 78 if err != restartmanager.ErrRestartCanceled { 79 logrus.Errorf("restartmanger wait error: %+v", err) 80 } 81 } 82 }() 83 } 84 85 defer c.Unlock() 86 if err := c.ToDisk(); err != nil { 87 return err 88 } 89 return daemon.postRunProcessing(c, e) 90 case libcontainerd.StateExitProcess: 91 92 fmt.Println("daemon/monitor.go StateExitProcess") 93 if execConfig := c.ExecCommands.Get(e.ProcessID); execConfig != nil { 94 ec := int(e.ExitCode) 95 execConfig.Lock() 96 defer execConfig.Unlock() 97 execConfig.ExitCode = &ec 98 execConfig.Running = false 99 execConfig.StreamConfig.Wait() 100 if err := execConfig.CloseStreams(); err != nil { 101 logrus.Errorf("%s: %s", c.ID, err) 102 } 103 104 // remove the exec command from the container's store only and not the 105 // daemon's store so that the exec command can be inspected. 106 c.ExecCommands.Delete(execConfig.ID) 107 } else { 108 logrus.Warnf("Ignoring StateExitProcess for %v but no exec command found", e) 109 } 110 case libcontainerd.StateStart, libcontainerd.StateRestore: 111 112 fmt.Println("daemon/monitor.go case StateStart") 113 // Container is already locked in this case 114 c.SetRunning(int(e.Pid), e.State == libcontainerd.StateStart) 115 fmt.Println("daemon/monitor.go case StateStart after Running running : ", int(e.Pid)) 116 c.HasBeenManuallyStopped = false 117 c.HasBeenStartedBefore = true 118 if err := c.ToDisk(); err != nil { 119 fmt.Println("daemon/monitor.go case StateStart toDisk err") 120 c.Reset(false) 121 return err 122 } 123 fmt.Println("daemon/monitor.go case StateStart before iHealth") 124 daemon.initHealthMonitor(c) 125 fmt.Println("daemon/monitor.go case StateStart initHealthMonitor") 126 daemon.LogContainerEvent(c, "start") 127 fmt.Println("daemon/monitor.go case StateStart LogContainerEvent") 128 fmt.Println("daemon/monitor.go case StateStart sleep 10 seconds") 129 time.Sleep(time.Second * 10) 130 case libcontainerd.StatePause: 131 // Container is already locked in this case 132 c.Paused = true 133 if err := c.ToDisk(); err != nil { 134 return err 135 } 136 daemon.updateHealthMonitor(c) 137 daemon.LogContainerEvent(c, "pause") 138 case libcontainerd.StateResume: 139 // Container is already locked in this case 140 c.Paused = false 141 if err := c.ToDisk(); err != nil { 142 return err 143 } 144 daemon.updateHealthMonitor(c) 145 daemon.LogContainerEvent(c, "unpause") 146 } 147 148 return nil 149 } 150 151 152 func (daemon *Daemon) GetFirstContainerBuildingStatus(id string) bool { 153 fmt.Println("daemon/monitor.go GetFirstContainerBuildingStatus()") 154 container, err := daemon.GetContainer(id) 155 if err != nil { 156 fmt.Println("daemon/monitor.go GetFirstContainerBuildingStatus() error!!!") 157 return false 158 } 159 160 return container.GetBuildingStatus() 161 } 162 163 164 func (daemon *Daemon) TriggerExitEvent(cId string) error { 165 fmt.Println("daemon/monitor.go TriggerExitEvent()") 166 167 if err := daemon.containerd.TriggerHandleStream(cId); err != nil { 168 fmt.Println("daemon/monitor.go TriggerExitEvent() error!!!") 169 return err 170 } 171 172 return nil 173 }