func parseMountEntry(entry string) (*mount, error) {
	if strings.HasPrefix(entry, "#") {  
		return nil, nil
	}
	parts := strings.Split(entry, " ")
	if len(parts) < 4 {
		return nil, fmt.Errorf("invalid format: expected at least 4 space-separated columns")
	}
	unescape := strings.NewReplacer(
		`\040`, "\040",
		`\011`, "\011",
		`\012`, "\012",
		`\134`, "\134",
	)
	return &mount{
		device:     unescape.Replace(parts[0]),
		mountPoint: unescape.Replace(parts[1]),
		fsType:     unescape.Replace(parts[2]),
		options:    unescape.Replace(parts[3]),
	}, nil
}
parseMountEntry takes a single line of /proc/mounts and returns a pointer to
a struct with corresponding fields and a nil error if parsing succeeded. The
pointer may be nil if the line is a comment. If the format is not as expected
the function returns a nil value and a non-nil error.
package volumes
import (
	"bufio"
	"bytes"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"log"
	"os"
	"strings"
	"github.com/GoogleCloudPlatform/konlet/gce-containers-startup/metadata"
	api "github.com/GoogleCloudPlatform/konlet/gce-containers-startup/types"
)
const (
	ext4FsType string = "ext4"
)
var (
	mountedVolumesPathPrefixFlag = flag.String("mounted-volumes-path-prefix", "/mnt/disks/gce-containers-mounts", "Path prefix under which mount volumes.")
	hostProcPathFlag             = flag.String("host-proc-path", "/host_proc", "Use nsenter to enter host's mount namespace specified under this path. If left empty, no namespace switch is performed (implying running outside of container.")
)
type Env struct {
	OsCommandRunner  OsCommandRunner
	MetadataProvider metadata.Provider
}
type OsCommandRunner interface {
	Run(...string) (string, error)
	MkdirAll(path string, perm os.FileMode) error
	Stat(name string) (os.FileInfo, error)
}
type VolumeHostPathAndMode struct {
	hostPath string
	readOnly bool
}
type HostPathBindConfiguration struct {
	HostPath      string
	ContainerPath string
	ReadOnly      bool
}
type mount struct {
	device     string
	mountPoint string
	fsType     string
	options    string
}
type mountOption func(*mount)
func newMount(device, mountPoint, fsType string, opts ...mountOption) mount {
	mnt := mount{device, mountPoint, fsType, ""}
	for _, opt := range opts {
		opt(&mnt)
	}
	return mnt
}
func readOnly(ro bool) mountOption {
	return func(mnt *mount) {
		var opt string
		if ro {
			opt = "ro"
		} else {
			opt = "rw"
		}
		if mnt.options == "" {
			mnt.options = opt
			return
		}
		mnt.options += ("," + opt)
	}
}
func (env Env) UnmountExistingVolumes() error {
	mounts, err := env.existingMounts()
	if err != nil {
		return fmt.Errorf("failed to list existing volumes: %v", err)
	}
	var buf bytes.Buffer
	for _, mnt := range mounts {
		if err := env.unmountDevice(mnt); err != nil {
			buf.WriteString(fmt.Sprintf("%v\n", err))
			continue
		}
		log.Printf("Unmounted %s", mnt.mountPoint)
	}
	if buf.Len() > 0 {
		msg := buf.String()
		return errors.New(msg[:len(msg)-1])  
	}
	return nil
}
func (env Env) existingMounts() ([]mount, error) {
	file, err := env.OsCommandRunner.Run(wrapToEnterHostMountNamespace("cat", "/proc/mounts")...)
	if err != nil {
		return nil, err
	}
	var mounts []mount
	scanner := bufio.NewScanner(strings.NewReader(file))
	for scanner.Scan() {
		line := scanner.Text()
		mnt, err := parseMountEntry(line)
		if err != nil || mnt == nil {
			continue
		}
		if strings.HasPrefix(mnt.mountPoint, *mountedVolumesPathPrefixFlag) {
			mounts = append(mounts, *mnt)
		}
	}
	return mounts, nil
}