88 "fmt"
99 "io"
1010 "io/ioutil"
11+ "net"
1112 "os"
1213 "os/exec"
1314 "path/filepath"
@@ -671,20 +672,21 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
671672 defer imageDir .Close ()
672673
673674 rpcOpts := criurpc.CriuOpts {
674- ImagesDirFd : proto .Int32 (int32 (imageDir .Fd ())),
675- WorkDirFd : proto .Int32 (int32 (workDir .Fd ())),
676- LogLevel : proto .Int32 (4 ),
677- LogFile : proto .String ("dump.log" ),
678- Root : proto .String (c .config .Rootfs ),
679- ManageCgroups : proto .Bool (true ),
680- NotifyScripts : proto .Bool (true ),
681- Pid : proto .Int32 (int32 (c .initProcess .pid ())),
682- ShellJob : proto .Bool (criuOpts .ShellJob ),
683- LeaveRunning : proto .Bool (criuOpts .LeaveRunning ),
684- TcpEstablished : proto .Bool (criuOpts .TcpEstablished ),
685- ExtUnixSk : proto .Bool (criuOpts .ExternalUnixConnections ),
686- FileLocks : proto .Bool (criuOpts .FileLocks ),
687- EmptyNs : proto .Uint32 (criuOpts .EmptyNs ),
675+ ImagesDirFd : proto .Int32 (int32 (imageDir .Fd ())),
676+ WorkDirFd : proto .Int32 (int32 (workDir .Fd ())),
677+ LogLevel : proto .Int32 (4 ),
678+ LogFile : proto .String ("dump.log" ),
679+ Root : proto .String (c .config .Rootfs ),
680+ ManageCgroups : proto .Bool (true ),
681+ NotifyScripts : proto .Bool (true ),
682+ Pid : proto .Int32 (int32 (c .initProcess .pid ())),
683+ ShellJob : proto .Bool (criuOpts .ShellJob ),
684+ LeaveRunning : proto .Bool (criuOpts .LeaveRunning ),
685+ TcpEstablished : proto .Bool (criuOpts .TcpEstablished ),
686+ ExtUnixSk : proto .Bool (criuOpts .ExternalUnixConnections ),
687+ FileLocks : proto .Bool (criuOpts .FileLocks ),
688+ EmptyNs : proto .Uint32 (criuOpts .EmptyNs ),
689+ OrphanPtsMaster : proto .Bool (true ),
688690 }
689691
690692 // append optional criu opts, e.g., page-server and port
@@ -852,20 +854,21 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
852854 req := & criurpc.CriuReq {
853855 Type : & t ,
854856 Opts : & criurpc.CriuOpts {
855- ImagesDirFd : proto .Int32 (int32 (imageDir .Fd ())),
856- WorkDirFd : proto .Int32 (int32 (workDir .Fd ())),
857- EvasiveDevices : proto .Bool (true ),
858- LogLevel : proto .Int32 (4 ),
859- LogFile : proto .String ("restore.log" ),
860- RstSibling : proto .Bool (true ),
861- Root : proto .String (root ),
862- ManageCgroups : proto .Bool (true ),
863- NotifyScripts : proto .Bool (true ),
864- ShellJob : proto .Bool (criuOpts .ShellJob ),
865- ExtUnixSk : proto .Bool (criuOpts .ExternalUnixConnections ),
866- TcpEstablished : proto .Bool (criuOpts .TcpEstablished ),
867- FileLocks : proto .Bool (criuOpts .FileLocks ),
868- EmptyNs : proto .Uint32 (criuOpts .EmptyNs ),
857+ ImagesDirFd : proto .Int32 (int32 (imageDir .Fd ())),
858+ WorkDirFd : proto .Int32 (int32 (workDir .Fd ())),
859+ EvasiveDevices : proto .Bool (true ),
860+ LogLevel : proto .Int32 (4 ),
861+ LogFile : proto .String ("restore.log" ),
862+ RstSibling : proto .Bool (true ),
863+ Root : proto .String (root ),
864+ ManageCgroups : proto .Bool (true ),
865+ NotifyScripts : proto .Bool (true ),
866+ ShellJob : proto .Bool (criuOpts .ShellJob ),
867+ ExtUnixSk : proto .Bool (criuOpts .ExternalUnixConnections ),
868+ TcpEstablished : proto .Bool (criuOpts .TcpEstablished ),
869+ FileLocks : proto .Bool (criuOpts .FileLocks ),
870+ EmptyNs : proto .Uint32 (criuOpts .EmptyNs ),
871+ OrphanPtsMaster : proto .Bool (true ),
869872 },
870873 }
871874
@@ -961,6 +964,11 @@ func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *
961964
962965 logPath := filepath .Join (opts .WorkDirectory , req .GetOpts ().GetLogFile ())
963966 criuClient := os .NewFile (uintptr (fds [0 ]), "criu-transport-client" )
967+ criuClientCon , err := net .FileConn (criuClient )
968+ if err != nil {
969+ return err
970+ }
971+
964972 criuServer := os .NewFile (uintptr (fds [1 ]), "criu-transport-server" )
965973 defer criuClient .Close ()
966974 defer criuServer .Close ()
@@ -1020,14 +1028,15 @@ func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *
10201028 if err != nil {
10211029 return err
10221030 }
1023- _ , err = criuClient .Write (data )
1031+ _ , err = criuClientCon .Write (data )
10241032 if err != nil {
10251033 return err
10261034 }
10271035
10281036 buf := make ([]byte , 10 * 4096 )
1037+ oob := make ([]byte , 4096 )
10291038 for true {
1030- n , err := criuClient . Read ( buf )
1039+ n , oobn , _ , _ , err := criuClientCon .( * net. UnixConn ). ReadMsgUnix ( buf , oob )
10311040 if err != nil {
10321041 return err
10331042 }
@@ -1051,7 +1060,7 @@ func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *
10511060 t := resp .GetType ()
10521061 switch {
10531062 case t == criurpc .CriuReqType_NOTIFY :
1054- if err := c .criuNotifications (resp , process , opts , extFds ); err != nil {
1063+ if err := c .criuNotifications (resp , process , opts , extFds , oob [: oobn ] ); err != nil {
10551064 return err
10561065 }
10571066 t = criurpc .CriuReqType_NOTIFY
@@ -1135,11 +1144,12 @@ func unlockNetwork(config *configs.Config) error {
11351144 return nil
11361145}
11371146
1138- func (c * linuxContainer ) criuNotifications (resp * criurpc.CriuResp , process * Process , opts * CriuOpts , fds []string ) error {
1147+ func (c * linuxContainer ) criuNotifications (resp * criurpc.CriuResp , process * Process , opts * CriuOpts , fds []string , oob [] byte ) error {
11391148 notify := resp .GetNotify ()
11401149 if notify == nil {
11411150 return fmt .Errorf ("invalid response: %s" , resp .String ())
11421151 }
1152+ logrus .Debugf ("notify: %s\n " , notify .GetScript ())
11431153 switch {
11441154 case notify .GetScript () == "post-dump" :
11451155 f , err := os .Create (filepath .Join (c .root , "checkpoint" ))
@@ -1192,6 +1202,15 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
11921202 logrus .Error (err )
11931203 }
11941204 }
1205+ case notify .GetScript () == "orphan-pts-master" :
1206+ scm , err := syscall .ParseSocketControlMessage (oob )
1207+ if err != nil {
1208+ return err
1209+ }
1210+ fds , err := syscall .ParseUnixRights (& scm [0 ])
1211+
1212+ process .consoleChan = make (chan * os.File , 1 )
1213+ process .consoleChan <- os .NewFile (uintptr (fds [0 ]), "console" )
11951214 }
11961215 return nil
11971216}
0 commit comments