MCPcopy
hub / github.com/apptainer/apptainer / startContainer

Function startContainer

internal/app/starter/master_linux.go:60–119  ·  view source on GitHub ↗
(ctx context.Context, masterSocket int, containerPid int, e *engine.Engine, fatalChan chan error)

Source from the content-addressed store, hash-verified

58}
59
60func startContainer(ctx context.Context, masterSocket int, containerPid int, e *engine.Engine, fatalChan chan error) {
61 comm := os.NewFile(uintptr(masterSocket), "master-socket")
62 if comm == nil {
63 fatalChan <- fmt.Errorf("bad master socket file descriptor")
64 return
65 }
66 conn, err := net.FileConn(comm)
67 comm.Close()
68 if err != nil {
69 fatalChan <- fmt.Errorf("failed to create master connection: %s", err)
70 return
71 }
72 defer conn.Close()
73
74 data := make([]byte, 1)
75
76 // special path for engines which needs to stop before executing
77 // container process
78 if obj, ok := e.Operations.(interface {
79 PreStartProcess(context.Context, int, net.Conn, chan error) error
80 }); ok {
81 _, err := conn.Read(data)
82 if err != nil {
83 if err != io.EOF {
84 fatalChan <- fmt.Errorf("error while reading master socket data: %s", err)
85 return
86 }
87 // EOF means something goes wrong in stage 2, don't send error via
88 // fatalChan, error will be reported by stage 2 and the process
89 // status will be set accordingly via MonitorContainer method below
90 sylog.Debugf("stage 2 process was interrupted, waiting status")
91 return
92 } else if data[0] == 'f' {
93 // StartProcess reported an error in stage 2, don't send error via
94 // fatalChan, error will be reported by stage 2 and the process
95 // status will be set accordingly via MonitorContainer method below
96 sylog.Debugf("stage 2 process reported an error, waiting status")
97 return
98 }
99 if err := obj.PreStartProcess(ctx, containerPid, conn, fatalChan); err != nil {
100 fatalChan <- fmt.Errorf("pre start process failed: %s", err)
101 return
102 }
103 }
104 // wait container process execution, EOF means container process
105 // was executed and master socket was closed by stage 2. If data
106 // byte sent is equal to 'f', it means an error occurred in
107 // StartProcess, just return by waiting error and process status
108 _, err = conn.Read(data)
109 if (err != nil && err != io.EOF) || data[0] == 'f' {
110 sylog.Debugf("stage 2 process reported an error, waiting status")
111 return
112 }
113
114 err = e.PostStartProcess(ctx, containerPid)
115 if err != nil {
116 fatalChan <- fmt.Errorf("post start process failed: %s", err)
117 return

Callers 2

MasterFunction · 0.85
TestStartContainerFunction · 0.85

Calls 5

DebugfFunction · 0.92
PreStartProcessMethod · 0.80
PostStartProcessMethod · 0.65
CloseMethod · 0.45
ReadMethod · 0.45

Tested by 1

TestStartContainerFunction · 0.68