MCPcopy
hub / github.com/opencontainers/runc / prepareRootfs

Function prepareRootfs

libcontainer/rootfs_linux.go:170–273  ·  view source on GitHub ↗

prepareRootfs sets up the devices, mount points, and filesystems for use inside a new mount namespace. It doesn't set anything as ro. You must call finalizeRootfs after this function to finish setting up the rootfs.

(pipe *syncSocket, iConfig *initConfig)

Source from the content-addressed store, hash-verified

168// inside a new mount namespace. It doesn't set anything as ro. You must call
169// finalizeRootfs after this function to finish setting up the rootfs.
170func prepareRootfs(pipe *syncSocket, iConfig *initConfig) (err error) {
171 config := iConfig.Config
172 if err := prepareRoot(config); err != nil {
173 return fmt.Errorf("error preparing rootfs: %w", err)
174 }
175
176 // Pre-open rootfs. NOTE that if we need to re-enable support for mounting
177 // on top of container root (see issue 5070), we will need to reopen rootFd
178 // after such mounts.
179 rootFd, err := os.OpenFile(config.Rootfs, unix.O_DIRECTORY|unix.O_CLOEXEC|unix.O_PATH, 0)
180 if err != nil {
181 return fmt.Errorf("open rootfs handle: %w", err)
182 }
183 defer rootFd.Close()
184
185 mountConfig := &mountConfig{
186 root: rootFd,
187 label: config.MountLabel,
188 cgroup2Path: iConfig.Cgroup2Path,
189 rootlessCgroups: config.RootlessCgroups,
190 cgroupns: config.Namespaces.Contains(configs.NEWCGROUP),
191 }
192 for _, m := range config.Mounts {
193 if err := setupAndMountToRootfs(pipe, config, mountConfig, m); err != nil {
194 return err
195 }
196 }
197
198 setupDev := needsSetupDev(config)
199 if setupDev {
200 if err := doSetupDev(rootFd, config); err != nil {
201 return fmt.Errorf("configuring container /dev: %w", err)
202 }
203 }
204
205 // Signal the parent to run the pre-start hooks.
206 // The hooks are run after the mounts are setup, but before we switch to the new
207 // root, so that the old root is still available in the hooks for any mount
208 // manipulations.
209 // Note that iConfig.Cwd is not guaranteed to exist here.
210 if err := syncParentHooks(pipe); err != nil {
211 return err
212 }
213
214 // The reason these operations are done here rather than in finalizeRootfs
215 // is because the console-handling code gets quite sticky if we have to set
216 // up the console before doing the pivot_root(2). This is because the
217 // Console API has to also work with the ExecIn case, which means that the
218 // API must be able to deal with being inside as well as outside the
219 // container. It's just cleaner to do this here (at the expense of the
220 // operation not being perfectly split).
221
222 if err := unix.Fchdir(int(rootFd.Fd())); err != nil {
223 return &os.PathError{Op: "chdir", Path: config.Rootfs, Err: err}
224 }
225
226 if s := iConfig.SpecState; s != nil {
227 s.Pid = unix.Getpid()

Callers 1

InitMethod · 0.85

Calls 13

prepareRootFunction · 0.85
setupAndMountToRootfsFunction · 0.85
needsSetupDevFunction · 0.85
doSetupDevFunction · 0.85
syncParentHooksFunction · 0.85
msMoveRootFunction · 0.85
pivotRootFunction · 0.85
chrootFunction · 0.85
mountFunction · 0.85
reOpenDevNullFunction · 0.85
ContainsMethod · 0.80
RunMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…