@@ -2,10 +2,13 @@ package osl
22
33import (
44 "fmt"
5+ "io/ioutil"
56 "net"
67 "os"
78 "os/exec"
89 "runtime"
10+ "strconv"
11+ "strings"
912 "sync"
1013 "syscall"
1114 "time"
@@ -133,6 +136,39 @@ func GC() {
133136// container id.
134137func GenerateKey (containerID string ) string {
135138 maxLen := 12
139+ // Read sandbox key from host for overlay
140+ if strings .HasPrefix (containerID , "-" ) {
141+ var (
142+ index int
143+ indexStr string
144+ tmpkey string
145+ )
146+ dir , err := ioutil .ReadDir (prefix )
147+ if err != nil {
148+ return ""
149+ }
150+
151+ for _ , v := range dir {
152+ id := v .Name ()
153+ if strings .HasSuffix (id , containerID [:maxLen - 1 ]) {
154+ indexStr = strings .TrimSuffix (id , containerID [:maxLen - 1 ])
155+ tmpindex , err := strconv .Atoi (indexStr )
156+ if err != nil {
157+ return ""
158+ }
159+ if tmpindex > index {
160+ index = tmpindex
161+ tmpkey = id
162+ }
163+
164+ }
165+ }
166+ containerID = tmpkey
167+ if containerID == "" {
168+ return ""
169+ }
170+ }
171+
136172 if len (containerID ) < maxLen {
137173 maxLen = len (containerID )
138174 }
@@ -142,10 +178,12 @@ func GenerateKey(containerID string) string {
142178
143179// NewSandbox provides a new sandbox instance created in an os specific way
144180// provided a key which uniquely identifies the sandbox
145- func NewSandbox (key string , osCreate bool ) (Sandbox , error ) {
146- err := createNetworkNamespace (key , osCreate )
147- if err != nil {
148- return nil , err
181+ func NewSandbox (key string , osCreate , isRestore bool ) (Sandbox , error ) {
182+ if ! isRestore {
183+ err := createNetworkNamespace (key , osCreate )
184+ if err != nil {
185+ return nil , err
186+ }
149187 }
150188
151189 n := & networkNamespace {path : key , isDefault : ! osCreate }
@@ -347,3 +385,108 @@ func (n *networkNamespace) Destroy() error {
347385 addToGarbagePaths (n .path )
348386 return nil
349387}
388+
389+ // Restore restore the network namespace
390+ func (n * networkNamespace ) Restore (ifsopt map [string ][]IfaceOption , routes []* types.StaticRoute , gw net.IP , gw6 net.IP ) error {
391+ // restore interfaces
392+ for name , opts := range ifsopt {
393+ if ! strings .Contains (name , "+" ) {
394+ return fmt .Errorf ("wrong iface name in restore osl sandbox interface: %s" , name )
395+ }
396+ seps := strings .Split (name , "+" )
397+ srcName := seps [0 ]
398+ dstPrefix := seps [1 ]
399+ i := & nwIface {srcName : srcName , dstName : dstPrefix , ns : n }
400+ i .processInterfaceOptions (opts ... )
401+ if i .master != "" {
402+ i .dstMaster = n .findDst (i .master , true )
403+ if i .dstMaster == "" {
404+ return fmt .Errorf ("could not find an appropriate master %q for %q" ,
405+ i .master , i .srcName )
406+ }
407+ }
408+ if n .isDefault {
409+ i .dstName = i .srcName
410+ } else {
411+ // due to the docker network connect/disconnect, so the dstName should
412+ // restore from the namespace
413+ err := nsInvoke (n .path , func (nsFD int ) error { return nil }, func (callerFD int ) error {
414+ ifaces , err := net .Interfaces ()
415+ if err != nil {
416+ return err
417+ }
418+ for _ , iface := range ifaces {
419+ addrs , err := iface .Addrs ()
420+ if err != nil {
421+ return err
422+ }
423+ if strings .HasPrefix (iface .Name , "vxlan" ) {
424+ if i .dstName == "vxlan" {
425+ i .dstName = iface .Name
426+ break
427+ }
428+ }
429+ // find the interface name by ip
430+ if i .address != nil {
431+ for _ , addr := range addrs {
432+ if addr .String () == i .address .String () {
433+ i .dstName = iface .Name
434+ break
435+ }
436+ continue
437+ }
438+ if i .dstName == iface .Name {
439+ break
440+ }
441+ }
442+ // This is to find the interface name of the pair in overlay sandbox
443+ if strings .HasPrefix (iface .Name , "veth" ) {
444+ if i .master != "" && i .dstName == "veth" {
445+ i .dstName = iface .Name
446+ }
447+ }
448+ }
449+ return nil
450+ })
451+ if err != nil {
452+ return err
453+ }
454+ var index int
455+ indexStr := strings .TrimPrefix (i .dstName , dstPrefix )
456+ if indexStr != "" {
457+ index , err = strconv .Atoi (indexStr )
458+ if err != nil {
459+ return err
460+ }
461+ }
462+ index ++
463+ n .Lock ()
464+ if index > n .nextIfIndex {
465+ n .nextIfIndex = index
466+ }
467+ n .iFaces = append (n .iFaces , i )
468+ n .Unlock ()
469+ }
470+ }
471+
472+ // restore routes
473+ for _ , r := range routes {
474+ n .Lock ()
475+ n .staticRoutes = append (n .staticRoutes , r )
476+ n .Unlock ()
477+ }
478+
479+ // restore gateway
480+ if len (gw ) > 0 {
481+ n .Lock ()
482+ n .gw = gw
483+ n .Unlock ()
484+ }
485+
486+ if len (gw6 ) > 0 {
487+ n .Lock ()
488+ n .gwv6 = gw6
489+ n .Unlock ()
490+ }
491+ return nil
492+ }
0 commit comments