mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-19 18:02:01 +00:00
Split MajorMinor into two fields
this reflects what is in the docker/docker/pkg/mount API. makes it easier to port additional code to out API.
This commit is contained in:
parent
241ff06ccc
commit
0f9a3f756b
@ -61,8 +61,12 @@ type MountInfo struct {
|
||||
ID int
|
||||
// The ID of the parent mount (or of self for the root of this mount namespace's mount tree).
|
||||
ParentID int
|
||||
// The value of `st_dev` for files on this filesystem.
|
||||
MajorMinor string
|
||||
// Major indicates one half of the device ID which identifies the device class
|
||||
// (parsed from `st_dev` for files on this filesystem).
|
||||
Major int
|
||||
// Minor indicates one half of the device ID which identifies a specific
|
||||
// instance of device (parsed from `st_dev` for files on this filesystem).
|
||||
Minor int
|
||||
// The pathname of the directory in the filesystem which forms the root of this mount.
|
||||
Root string
|
||||
// Mount source, filesystem-specific information. e.g. device, tmpfs name.
|
||||
@ -106,10 +110,24 @@ func ParseMountInfo(filename string) ([]MountInfo, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mm := strings.Split(fields[2], ":")
|
||||
if len(mm) != 2 {
|
||||
return nil, fmt.Errorf("parsing '%s' failed: unexpected minor:major pair %s", line, mm)
|
||||
}
|
||||
major, err := strconv.Atoi(mm[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing '%s' failed: unable to parse major device id, err:%v", mm[0], err)
|
||||
}
|
||||
minor, err := strconv.Atoi(mm[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing '%s' failed: unable to parse minor device id, err:%v", mm[1], err)
|
||||
}
|
||||
|
||||
info := MountInfo{
|
||||
ID: id,
|
||||
ParentID: parentID,
|
||||
MajorMinor: fields[2],
|
||||
Major: major,
|
||||
Minor: minor,
|
||||
Root: fields[3],
|
||||
MountPoint: fields[4],
|
||||
MountOptions: strings.Split(fields[5], ","),
|
||||
|
@ -100,7 +100,8 @@ func TestParseMountInfo(t *testing.T) {
|
||||
MountInfo{
|
||||
ID: 189,
|
||||
ParentID: 80,
|
||||
MajorMinor: "8:1",
|
||||
Major: 8,
|
||||
Minor: 1,
|
||||
Root: "/var/lib/kubelet",
|
||||
Source: "/dev/sda1",
|
||||
MountPoint: "/var/lib/kubelet",
|
||||
@ -116,7 +117,8 @@ func TestParseMountInfo(t *testing.T) {
|
||||
MountInfo{
|
||||
ID: 222,
|
||||
ParentID: 24,
|
||||
MajorMinor: "253:0",
|
||||
Major: 253,
|
||||
Minor: 0,
|
||||
Root: "/tmp/src",
|
||||
Source: "/dev/mapper/vagrant--vg-root",
|
||||
MountPoint: "/mnt/dst",
|
||||
@ -132,7 +134,8 @@ func TestParseMountInfo(t *testing.T) {
|
||||
MountInfo{
|
||||
ID: 224,
|
||||
ParentID: 62,
|
||||
MajorMinor: "253:0",
|
||||
Major: 253,
|
||||
Minor: 0,
|
||||
Root: "/var/lib/docker/devicemapper/test/shared",
|
||||
Source: "/dev/mapper/ssd-root",
|
||||
MountPoint: "/var/lib/docker/devicemapper/test/shared",
|
||||
@ -148,7 +151,8 @@ func TestParseMountInfo(t *testing.T) {
|
||||
MountInfo{
|
||||
ID: 28,
|
||||
ParentID: 18,
|
||||
MajorMinor: "0:24",
|
||||
Major: 0,
|
||||
Minor: 24,
|
||||
Root: "/",
|
||||
Source: "tmpfs",
|
||||
MountPoint: "/sys/fs/cgroup",
|
||||
@ -164,7 +168,8 @@ func TestParseMountInfo(t *testing.T) {
|
||||
MountInfo{
|
||||
ID: 29,
|
||||
ParentID: 28,
|
||||
MajorMinor: "0:25",
|
||||
Major: 0,
|
||||
Minor: 25,
|
||||
Root: "/",
|
||||
Source: "cgroup",
|
||||
MountPoint: "/sys/fs/cgroup/systemd",
|
||||
@ -180,7 +185,8 @@ func TestParseMountInfo(t *testing.T) {
|
||||
MountInfo{
|
||||
ID: 31,
|
||||
ParentID: 28,
|
||||
MajorMinor: "0:27",
|
||||
Major: 0,
|
||||
Minor: 27,
|
||||
Root: "/",
|
||||
Source: "cgroup",
|
||||
MountPoint: "/sys/fs/cgroup/cpuset",
|
||||
@ -213,3 +219,98 @@ func TestParseMountInfo(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBadParseMountInfo(t *testing.T) {
|
||||
tests := []struct {
|
||||
info string
|
||||
name string
|
||||
id int
|
||||
expectedInfo *MountInfo
|
||||
error string
|
||||
}{
|
||||
{
|
||||
`224 62 253:0 /var/lib/docker/devicemapper/test/shared /var/lib/docker/devicemapper/test/shared rw,relatime master:1 shared:44 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered`,
|
||||
"good major:minor field",
|
||||
224,
|
||||
&MountInfo{
|
||||
ID: 224,
|
||||
ParentID: 62,
|
||||
Major: 253,
|
||||
Minor: 0,
|
||||
Root: "/var/lib/docker/devicemapper/test/shared",
|
||||
Source: "/dev/mapper/ssd-root",
|
||||
MountPoint: "/var/lib/docker/devicemapper/test/shared",
|
||||
OptionalFields: []string{"master:1", "shared:44"},
|
||||
FsType: "ext4",
|
||||
MountOptions: []string{"rw", "relatime"},
|
||||
SuperOptions: []string{"rw", "seclabel", "data=ordered"},
|
||||
},
|
||||
"",
|
||||
},
|
||||
{
|
||||
`224 62 /var/lib/docker/devicemapper/test/shared /var/lib/docker/devicemapper/test/shared rw,relatime master:1 shared:44 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered`,
|
||||
"missing major:minor field",
|
||||
224,
|
||||
nil,
|
||||
`parsing '224 62 /var/lib/docker/devicemapper/test/shared /var/lib/docker/devicemapper/test/shared rw,relatime master:1 shared:44 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered' failed: unexpected minor:major pair [/var/lib/docker/devicemapper/test/shared]`,
|
||||
},
|
||||
{
|
||||
`224 62 :0 /var/lib/docker/devicemapper/test/shared /var/lib/docker/devicemapper/test/shared rw,relatime master:1 shared:44 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered`,
|
||||
"empty major field",
|
||||
224,
|
||||
nil,
|
||||
`parsing '' failed: unable to parse major device id, err:strconv.Atoi: parsing "": invalid syntax`,
|
||||
},
|
||||
{
|
||||
`224 62 253: /var/lib/docker/devicemapper/test/shared /var/lib/docker/devicemapper/test/shared rw,relatime master:1 shared:44 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered`,
|
||||
"empty minor field",
|
||||
224,
|
||||
nil,
|
||||
`parsing '' failed: unable to parse minor device id, err:strconv.Atoi: parsing "": invalid syntax`,
|
||||
},
|
||||
{
|
||||
`224 62 foo:0 /var/lib/docker/devicemapper/test/shared /var/lib/docker/devicemapper/test/shared rw,relatime master:1 shared:44 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered`,
|
||||
"alphabet in major field",
|
||||
224,
|
||||
nil,
|
||||
`parsing 'foo' failed: unable to parse major device id, err:strconv.Atoi: parsing "foo": invalid syntax`,
|
||||
},
|
||||
{
|
||||
`224 62 253:bar /var/lib/docker/devicemapper/test/shared /var/lib/docker/devicemapper/test/shared rw,relatime master:1 shared:44 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered`,
|
||||
"alphabet in minor field",
|
||||
224,
|
||||
nil,
|
||||
`parsing 'bar' failed: unable to parse minor device id, err:strconv.Atoi: parsing "bar": invalid syntax`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
tempDir, filename, err := writeFile(test.info)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot create temporary file: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
infos, err := ParseMountInfo(filename)
|
||||
if err != nil {
|
||||
if err.Error() != test.error {
|
||||
t.Errorf("Test case %q:\n expected error: %+v\n got: %+v", test.name, test.error, err.Error())
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
found := false
|
||||
for _, info := range infos {
|
||||
if info.ID == test.id {
|
||||
found = true
|
||||
if !reflect.DeepEqual(info, *test.expectedInfo) {
|
||||
t.Errorf("Test case %q:\n expected: %+v\n got: %+v", test.name, test.expectedInfo, info)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("Test case %q: mountPoint %d not found", test.name, test.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -499,7 +499,8 @@ func SearchMountPoints(hostSource, mountInfoPath string) ([]string, error) {
|
||||
|
||||
mountID := 0
|
||||
rootPath := ""
|
||||
majorMinor := ""
|
||||
major := -1
|
||||
minor := -1
|
||||
|
||||
// Finding the underlying root path and major:minor if possible.
|
||||
// We need search in backward order because it's possible for later mounts
|
||||
@ -509,12 +510,13 @@ func SearchMountPoints(hostSource, mountInfoPath string) ([]string, error) {
|
||||
// If it's a mount point or path under a mount point.
|
||||
mountID = mis[i].ID
|
||||
rootPath = filepath.Join(mis[i].Root, strings.TrimPrefix(hostSource, mis[i].MountPoint))
|
||||
majorMinor = mis[i].MajorMinor
|
||||
major = mis[i].Major
|
||||
minor = mis[i].Minor
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if rootPath == "" || majorMinor == "" {
|
||||
if rootPath == "" || major == -1 || minor == -1 {
|
||||
return nil, fmt.Errorf("failed to get root path and major:minor for %s", hostSource)
|
||||
}
|
||||
|
||||
@ -524,7 +526,7 @@ func SearchMountPoints(hostSource, mountInfoPath string) ([]string, error) {
|
||||
// Ignore mount entry for mount source itself.
|
||||
continue
|
||||
}
|
||||
if mis[i].Root == rootPath && mis[i].MajorMinor == majorMinor {
|
||||
if mis[i].Root == rootPath && mis[i].Major == major && mis[i].Minor == minor {
|
||||
refs = append(refs, mis[i].MountPoint)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user