func (fs *MemFS) Checkpoint(newRoot string, sources []string) error {
	if len(sources) == 0 {
		return nil
	}
	resolvedSources := []string{}
	for _, src := range sources {
		if matches, err := filepath.Glob(src); err != nil || len(matches) == 0 {
			resolvedSources = append(resolvedSources, src)
		} else {
			resolvedSources = append(resolvedSources, matches...)
		}
	}
	log.Infof("* Moving directories %v to %s", sources, newRoot)
	for _, src := range resolvedSources {
		if !filepath.IsAbs(src) {
			src = filepath.Join(fs.tree.src, src)
		}
		trimmedSrc, err := pathutils.TrimRoot(src, fs.tree.src)
		if err != nil {
			return fmt.Errorf("trim src %s: %s", src, err)
		}
		dst := filepath.Join(newRoot, trimmedSrc)
		sourceInfo, err := os.Stat(src)
		if err != nil {
			return fmt.Errorf("stat %s: %s", src, err)
		}
		fi, err := os.Lstat(src)
		if err != nil {
			return fmt.Errorf("lstat %s: %s", src, err)
		}
		stat := utils.FileInfoStat(fi)
		copier := fileio.NewCopier(fs.blacklist,
			fileio.WithDstDirOwner(int(stat.Uid), int(stat.Gid), false))
		if sourceInfo.IsDir() {
			if err := copier.CopyDir(src, dst); err != nil {
				return fmt.Errorf("copy dir %s: %s", src, err)
			}
		} else {
			if err := copier.CopyFile(src, dst); err != nil {
				return fmt.Errorf("copy file %s: %s", src, err)
			}
		}
	}
	return nil
}
Checkpoint relocates the given src files & directories to the given newRoot.
package snapshot
import (
	"archive/tar"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"
	"syscall"
	"time"
	"github.com/andres-erbsen/clock"
	"github.com/uber/makisu/lib/docker/image"
	"github.com/uber/makisu/lib/fileio"
	"github.com/uber/makisu/lib/log"
	"github.com/uber/makisu/lib/mountutils"
	"github.com/uber/makisu/lib/pathutils"
	"github.com/uber/makisu/lib/tario"
	"github.com/uber/makisu/lib/utils"
)
type memFSNode struct {
	*contentMemFile                        
	children        map[string]*memFSNode  
}
func newMemFSNode(mf *contentMemFile) *memFSNode {
	return &memFSNode{mf, make(map[string]*memFSNode)}
}
func (n *memFSNode) isOnDisk() (bool, error) {
	if _, err := os.Lstat(n.src); err == nil {
		return true, nil
	} else if os.IsNotExist(err) {
		return false, nil
	} else {
		return false, err
	}
}
type MemFS struct {
	clk  clock.Clock
	tree *memFSNode
	blacklist []string
	layers    []*memLayer
}
func NewMemFS(clk clock.Clock, root string, blacklist []string) (*MemFS, error) {
	fi, err := os.Lstat(root)
	if err != nil {
		return nil, fmt.Errorf("unable to stat root dir: %s", root)
	}
	hdr, err := newMemLayer().createHeader(root, root, "/", fi)
	if err != nil {
		return nil, fmt.Errorf("unable to create root header")
	}
	return &MemFS{
		clk:       clk,
		tree:      newMemFSNode(newContentMemFile(root, "/", hdr)),
		blacklist: blacklist,
	}, nil
}
func (fs *MemFS) Reset() {
	fs.tree.children = make(map[string]*memFSNode)
}