code: func setupRootfs(config *configs.Config, console *linuxConsole) (err error) {
  	if err := prepareRoot(config); err != nil {
  		return newSystemError(err)
  	}
  	for _, m := range config.Mounts {
  		for _, precmd := range m.PremountCmds {
  			if err := mountCmd(precmd); err != nil {
  				return newSystemError(err)
  			}
  		}
  		if err := mountToRootfs(m, config.Rootfs, config.MountLabel); err != nil {
  			return newSystemError(err)
  		}
  
  		for _, postcmd := range m.PostmountCmds {
  			if err := mountCmd(postcmd); err != nil {
  				return newSystemError(err)
  			}
  		}
  	}
  	if err := createDevices(config); err != nil {
  		return newSystemError(err)
  	}
  	if err := setupPtmx(config, console); err != nil {
  		return newSystemError(err)
  	}
  	if err := setupDevSymlinks(config.Rootfs); err != nil {
  		return newSystemError(err)
  	}
  	if err := syscall.Chdir(config.Rootfs); err != nil {
  		return newSystemError(err)
  	}
  	if config.NoPivotRoot {
  		err = msMoveRoot(config.Rootfs)
  	} else {
  		err = pivotRoot(config.Rootfs, config.PivotDir)
  	}
  	if err != nil {
  		return newSystemError(err)
  	}
  	if err := reOpenDevNull(config.Rootfs); err != nil {
  		return newSystemError(err)
  	}
  	if config.Readonlyfs {
  		if err := setReadonly(); err != nil {
  			return newSystemError(err)
  		}
  	}
  	syscall.Umask(0022)
  	return nil
  }
docs: // setupRootfs sets up the devices, mount points, and filesystems for use inside a
  // new mount namespace.