github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/sandbox_store.go (about) 1 package libnetwork 2 3 import ( 4 "container/heap" 5 "encoding/json" 6 "sync" 7 8 "github.com/Sirupsen/logrus" 9 "github.com/docker/libnetwork/datastore" 10 "github.com/docker/libnetwork/osl" 11 ) 12 13 const ( 14 sandboxPrefix = "sandbox" 15 ) 16 17 type epState struct { 18 Eid string 19 Nid string 20 } 21 22 type sbState struct { 23 ID string 24 Cid string 25 c *controller 26 dbIndex uint64 27 dbExists bool 28 Eps []epState 29 EpPriority map[string]int 30 ExtDNS []string 31 } 32 33 func (sbs *sbState) Key() []string { 34 return []string{sandboxPrefix, sbs.ID} 35 } 36 37 func (sbs *sbState) KeyPrefix() []string { 38 return []string{sandboxPrefix} 39 } 40 41 func (sbs *sbState) Value() []byte { 42 b, err := json.Marshal(sbs) 43 if err != nil { 44 return nil 45 } 46 return b 47 } 48 49 func (sbs *sbState) SetValue(value []byte) error { 50 return json.Unmarshal(value, sbs) 51 } 52 53 func (sbs *sbState) Index() uint64 { 54 sbi, err := sbs.c.SandboxByID(sbs.ID) 55 if err != nil { 56 return sbs.dbIndex 57 } 58 59 sb := sbi.(*sandbox) 60 maxIndex := sb.dbIndex 61 if sbs.dbIndex > maxIndex { 62 maxIndex = sbs.dbIndex 63 } 64 65 return maxIndex 66 } 67 68 func (sbs *sbState) SetIndex(index uint64) { 69 sbs.dbIndex = index 70 sbs.dbExists = true 71 72 sbi, err := sbs.c.SandboxByID(sbs.ID) 73 if err != nil { 74 return 75 } 76 77 sb := sbi.(*sandbox) 78 sb.dbIndex = index 79 sb.dbExists = true 80 } 81 82 func (sbs *sbState) Exists() bool { 83 if sbs.dbExists { 84 return sbs.dbExists 85 } 86 87 sbi, err := sbs.c.SandboxByID(sbs.ID) 88 if err != nil { 89 return false 90 } 91 92 sb := sbi.(*sandbox) 93 return sb.dbExists 94 } 95 96 func (sbs *sbState) Skip() bool { 97 return false 98 } 99 100 func (sbs *sbState) New() datastore.KVObject { 101 return &sbState{c: sbs.c} 102 } 103 104 func (sbs *sbState) CopyTo(o datastore.KVObject) error { 105 dstSbs := o.(*sbState) 106 dstSbs.c = sbs.c 107 dstSbs.ID = sbs.ID 108 dstSbs.Cid = sbs.Cid 109 dstSbs.dbIndex = sbs.dbIndex 110 dstSbs.dbExists = sbs.dbExists 111 dstSbs.EpPriority = sbs.EpPriority 112 113 for _, eps := range sbs.Eps { 114 dstSbs.Eps = append(dstSbs.Eps, eps) 115 } 116 117 for _, dns := range sbs.ExtDNS { 118 dstSbs.ExtDNS = append(dstSbs.ExtDNS, dns) 119 } 120 121 return nil 122 } 123 124 func (sbs *sbState) DataScope() string { 125 return datastore.LocalScope 126 } 127 128 func (sb *sandbox) storeUpdate() error { 129 sbs := &sbState{ 130 c: sb.controller, 131 ID: sb.id, 132 Cid: sb.containerID, 133 EpPriority: sb.epPriority, 134 ExtDNS: sb.extDNS, 135 } 136 137 retry: 138 sbs.Eps = nil 139 for _, ep := range sb.getConnectedEndpoints() { 140 // If the endpoint is not persisted then do not add it to 141 // the sandbox checkpoint 142 if ep.Skip() { 143 continue 144 } 145 146 eps := epState{ 147 Nid: ep.getNetwork().ID(), 148 Eid: ep.ID(), 149 } 150 151 sbs.Eps = append(sbs.Eps, eps) 152 } 153 154 err := sb.controller.updateToStore(sbs) 155 if err == datastore.ErrKeyModified { 156 // When we get ErrKeyModified it is sufficient to just 157 // go back and retry. No need to get the object from 158 // the store because we always regenerate the store 159 // state from in memory sandbox state 160 goto retry 161 } 162 163 return err 164 } 165 166 func (sb *sandbox) storeDelete() error { 167 sbs := &sbState{ 168 c: sb.controller, 169 ID: sb.id, 170 Cid: sb.containerID, 171 dbIndex: sb.dbIndex, 172 dbExists: sb.dbExists, 173 } 174 175 return sb.controller.deleteFromStore(sbs) 176 } 177 178 func (c *controller) sandboxCleanup(activeSandboxes map[string]interface{}) { 179 store := c.getStore(datastore.LocalScope) 180 if store == nil { 181 logrus.Errorf("Could not find local scope store while trying to cleanup sandboxes") 182 return 183 } 184 185 kvol, err := store.List(datastore.Key(sandboxPrefix), &sbState{c: c}) 186 if err != nil && err != datastore.ErrKeyNotFound { 187 logrus.Errorf("failed to get sandboxes for scope %s: %v", store.Scope(), err) 188 return 189 } 190 191 // It's normal for no sandboxes to be found. Just bail out. 192 if err == datastore.ErrKeyNotFound { 193 return 194 } 195 196 for _, kvo := range kvol { 197 sbs := kvo.(*sbState) 198 199 sb := &sandbox{ 200 id: sbs.ID, 201 controller: sbs.c, 202 containerID: sbs.Cid, 203 endpoints: epHeap{}, 204 populatedEndpoints: map[string]struct{}{}, 205 dbIndex: sbs.dbIndex, 206 isStub: true, 207 dbExists: true, 208 extDNS: sbs.ExtDNS, 209 } 210 211 msg := " for cleanup" 212 create := true 213 isRestore := false 214 if val, ok := activeSandboxes[sb.ID()]; ok { 215 msg = "" 216 sb.isStub = false 217 isRestore = true 218 opts := val.([]SandboxOption) 219 sb.processOptions(opts...) 220 sb.restorePath() 221 create = !sb.config.useDefaultSandBox 222 heap.Init(&sb.endpoints) 223 } 224 sb.osSbox, err = osl.NewSandbox(sb.Key(), create, isRestore) 225 if err != nil { 226 logrus.Errorf("failed to create osl sandbox while trying to restore sandbox %s%s: %v", sb.ID()[0:7], msg, err) 227 continue 228 } 229 230 c.Lock() 231 c.sandboxes[sb.id] = sb 232 c.Unlock() 233 234 for _, eps := range sbs.Eps { 235 n, err := c.getNetworkFromStore(eps.Nid) 236 var ep *endpoint 237 if err != nil { 238 logrus.Errorf("getNetworkFromStore for nid %s failed while trying to build sandbox for cleanup: %v", eps.Nid, err) 239 n = &network{id: eps.Nid, ctrlr: c, drvOnce: &sync.Once{}, persist: true} 240 ep = &endpoint{id: eps.Eid, network: n, sandboxID: sbs.ID} 241 } else { 242 ep, err = n.getEndpointFromStore(eps.Eid) 243 if err != nil { 244 logrus.Errorf("getEndpointFromStore for eid %s failed while trying to build sandbox for cleanup: %v", eps.Eid, err) 245 ep = &endpoint{id: eps.Eid, network: n, sandboxID: sbs.ID} 246 } 247 } 248 if _, ok := activeSandboxes[sb.ID()]; ok && err != nil { 249 logrus.Errorf("failed to restore endpoint %s in %s for container %s due to %v", eps.Eid, eps.Nid, sb.ContainerID(), err) 250 continue 251 } 252 heap.Push(&sb.endpoints, ep) 253 } 254 255 if _, ok := activeSandboxes[sb.ID()]; !ok { 256 logrus.Infof("Removing stale sandbox %s (%s)", sb.id, sb.containerID) 257 if err := sb.delete(true); err != nil { 258 logrus.Errorf("Failed to delete sandbox %s while trying to cleanup: %v", sb.id, err) 259 } 260 continue 261 } 262 263 // reconstruct osl sandbox field 264 if !sb.config.useDefaultSandBox { 265 if err := sb.restoreOslSandbox(); err != nil { 266 logrus.Errorf("failed to populate fields for osl sandbox %s", sb.ID()) 267 continue 268 } 269 } else { 270 c.sboxOnce.Do(func() { 271 c.defOsSbox = sb.osSbox 272 }) 273 } 274 275 for _, ep := range sb.endpoints { 276 // Watch for service records 277 if !c.isAgent() { 278 c.watchSvcRecord(ep) 279 } 280 } 281 } 282 }