startSubcontainer starts a child container. It returns the thread group ID of the newly created process. Used FDs are either closed or released. It's safe for the caller to close any remaining files upon return.
(spec *specs.Spec, conf *config.Config, cid string, stdioFDs, goferFDs, goferFilestoreFDs []*fd.FD, devGoferFD *fd.FD, goferMountConfs []specutils.GoferMountConf, rootfsUpperTarFD *fd.FD)
| 1189 | // the newly created process. Used FDs are either closed or released. It's safe |
| 1190 | // for the caller to close any remaining files upon return. |
| 1191 | func (l *Loader) startSubcontainer(spec *specs.Spec, conf *config.Config, cid string, stdioFDs, goferFDs, goferFilestoreFDs []*fd.FD, devGoferFD *fd.FD, goferMountConfs []specutils.GoferMountConf, rootfsUpperTarFD *fd.FD) error { |
| 1192 | l.mu.Lock() |
| 1193 | defer l.mu.Unlock() |
| 1194 | |
| 1195 | cu := cleanup.Make(func() { |
| 1196 | l.failedToStart[cid] = struct{}{} // +checklocksignore: l.mu is locked above |
| 1197 | }) |
| 1198 | defer cu.Clean() |
| 1199 | |
| 1200 | ep := l.processes[execID{cid: cid}] |
| 1201 | if ep == nil { |
| 1202 | return fmt.Errorf("trying to start a deleted container %q", cid) |
| 1203 | } |
| 1204 | |
| 1205 | // Create credentials. We reuse the root user namespace because the |
| 1206 | // sentry currently supports only 1 mount namespace, which is tied to a |
| 1207 | // single user namespace. Thus we must run in the same user namespace |
| 1208 | // to access mounts. |
| 1209 | creds := getRootCredentials(spec, conf, l.k.RootUserNamespace()) |
| 1210 | if creds == nil { |
| 1211 | return fmt.Errorf("getting root credentials") |
| 1212 | } |
| 1213 | var pidns *kernel.PIDNamespace |
| 1214 | if ns, ok := specutils.GetNS(specs.PIDNamespace, spec); ok { |
| 1215 | if ns.Path != "" { |
| 1216 | for _, p := range l.processes { |
| 1217 | if ns.Path == p.pidnsPath { |
| 1218 | log.Debugf("Joining PID namespace named %q", ns.Path) |
| 1219 | pidns = p.tg.PIDNamespace() |
| 1220 | break |
| 1221 | } |
| 1222 | } |
| 1223 | } |
| 1224 | if pidns == nil { |
| 1225 | log.Warningf("PID namespace %q not found, running in new PID namespace", ns.Path) |
| 1226 | pidns = l.k.RootPIDNamespace().NewChild(l.k.SupervisorContext(), l.k, l.k.RootUserNamespace()) |
| 1227 | } |
| 1228 | ep.pidnsPath = ns.Path |
| 1229 | } else { |
| 1230 | pidns = l.k.RootPIDNamespace() |
| 1231 | } |
| 1232 | |
| 1233 | containerName := l.registerContainerLocked(spec, cid) |
| 1234 | l.k.RegisterContainerName(cid, containerName) |
| 1235 | info := &containerInfo{ |
| 1236 | cid: cid, |
| 1237 | containerName: containerName, |
| 1238 | conf: conf, |
| 1239 | spec: spec, |
| 1240 | goferFDs: goferFDs, |
| 1241 | devGoferFD: devGoferFD, |
| 1242 | goferFilestoreFDs: goferFilestoreFDs, |
| 1243 | goferMountConfs: goferMountConfs, |
| 1244 | nvidiaHostSettings: l.root.nvidiaHostSettings, |
| 1245 | nvproxyDevInfo: l.root.nvproxyDevInfo, |
| 1246 | rootfsUpperTarFD: rootfsUpperTarFD, |
| 1247 | } |
| 1248 | var err error |
no test coverage detected