1// +build !windows 2 3/* 4Copyright 2019 The Kubernetes Authors. 5 6Licensed under the Apache License, Version 2.0 (the "License"); 7you may not use this file except in compliance with the License. 8You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12Unless required by applicable law or agreed to in writing, software 13distributed under the License is distributed on an "AS IS" BASIS, 14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15See the License for the specific language governing permissions and 16limitations under the License. 17*/ 18 19package mount 20 21import ( 22 "io/ioutil" 23 "os" 24 "path/filepath" 25 "reflect" 26 "testing" 27) 28 29func writeFile(content string) (string, string, error) { 30 tempDir, err := ioutil.TempDir("", "mounter_shared_test") 31 if err != nil { 32 return "", "", err 33 } 34 filename := filepath.Join(tempDir, "mountinfo") 35 err = ioutil.WriteFile(filename, []byte(content), 0600) 36 if err != nil { 37 os.RemoveAll(tempDir) 38 return "", "", err 39 } 40 return tempDir, filename, nil 41} 42 43func TestParseMountInfo(t *testing.T) { 44 info := 45 `62 0 253:0 / / rw,relatime shared:1 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered 4678 62 0:41 / /tmp rw,nosuid,nodev shared:30 - tmpfs tmpfs rw,seclabel 4780 62 0:42 / /var/lib/nfs/rpc_pipefs rw,relatime shared:31 - rpc_pipefs sunrpc rw 4882 62 0:43 / /var/lib/foo rw,relatime shared:32 - tmpfs tmpfs rw 4983 63 0:44 / /var/lib/bar rw,relatime - tmpfs tmpfs rw 50227 62 253:0 /var/lib/docker/devicemapper /var/lib/docker/devicemapper rw,relatime - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered 51224 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 5276 17 8:1 / /mnt/stateful_partition rw,nosuid,nodev,noexec,relatime - ext4 /dev/sda1 rw,commit=30,data=ordered 5380 17 8:1 /var /var rw,nosuid,nodev,noexec,relatime shared:30 - ext4 /dev/sda1 rw,commit=30,data=ordered 54189 80 8:1 /var/lib/kubelet /var/lib/kubelet rw,relatime shared:30 - ext4 /dev/sda1 rw,commit=30,data=ordered 55818 77 8:40 / /var/lib/kubelet/pods/c25464af-e52e-11e7-ab4d-42010a800002/volumes/kubernetes.io~gce-pd/vol1 rw,relatime shared:290 - ext4 /dev/sdc rw,data=ordered 56819 78 8:48 / /var/lib/kubelet/pods/c25464af-e52e-11e7-ab4d-42010a800002/volumes/kubernetes.io~gce-pd/vol1 rw,relatime shared:290 - ext4 /dev/sdd rw,data=ordered 57900 100 8:48 /dir1 /var/lib/kubelet/pods/c25464af-e52e-11e7-ab4d-42010a800002/volume-subpaths/vol1/subpath1/0 rw,relatime shared:290 - ext4 /dev/sdd rw,data=ordered 58901 101 8:1 /dir1 /var/lib/kubelet/pods/c25464af-e52e-11e7-ab4d-42010a800002/volume-subpaths/vol1/subpath1/1 rw,relatime shared:290 - ext4 /dev/sdd rw,data=ordered 59902 102 8:1 /var/lib/kubelet/pods/d4076f24-e53a-11e7-ba15-42010a800002/volumes/kubernetes.io~empty-dir/vol1/dir1 /var/lib/kubelet/pods/d4076f24-e53a-11e7-ba15-42010a800002/volume-subpaths/vol1/subpath1/0 rw,relatime shared:30 - ext4 /dev/sda1 rw,commit=30,data=ordered 60903 103 8:1 /var/lib/kubelet/pods/d4076f24-e53a-11e7-ba15-42010a800002/volumes/kubernetes.io~empty-dir/vol2/dir1 /var/lib/kubelet/pods/d4076f24-e53a-11e7-ba15-42010a800002/volume-subpaths/vol1/subpath1/1 rw,relatime shared:30 - ext4 /dev/sda1 rw,commit=30,data=ordered 61178 25 253:0 /etc/bar /var/lib/kubelet/pods/12345/volume-subpaths/vol1/subpath1/0 rw,relatime shared:1 - ext4 /dev/sdb2 rw,errors=remount-ro,data=ordered 62698 186 0:41 /tmp1/dir1 /var/lib/kubelet/pods/41135147-e697-11e7-9342-42010a800002/volume-subpaths/vol1/subpath1/0 rw shared:26 - tmpfs tmpfs rw 63918 77 8:50 / /var/lib/kubelet/pods/2345/volumes/kubernetes.io~gce-pd/vol1 rw,relatime shared:290 - ext4 /dev/sdc rw,data=ordered 64919 78 8:58 / /var/lib/kubelet/pods/2345/volumes/kubernetes.io~gce-pd/vol1 rw,relatime shared:290 - ext4 /dev/sdd rw,data=ordered 65920 100 8:50 /dir1 /var/lib/kubelet/pods/2345/volume-subpaths/vol1/subpath1/0 rw,relatime shared:290 - ext4 /dev/sdc rw,data=ordered 66150 23 1:58 / /media/nfs_vol rw,relatime shared:89 - nfs4 172.18.4.223:/srv/nfs rw,vers=4.0,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=172.18.4.223,local_lock=none,addr=172.18.4.223 67151 24 1:58 / /media/nfs_bindmount rw,relatime shared:89 - nfs4 172.18.4.223:/srv/nfs/foo rw,vers=4.0,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=172.18.4.223,local_lock=none,addr=172.18.4.223 68134 23 0:58 / /var/lib/kubelet/pods/43219158-e5e1-11e7-a392-0e858b8eaf40/volumes/kubernetes.io~nfs/nfs1 rw,relatime shared:89 - nfs4 172.18.4.223:/srv/nfs rw,vers=4.0,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=172.18.4.223,local_lock=none,addr=172.18.4.223 69187 23 0:58 / /var/lib/kubelet/pods/1fc5ea21-eff4-11e7-ac80-0e858b8eaf40/volumes/kubernetes.io~nfs/nfs2 rw,relatime shared:96 - nfs4 172.18.4.223:/srv/nfs2 rw,vers=4.0,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=172.18.4.223,local_lock=none,addr=172.18.4.223 70188 24 0:58 / /var/lib/kubelet/pods/43219158-e5e1-11e7-a392-0e858b8eaf40/volume-subpaths/nfs1/subpath1/0 rw,relatime shared:89 - nfs4 172.18.4.223:/srv/nfs/foo rw,vers=4.0,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=172.18.4.223,local_lock=none,addr=172.18.4.223 71347 60 0:71 / /var/lib/kubelet/pods/13195d46-f9fa-11e7-bbf1-5254007a695a/volumes/kubernetes.io~nfs/vol2 rw,relatime shared:170 - nfs 172.17.0.3:/exports/2 rw,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=172.17.0.3,mountvers=3,mountport=20048,mountproto=udp,local_lock=none,addr=172.17.0.3 72222 24 253:0 /tmp/src /mnt/dst rw,relatime shared:1 - ext4 /dev/mapper/vagrant--vg-root rw,errors=remount-ro,data=ordered 7328 18 0:24 / /sys/fs/cgroup ro,nosuid,nodev,noexec shared:9 - tmpfs tmpfs ro,mode=755 7429 28 0:25 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime shared:10 - cgroup cgroup rw,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd 7531 28 0:27 / /sys/fs/cgroup/cpuset rw,nosuid,nodev,noexec,relatime shared:13 - cgroup cgroup rw,cpuset 7632 28 0:28 / /sys/fs/cgroup/cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:14 - cgroup cgroup rw,cpu,cpuacct 7733 28 0:29 / /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime shared:15 - cgroup cgroup rw,freezer 7834 28 0:30 / /sys/fs/cgroup/net_cls,net_prio rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,net_cls,net_prio 7935 28 0:31 / /sys/fs/cgroup/pids rw,nosuid,nodev,noexec,relatime shared:17 - cgroup cgroup rw,pids 8036 28 0:32 / /sys/fs/cgroup/devices rw,nosuid,nodev,noexec,relatime shared:18 - cgroup cgroup rw,devices 8137 28 0:33 / /sys/fs/cgroup/hugetlb rw,nosuid,nodev,noexec,relatime shared:19 - cgroup cgroup rw,hugetlb 8238 28 0:34 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:20 - cgroup cgroup rw,blkio 8339 28 0:35 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime shared:21 - cgroup cgroup rw,memory 8440 28 0:36 / /sys/fs/cgroup/perf_event rw,nosuid,nodev,noexec,relatime shared:22 - cgroup cgroup rw,perf_event 85` 86 tempDir, filename, err := writeFile(info) 87 if err != nil { 88 t.Fatalf("cannot create temporary file: %v", err) 89 } 90 defer os.RemoveAll(tempDir) 91 92 tests := []struct { 93 name string 94 id int 95 expectedInfo MountInfo 96 }{ 97 { 98 "simple bind mount", 99 189, 100 MountInfo{ 101 ID: 189, 102 ParentID: 80, 103 MajorMinor: "8:1", 104 Root: "/var/lib/kubelet", 105 Source: "/dev/sda1", 106 MountPoint: "/var/lib/kubelet", 107 OptionalFields: []string{"shared:30"}, 108 FsType: "ext4", 109 MountOptions: []string{"rw", "relatime"}, 110 SuperOptions: []string{"rw", "commit=30", "data=ordered"}, 111 }, 112 }, 113 { 114 "bind mount a directory", 115 222, 116 MountInfo{ 117 ID: 222, 118 ParentID: 24, 119 MajorMinor: "253:0", 120 Root: "/tmp/src", 121 Source: "/dev/mapper/vagrant--vg-root", 122 MountPoint: "/mnt/dst", 123 OptionalFields: []string{"shared:1"}, 124 FsType: "ext4", 125 MountOptions: []string{"rw", "relatime"}, 126 SuperOptions: []string{"rw", "errors=remount-ro", "data=ordered"}, 127 }, 128 }, 129 { 130 "more than one optional fields", 131 224, 132 MountInfo{ 133 ID: 224, 134 ParentID: 62, 135 MajorMinor: "253:0", 136 Root: "/var/lib/docker/devicemapper/test/shared", 137 Source: "/dev/mapper/ssd-root", 138 MountPoint: "/var/lib/docker/devicemapper/test/shared", 139 OptionalFields: []string{"master:1", "shared:44"}, 140 FsType: "ext4", 141 MountOptions: []string{"rw", "relatime"}, 142 SuperOptions: []string{"rw", "seclabel", "data=ordered"}, 143 }, 144 }, 145 { 146 "cgroup-mountpoint", 147 28, 148 MountInfo{ 149 ID: 28, 150 ParentID: 18, 151 MajorMinor: "0:24", 152 Root: "/", 153 Source: "tmpfs", 154 MountPoint: "/sys/fs/cgroup", 155 OptionalFields: []string{"shared:9"}, 156 FsType: "tmpfs", 157 MountOptions: []string{"ro", "nosuid", "nodev", "noexec"}, 158 SuperOptions: []string{"ro", "mode=755"}, 159 }, 160 }, 161 { 162 "cgroup-subsystem-systemd-mountpoint", 163 29, 164 MountInfo{ 165 ID: 29, 166 ParentID: 28, 167 MajorMinor: "0:25", 168 Root: "/", 169 Source: "cgroup", 170 MountPoint: "/sys/fs/cgroup/systemd", 171 OptionalFields: []string{"shared:10"}, 172 FsType: "cgroup", 173 MountOptions: []string{"rw", "nosuid", "nodev", "noexec", "relatime"}, 174 SuperOptions: []string{"rw", "xattr", "release_agent=/lib/systemd/systemd-cgroups-agent", "name=systemd"}, 175 }, 176 }, 177 { 178 "cgroup-subsystem-cpuset-mountpoint", 179 31, 180 MountInfo{ 181 ID: 31, 182 ParentID: 28, 183 MajorMinor: "0:27", 184 Root: "/", 185 Source: "cgroup", 186 MountPoint: "/sys/fs/cgroup/cpuset", 187 OptionalFields: []string{"shared:13"}, 188 FsType: "cgroup", 189 MountOptions: []string{"rw", "nosuid", "nodev", "noexec", "relatime"}, 190 SuperOptions: []string{"rw", "cpuset"}, 191 }, 192 }, 193 } 194 195 infos, err := ParseMountInfo(filename) 196 if err != nil { 197 t.Fatalf("Cannot parse %s: %s", filename, err) 198 } 199 200 for _, test := range tests { 201 found := false 202 for _, info := range infos { 203 if info.ID == test.id { 204 found = true 205 if !reflect.DeepEqual(info, test.expectedInfo) { 206 t.Errorf("Test case %q:\n expected: %+v\n got: %+v", test.name, test.expectedInfo, info) 207 } 208 break 209 } 210 } 211 if !found { 212 t.Errorf("Test case %q: mountPoint %d not found", test.name, test.id) 213 } 214 } 215} 216