func isNetworkFileSystem(fsMagic graphdriver.FsMagic) bool {
	switch fsMagic {
	case graphdriver.FsMagicNfsFs, graphdriver.FsMagicSmbFs, graphdriver.FsMagicAcfs,
		graphdriver.FsMagicAfs, graphdriver.FsMagicCephFs, graphdriver.FsMagicCIFS,
		graphdriver.FsMagicFHGFSFs, graphdriver.FsMagicGPFS, graphdriver.FsMagicIBRIX,
		graphdriver.FsMagicKAFS, graphdriver.FsMagicLUSTRE, graphdriver.FsMagicNCP,
		graphdriver.FsMagicNFSD, graphdriver.FsMagicOCFS2, graphdriver.FsMagicPANFS,
		graphdriver.FsMagicPRLFS, graphdriver.FsMagicSMB2, graphdriver.FsMagicSNFS,
		graphdriver.FsMagicVBOXSF, graphdriver.FsMagicVXFS:
		return true
	}
	return false
}
isNetworkFileSystem checks if the specified file system is supported by native overlay
as backing store when running in a user namespace.
package overlay
import (
	"bytes"
	"encoding/base64"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
	"syscall"
	graphdriver "github.com/containers/storage/drivers"
	"github.com/containers/storage/drivers/overlayutils"
	"github.com/containers/storage/drivers/quota"
	"github.com/containers/storage/pkg/archive"
	"github.com/containers/storage/pkg/chrootarchive"
	"github.com/containers/storage/pkg/directory"
	"github.com/containers/storage/pkg/fsutils"
	"github.com/containers/storage/pkg/idtools"
	"github.com/containers/storage/pkg/locker"
	"github.com/containers/storage/pkg/mount"
	"github.com/containers/storage/pkg/parsers"
	"github.com/containers/storage/pkg/system"
	"github.com/containers/storage/pkg/unshare"
	units "github.com/docker/go-units"
	"github.com/hashicorp/go-multierror"
	digest "github.com/opencontainers/go-digest"
	"github.com/opencontainers/runc/libcontainer/userns"
	"github.com/opencontainers/selinux/go-selinux"
	"github.com/opencontainers/selinux/go-selinux/label"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"github.com/vbatts/tar-split/tar/storage"
	"golang.org/x/sys/unix"
)
var (
	untar = chrootarchive.UntarUncompressed
)
const (
	defaultPerms     = os.FileMode(0555)
	selinuxLabelTest = "system_u:object_r:container_file_t:s0"
)
const (
	linkDir   = "l"
	lowerFile = "lower"
	maxDepth  = 128
	idLength = 26
)
type overlayOptions struct {
	imageStores       []string
	layerStores       []additionalLayerStore
	quota             quota.Quota
	mountProgram      string
	skipMountHome     bool
	mountOptions      string
	ignoreChownErrors bool
	forceMask         *os.FileMode
}
type Driver struct {
	name             string
	home             string
	runhome          string
	uidMaps          []idtools.IDMap
	gidMaps          []idtools.IDMap
	ctr              *graphdriver.RefCounter
	quotaCtl         *quota.Control
	options          overlayOptions
	naiveDiff        graphdriver.DiffDriver
	supportsDType    bool
	supportsVolatile *bool
	usingMetacopy    bool
	locker           *locker.Locker
}
type additionalLayerStore struct {
	path string
	withReference bool
}
var (
	backingFs             = "<unknown>"
	projectQuotaSupported = false
	useNaiveDiffLock sync.Once
	useNaiveDiffOnly bool
)
func init() {
	graphdriver.Register("overlay", Init)
	graphdriver.Register("overlay2", Init)
}
func hasMetacopyOption(opts []string) bool {
	for _, s := range opts {
		if s == "metacopy=on" {
			return true
		}
	}
	return false
}
func hasVolatileOption(opts []string) bool {
	for _, s := range opts {
		if s == "volatile" {
			return true
		}
	}
	return false
}
func getMountProgramFlagFile(path string) string {
	return filepath.Join(path, ".has-mount-program")
}
func checkSupportVolatile(home, runhome string) (bool, error) {
	feature := fmt.Sprintf("volatile")
	volatileCacheResult, _, err := cachedFeatureCheck(runhome, feature)
	var usingVolatile bool
	if err == nil {
		if volatileCacheResult {
			logrus.Debugf("Cached value indicated that volatile is being used")
		} else {
			logrus.Debugf("Cached value indicated that volatile is not being used")
		}
		usingVolatile = volatileCacheResult
	} else {
		usingVolatile, err = doesVolatile(home)
		if err == nil {
			if usingVolatile {
				logrus.Debugf("overlay: test mount indicated that volatile is being used")
			} else {
				logrus.Debugf("overlay: test mount indicated that volatile is not being used")
			}
			if err = cachedFeatureRecord(runhome, feature, usingVolatile, ""); err != nil {
				return false, errors.Wrap(err, "recording volatile-being-used status")
			}
		}
	}
	return usingVolatile, nil
}
func checkAndRecordOverlaySupport(fsMagic graphdriver.FsMagic, home, runhome string) (bool, error) {
	var supportsDType bool
	if os.Geteuid() != 0 {
		return false, nil
	}
	feature := "overlay"
	overlayCacheResult, overlayCacheText, err := cachedFeatureCheck(runhome, feature)
	if err == nil {
		if overlayCacheResult {
			logrus.Debugf("Cached value indicated that overlay is supported")
		} else {
			logrus.Debugf("Cached value indicated that overlay is not supported")
		}
		supportsDType = overlayCacheResult
		if !supportsDType {
			return false, errors.New(overlayCacheText)
		}
	} else {
		supportsDType, err = supportsOverlay(home, fsMagic, 0, 0)
		if err != nil {
			os.Remove(filepath.Join(home, linkDir))
			os.Remove(home)
			patherr, ok := err.(*os.PathError)
			if ok && patherr.Err == syscall.ENOSPC {
				return false, err
			}
			err = errors.Wrap(err, "kernel does not support overlay fs")
			if err2 := cachedFeatureRecord(runhome, feature, false, err.Error()); err2 != nil {
				return false, errors.Wrapf(err2, "recording overlay not being supported (%v)", err)
			}
			return false, err
		}
		if err = cachedFeatureRecord(runhome, feature, supportsDType, ""); err != nil {
			return false, errors.Wrap(err, "recording overlay support status")
		}
	}
	return supportsDType, nil
}
func (d *Driver) getSupportsVolatile() (bool, error) {
	if d.supportsVolatile != nil {
		return *d.supportsVolatile, nil
	}
	supportsVolatile, err := checkSupportVolatile(d.home, d.runhome)
	if err != nil {
		return false, err
	}
	d.supportsVolatile = &supportsVolatile
	return supportsVolatile, nil
}