MCPcopy Index your code
hub / github.com/opencontainers/runc / pivotRoot

Function pivotRoot

libcontainer/rootfs_linux.go:1138–1187  ·  view source on GitHub ↗

pivotRoot will call pivot_root such that rootfs becomes the new root filesystem, and everything else is cleaned up.

(root *os.File)

Source from the content-addressed store, hash-verified

1136// pivotRoot will call pivot_root such that rootfs becomes the new root
1137// filesystem, and everything else is cleaned up.
1138func pivotRoot(root *os.File) error {
1139 // While the documentation may claim otherwise, pivot_root(".", ".") is
1140 // actually valid. What this results in is / being the new root but
1141 // /proc/self/cwd being the old root. Since we can play around with the cwd
1142 // with pivot_root this allows us to pivot without creating directories in
1143 // the rootfs. Shout-outs to the LXC developers for giving us this idea.
1144
1145 oldroot, err := linux.Open("/", unix.O_DIRECTORY|unix.O_RDONLY|unix.O_PATH, 0)
1146 if err != nil {
1147 return err
1148 }
1149 defer unix.Close(oldroot)
1150
1151 // Change to the new root so that the pivot_root actually acts on it.
1152 if err := unix.Fchdir(int(root.Fd())); err != nil {
1153 return &os.PathError{Op: "chdir", Path: root.Name(), Err: err}
1154 }
1155
1156 if err := unix.PivotRoot(".", "."); err != nil {
1157 return &os.PathError{Op: "pivot_root", Path: ".", Err: err}
1158 }
1159
1160 // Currently our "." is oldroot (according to the current kernel code).
1161 // However, purely for safety, we will fchdir(oldroot) since there isn't
1162 // really any guarantee from the kernel what /proc/self/cwd will be after a
1163 // pivot_root(2).
1164
1165 if err := unix.Fchdir(oldroot); err != nil {
1166 return &os.PathError{Op: "fchdir", Path: "fd " + strconv.Itoa(oldroot), Err: err}
1167 }
1168
1169 // Make oldroot rslave to make sure our unmounts don't propagate to the
1170 // host (and thus bork the machine). We don't use rprivate because this is
1171 // known to cause issues due to races where we still have a reference to a
1172 // mount while a process in the host namespace are trying to operate on
1173 // something they think has no mounts (devicemapper in particular).
1174 if err := mount("", ".", "", unix.MS_SLAVE|unix.MS_REC, ""); err != nil {
1175 return err
1176 }
1177 // Perform the unmount. MNT_DETACH allows us to unmount /proc/self/cwd.
1178 if err := unmount(".", unix.MNT_DETACH); err != nil {
1179 return err
1180 }
1181
1182 // Switch back to our shiny new root.
1183 if err := unix.Chdir("/"); err != nil {
1184 return &os.PathError{Op: "chdir", Path: "/", Err: err}
1185 }
1186 return nil
1187}
1188
1189func msMoveRoot(rootfs string) error {
1190 // Before we move the root and chroot we have to mask all "full" sysfs and

Callers 1

prepareRootfsFunction · 0.85

Calls 4

OpenFunction · 0.92
mountFunction · 0.85
unmountFunction · 0.85
CloseMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…