diff --git a/staging/src/k8s.io/mount-utils/mount_helper_unix.go b/staging/src/k8s.io/mount-utils/mount_helper_unix.go index 013c688a2a6..cb8732fce74 100644 --- a/staging/src/k8s.io/mount-utils/mount_helper_unix.go +++ b/staging/src/k8s.io/mount-utils/mount_helper_unix.go @@ -136,7 +136,7 @@ func ParseMountInfo(filename string) ([]MountInfo, error) { Minor: minor, Root: fields[3], MountPoint: fields[4], - MountOptions: strings.Split(fields[5], ","), + MountOptions: splitMountOptions(fields[5]), } // All fields until "-" are "optional fields". i := 6 @@ -150,12 +150,26 @@ func ParseMountInfo(filename string) ([]MountInfo, error) { } info.FsType = fields[i] info.Source = fields[i+1] - info.SuperOptions = strings.Split(fields[i+2], ",") + info.SuperOptions = splitMountOptions(fields[i+2]) infos = append(infos, info) } return infos, nil } +// splitMountOptions parses comma-separated list of mount options into an array. +// It respects double quotes - commas in them are not considered as the option separator. +func splitMountOptions(s string) []string { + inQuotes := false + list := strings.FieldsFunc(s, func(r rune) bool { + if r == '"' { + inQuotes = !inQuotes + } + // Report a new field only when outside of double quotes. + return r == ',' && !inQuotes + }) + return list +} + // isMountPointMatch returns true if the path in mp is the same as dir. // Handles case where mountpoint dir has been renamed due to stale NFS mount. func isMountPointMatch(mp MountPoint, dir string) bool { diff --git a/staging/src/k8s.io/mount-utils/mount_helper_unix_test.go b/staging/src/k8s.io/mount-utils/mount_helper_unix_test.go index e63e30aeca2..6fbc79e3e4d 100644 --- a/staging/src/k8s.io/mount-utils/mount_helper_unix_test.go +++ b/staging/src/k8s.io/mount-utils/mount_helper_unix_test.go @@ -83,6 +83,7 @@ func TestParseMountInfo(t *testing.T) { 38 28 0:34 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:20 - cgroup cgroup rw,blkio 39 28 0:35 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime shared:21 - cgroup cgroup rw,memory 40 28 0:36 / /sys/fs/cgroup/perf_event rw,nosuid,nodev,noexec,relatime shared:22 - cgroup cgroup rw,perf_event +761 60 8:0 / /var/lib/kubelet/plugins/kubernetes.io/iscsi/iface-default/127.0.0.1:3260-iqn.2003-01.org.linux-iscsi.f21.x8664:sn.4b0aae584f7c-lun-0 rw,relatime shared:421 - ext4 /dev/sda rw,context="system_u:object_r:container_file_t:s0:c314,c894",data=ordered ` tempDir, filename, err := writeFile(info) if err != nil { @@ -197,6 +198,23 @@ func TestParseMountInfo(t *testing.T) { SuperOptions: []string{"rw", "cpuset"}, }, }, + { + "mount option with commas inside quotes", + 761, + MountInfo{ + ID: 761, + ParentID: 60, + Major: 8, + Minor: 0, + Root: "/", + Source: "/dev/sda", + MountPoint: "/var/lib/kubelet/plugins/kubernetes.io/iscsi/iface-default/127.0.0.1:3260-iqn.2003-01.org.linux-iscsi.f21.x8664:sn.4b0aae584f7c-lun-0", + OptionalFields: []string{"shared:421"}, + FsType: "ext4", + MountOptions: []string{"rw", "relatime"}, + SuperOptions: []string{"rw", "context=\"system_u:object_r:container_file_t:s0:c314,c894\"", "data=ordered"}, + }, + }, } infos, err := ParseMountInfo(filename)