github.com/rigado/snapd@v2.42.5-go-mod+incompatible/gadget/device_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2019 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package gadget_test 21 22 import ( 23 "errors" 24 "io/ioutil" 25 "os" 26 "path/filepath" 27 "strings" 28 29 . "gopkg.in/check.v1" 30 31 "github.com/snapcore/snapd/dirs" 32 "github.com/snapcore/snapd/gadget" 33 "github.com/snapcore/snapd/osutil" 34 ) 35 36 type deviceSuite struct { 37 dir string 38 } 39 40 var _ = Suite(&deviceSuite{}) 41 42 func (d *deviceSuite) SetUpTest(c *C) { 43 d.dir = c.MkDir() 44 dirs.SetRootDir(d.dir) 45 46 err := os.MkdirAll(filepath.Join(d.dir, "/dev/disk/by-label"), 0755) 47 c.Assert(err, IsNil) 48 err = os.MkdirAll(filepath.Join(d.dir, "/dev/disk/by-partlabel"), 0755) 49 c.Assert(err, IsNil) 50 err = ioutil.WriteFile(filepath.Join(d.dir, "/dev/fakedevice"), []byte(""), 0644) 51 c.Assert(err, IsNil) 52 } 53 54 func (d *deviceSuite) TearDownTest(c *C) { 55 dirs.SetRootDir("/") 56 } 57 58 func (d *deviceSuite) setUpWritableFallback(c *C, mountInfo string) { 59 // setup everything for 'writable' 60 err := ioutil.WriteFile(filepath.Join(d.dir, "/dev/fakedevice0p1"), []byte(""), 0644) 61 c.Assert(err, IsNil) 62 err = os.Symlink("../../fakedevice0p1", filepath.Join(d.dir, "/dev/disk/by-label/writable")) 63 c.Assert(err, IsNil) 64 // make parent device 65 err = ioutil.WriteFile(filepath.Join(d.dir, "/dev/fakedevice0"), []byte(""), 0644) 66 c.Assert(err, IsNil) 67 // and fake /sys/block structure 68 err = os.MkdirAll(filepath.Join(d.dir, "/sys/block/fakedevice0/fakedevice0p1"), 0755) 69 c.Assert(err, IsNil) 70 71 mockProcSelfFilesystem(c, d.dir, mountInfo) 72 } 73 74 func (d *deviceSuite) TestDeviceFindByStructureName(c *C) { 75 names := []struct { 76 escaped string 77 structure string 78 }{ 79 {"foo", "foo"}, 80 {"123", "123"}, 81 {"foo\\x20bar", "foo bar"}, 82 {"foo#bar", "foo#bar"}, 83 {"Новый_том", "Новый_том"}, 84 {`pinkié\x20pie`, `pinkié pie`}, 85 } 86 for _, name := range names { 87 err := os.Symlink(filepath.Join(d.dir, "/dev/fakedevice"), filepath.Join(d.dir, "/dev/disk/by-partlabel", name.escaped)) 88 c.Assert(err, IsNil) 89 } 90 91 for _, tc := range names { 92 c.Logf("trying: %q", tc) 93 found, err := gadget.FindDeviceForStructure(&gadget.LaidOutStructure{ 94 VolumeStructure: &gadget.VolumeStructure{Name: tc.structure}, 95 }) 96 c.Check(err, IsNil) 97 c.Check(found, Equals, filepath.Join(d.dir, "/dev/fakedevice")) 98 } 99 } 100 101 func (d *deviceSuite) TestDeviceFindRelativeSymlink(c *C) { 102 err := os.Symlink("../../fakedevice", filepath.Join(d.dir, "/dev/disk/by-partlabel/relative")) 103 c.Assert(err, IsNil) 104 105 found, err := gadget.FindDeviceForStructure(&gadget.LaidOutStructure{ 106 VolumeStructure: &gadget.VolumeStructure{Name: "relative"}, 107 }) 108 c.Check(err, IsNil) 109 c.Check(found, Equals, filepath.Join(d.dir, "/dev/fakedevice")) 110 } 111 112 func (d *deviceSuite) TestDeviceFindByFilesystemLabel(c *C) { 113 names := []struct { 114 escaped string 115 structure string 116 }{ 117 {"foo", "foo"}, 118 {"123", "123"}, 119 {`foo\x20bar`, "foo bar"}, 120 {"foo#bar", "foo#bar"}, 121 {"Новый_том", "Новый_том"}, 122 {`pinkié\x20pie`, `pinkié pie`}, 123 } 124 for _, name := range names { 125 err := os.Symlink(filepath.Join(d.dir, "/dev/fakedevice"), filepath.Join(d.dir, "/dev/disk/by-label", name.escaped)) 126 c.Assert(err, IsNil) 127 } 128 129 for _, tc := range names { 130 c.Logf("trying: %q", tc) 131 found, err := gadget.FindDeviceForStructure(&gadget.LaidOutStructure{ 132 VolumeStructure: &gadget.VolumeStructure{Label: tc.structure}, 133 }) 134 c.Check(err, IsNil) 135 c.Check(found, Equals, filepath.Join(d.dir, "/dev/fakedevice")) 136 } 137 } 138 139 func (d *deviceSuite) TestDeviceFindChecksPartlabelAndFilesystemLabelHappy(c *C) { 140 fakedevice := filepath.Join(d.dir, "/dev/fakedevice") 141 err := os.Symlink(fakedevice, filepath.Join(d.dir, "/dev/disk/by-label/foo")) 142 c.Assert(err, IsNil) 143 144 err = os.Symlink(fakedevice, filepath.Join(d.dir, "/dev/disk/by-partlabel/bar")) 145 c.Assert(err, IsNil) 146 147 found, err := gadget.FindDeviceForStructure(&gadget.LaidOutStructure{ 148 VolumeStructure: &gadget.VolumeStructure{ 149 Name: "bar", 150 Label: "foo", 151 }, 152 }) 153 c.Check(err, IsNil) 154 c.Check(found, Equals, filepath.Join(d.dir, "/dev/fakedevice")) 155 } 156 157 func (d *deviceSuite) TestDeviceFindChecksPartlabelAndFilesystemLabelMismatch(c *C) { 158 fakedevice := filepath.Join(d.dir, "/dev/fakedevice") 159 err := os.Symlink(fakedevice, filepath.Join(d.dir, "/dev/disk/by-label/foo")) 160 c.Assert(err, IsNil) 161 162 // partlabel of the structure points to a different device 163 fakedeviceOther := filepath.Join(d.dir, "/dev/fakedevice-other") 164 err = ioutil.WriteFile(fakedeviceOther, []byte(""), 0644) 165 c.Assert(err, IsNil) 166 err = os.Symlink(fakedeviceOther, filepath.Join(d.dir, "/dev/disk/by-partlabel/bar")) 167 c.Assert(err, IsNil) 168 169 found, err := gadget.FindDeviceForStructure(&gadget.LaidOutStructure{ 170 VolumeStructure: &gadget.VolumeStructure{ 171 Name: "bar", 172 Label: "foo", 173 }, 174 }) 175 c.Check(err, ErrorMatches, `conflicting device match, ".*/by-label/foo" points to ".*/fakedevice", previous match ".*/by-partlabel/bar" points to ".*/fakedevice-other"`) 176 c.Check(found, Equals, "") 177 } 178 179 func (d *deviceSuite) TestDeviceFindNotFound(c *C) { 180 found, err := gadget.FindDeviceForStructure(&gadget.LaidOutStructure{ 181 VolumeStructure: &gadget.VolumeStructure{ 182 Name: "bar", 183 Label: "foo", 184 }, 185 }) 186 c.Check(err, ErrorMatches, `device not found`) 187 c.Check(found, Equals, "") 188 } 189 190 func (d *deviceSuite) TestDeviceFindNotFoundEmpty(c *C) { 191 // neither name nor filesystem label set 192 found, err := gadget.FindDeviceForStructure(&gadget.LaidOutStructure{ 193 VolumeStructure: &gadget.VolumeStructure{ 194 Name: "", 195 Label: "", 196 }, 197 }) 198 c.Check(err, ErrorMatches, `device not found`) 199 c.Check(found, Equals, "") 200 } 201 202 func (d *deviceSuite) TestDeviceFindNotFoundSymlinkPointsNowhere(c *C) { 203 fakedevice := filepath.Join(d.dir, "/dev/fakedevice-not-found") 204 err := os.Symlink(fakedevice, filepath.Join(d.dir, "/dev/disk/by-label/foo")) 205 c.Assert(err, IsNil) 206 207 found, err := gadget.FindDeviceForStructure(&gadget.LaidOutStructure{ 208 VolumeStructure: &gadget.VolumeStructure{ 209 Label: "foo", 210 }, 211 }) 212 c.Check(err, ErrorMatches, `device not found`) 213 c.Check(found, Equals, "") 214 } 215 216 func (d *deviceSuite) TestDeviceFindNotFoundNotASymlink(c *C) { 217 err := ioutil.WriteFile(filepath.Join(d.dir, "/dev/disk/by-label/foo"), nil, 0644) 218 c.Assert(err, IsNil) 219 220 found, err := gadget.FindDeviceForStructure(&gadget.LaidOutStructure{ 221 VolumeStructure: &gadget.VolumeStructure{ 222 Label: "foo", 223 }, 224 }) 225 c.Check(err, ErrorMatches, `candidate .*/dev/disk/by-label/foo is not a symlink`) 226 c.Check(found, Equals, "") 227 } 228 229 func (d *deviceSuite) TestDeviceFindBadEvalSymlinks(c *C) { 230 fakedevice := filepath.Join(d.dir, "/dev/fakedevice") 231 fooSymlink := filepath.Join(d.dir, "/dev/disk/by-label/foo") 232 err := os.Symlink(fakedevice, fooSymlink) 233 c.Assert(err, IsNil) 234 235 restore := gadget.MockEvalSymlinks(func(p string) (string, error) { 236 c.Assert(p, Equals, fooSymlink) 237 return "", errors.New("failed") 238 }) 239 defer restore() 240 241 found, err := gadget.FindDeviceForStructure(&gadget.LaidOutStructure{ 242 VolumeStructure: &gadget.VolumeStructure{ 243 Label: "foo", 244 }, 245 }) 246 c.Check(err, ErrorMatches, `cannot read device link: failed`) 247 c.Check(found, Equals, "") 248 } 249 250 var writableMountInfo = `26 27 8:3 / /writable rw,relatime shared:7 - ext4 /dev/fakedevice0p1 rw,data=ordered` 251 252 func (d *deviceSuite) TestDeviceFindFallbackNotFoundNoWritable(c *C) { 253 badMountInfo := `26 27 8:3 / /not-writable rw,relatime shared:7 - ext4 /dev/fakedevice0p1 rw,data=ordered` 254 255 mockProcSelfFilesystem(c, d.dir, badMountInfo) 256 257 found, offs, err := gadget.FindDeviceForStructureWithFallback(&gadget.LaidOutStructure{ 258 VolumeStructure: &gadget.VolumeStructure{ 259 Type: "bare", 260 }, 261 StartOffset: 123, 262 }) 263 c.Check(err, ErrorMatches, `device not found`) 264 c.Check(found, Equals, "") 265 c.Check(offs, Equals, gadget.Size(0)) 266 } 267 268 func (d *deviceSuite) TestDeviceFindFallbackBadWritable(c *C) { 269 mockProcSelfFilesystem(c, d.dir, writableMountInfo) 270 271 ps := &gadget.LaidOutStructure{ 272 VolumeStructure: &gadget.VolumeStructure{ 273 Type: "bare", 274 }, 275 StartOffset: 123, 276 } 277 278 found, offs, err := gadget.FindDeviceForStructureWithFallback(ps) 279 c.Check(err, ErrorMatches, `unexpected number of matches \(0\) for /sys/block/\*/fakedevice0p1`) 280 c.Check(found, Equals, "") 281 c.Check(offs, Equals, gadget.Size(0)) 282 283 err = os.MkdirAll(filepath.Join(d.dir, "/sys/block/fakedevice0/fakedevice0p1"), 0755) 284 c.Assert(err, IsNil) 285 286 found, offs, err = gadget.FindDeviceForStructureWithFallback(ps) 287 c.Check(err, ErrorMatches, `device .*/dev/fakedevice0 does not exist`) 288 c.Check(found, Equals, "") 289 c.Check(offs, Equals, gadget.Size(0)) 290 } 291 292 func (d *deviceSuite) TestDeviceFindFallbackHappyWritable(c *C) { 293 d.setUpWritableFallback(c, writableMountInfo) 294 295 psJustBare := &gadget.LaidOutStructure{ 296 VolumeStructure: &gadget.VolumeStructure{ 297 Type: "bare", 298 }, 299 StartOffset: 123, 300 } 301 psBareWithName := &gadget.LaidOutStructure{ 302 VolumeStructure: &gadget.VolumeStructure{ 303 Type: "bare", 304 Name: "foo", 305 }, 306 StartOffset: 123, 307 } 308 psNoName := &gadget.LaidOutStructure{ 309 VolumeStructure: &gadget.VolumeStructure{}, 310 StartOffset: 123, 311 } 312 313 for _, ps := range []*gadget.LaidOutStructure{psJustBare, psBareWithName, psNoName} { 314 found, offs, err := gadget.FindDeviceForStructureWithFallback(ps) 315 c.Check(err, IsNil) 316 c.Check(found, Equals, filepath.Join(d.dir, "/dev/fakedevice0")) 317 c.Check(offs, Equals, gadget.Size(123)) 318 } 319 } 320 321 func (d *deviceSuite) TestDeviceFindFallbackNotForNamedWritable(c *C) { 322 d.setUpWritableFallback(c, writableMountInfo) 323 324 // should not hit the fallback path 325 psNamed := &gadget.LaidOutStructure{ 326 VolumeStructure: &gadget.VolumeStructure{ 327 Name: "foo", 328 }, 329 StartOffset: 123, 330 } 331 found, offs, err := gadget.FindDeviceForStructureWithFallback(psNamed) 332 c.Check(err, Equals, gadget.ErrDeviceNotFound) 333 c.Check(found, Equals, "") 334 c.Check(offs, Equals, gadget.Size(0)) 335 } 336 337 func (d *deviceSuite) TestDeviceFindFallbackNotForFilesystem(c *C) { 338 d.setUpWritableFallback(c, writableMountInfo) 339 340 psFs := &gadget.LaidOutStructure{ 341 VolumeStructure: &gadget.VolumeStructure{ 342 Label: "foo", 343 Filesystem: "ext4", 344 }, 345 StartOffset: 123, 346 } 347 found, offs, err := gadget.FindDeviceForStructureWithFallback(psFs) 348 c.Check(err, ErrorMatches, "internal error: cannot use with filesystem structures") 349 c.Check(found, Equals, "") 350 c.Check(offs, Equals, gadget.Size(0)) 351 } 352 353 func (d *deviceSuite) TestDeviceFindFallbackBadMountInfo(c *C) { 354 d.setUpWritableFallback(c, "garbage") 355 psFs := &gadget.LaidOutStructure{ 356 VolumeStructure: &gadget.VolumeStructure{ 357 Name: "foo", 358 Type: "bare", 359 }, 360 StartOffset: 123, 361 } 362 found, offs, err := gadget.FindDeviceForStructureWithFallback(psFs) 363 c.Check(err, ErrorMatches, "cannot read mount info: .*") 364 c.Check(found, Equals, "") 365 c.Check(offs, Equals, gadget.Size(0)) 366 } 367 368 func (d *deviceSuite) TestDeviceFindFallbackPassThrough(c *C) { 369 err := ioutil.WriteFile(filepath.Join(d.dir, "/dev/disk/by-partlabel/foo"), nil, 0644) 370 c.Assert(err, IsNil) 371 372 ps := &gadget.LaidOutStructure{ 373 VolumeStructure: &gadget.VolumeStructure{ 374 Name: "foo", 375 }, 376 } 377 found, offs, err := gadget.FindDeviceForStructureWithFallback(ps) 378 c.Check(err, ErrorMatches, `candidate .*/dev/disk/by-partlabel/foo is not a symlink`) 379 c.Check(found, Equals, "") 380 c.Check(offs, Equals, gadget.Size(0)) 381 382 // create a proper symlink 383 err = os.Remove(filepath.Join(d.dir, "/dev/disk/by-partlabel/foo")) 384 c.Assert(err, IsNil) 385 err = os.Symlink("../../fakedevice", filepath.Join(d.dir, "/dev/disk/by-partlabel/foo")) 386 c.Assert(err, IsNil) 387 388 // this should be happy again 389 found, offs, err = gadget.FindDeviceForStructureWithFallback(ps) 390 c.Assert(err, IsNil) 391 c.Check(found, Equals, filepath.Join(d.dir, "/dev/fakedevice")) 392 c.Check(offs, Equals, gadget.Size(0)) 393 } 394 395 func (d *deviceSuite) TestDeviceEncodeLabel(c *C) { 396 // Test output obtained with the following program: 397 // 398 // #include <string.h> 399 // #include <stdio.h> 400 // #include <blkid/blkid.h> 401 // int main(int argc, char *argv[]) { 402 // char out[2048] = {0}; 403 // if (blkid_encode_string(argv[1], out, sizeof(out)) != 0) { 404 // fprintf(stderr, "failed to encode string\n"); 405 // return 1; 406 // } 407 // fprintf(stdout, out); 408 // return 0; 409 // } 410 for i, tc := range []struct { 411 what string 412 exp string 413 }{ 414 {"foo", "foo"}, 415 {"foo bar", `foo\x20bar`}, 416 {"foo/bar", `foo\x2fbar`}, 417 {"foo:#.@bar", `foo:#.@bar`}, 418 {"foo..bar", `foo..bar`}, 419 {"foo/../bar", `foo\x2f..\x2fbar`}, 420 {"foo\\bar", `foo\x5cbar`}, 421 {"Новый_том", "Новый_том"}, 422 {"befs_test", "befs_test"}, 423 {"P01_S16A", "P01_S16A"}, 424 {"pinkié pie", `pinkié\x20pie`}, 425 {"(EFI Boot)", `\x28EFI\x20Boot\x29`}, 426 {"[System Boot]", `\x5bSystem\x20Boot\x5d`}, 427 } { 428 c.Logf("tc: %v %q", i, tc) 429 res := gadget.EncodeLabel(tc.what) 430 c.Check(res, Equals, tc.exp) 431 } 432 } 433 434 func (d *deviceSuite) TestDeviceFindMountPointErrorsWithBare(c *C) { 435 p, err := gadget.FindMountPointForStructure(&gadget.LaidOutStructure{ 436 VolumeStructure: &gadget.VolumeStructure{ 437 // no filesystem 438 Filesystem: "", 439 }, 440 }) 441 c.Assert(err, ErrorMatches, "no filesystem defined") 442 c.Check(p, Equals, "") 443 444 p, err = gadget.FindMountPointForStructure(&gadget.LaidOutStructure{ 445 VolumeStructure: &gadget.VolumeStructure{ 446 // also counts as bare structure 447 Filesystem: "none", 448 }, 449 }) 450 c.Assert(err, ErrorMatches, "no filesystem defined") 451 c.Check(p, Equals, "") 452 } 453 454 func (d *deviceSuite) TestDeviceFindMountPointErrorsFromDevice(c *C) { 455 p, err := gadget.FindMountPointForStructure(&gadget.LaidOutStructure{ 456 VolumeStructure: &gadget.VolumeStructure{ 457 Label: "bar", 458 Filesystem: "ext4", 459 }, 460 }) 461 c.Assert(err, ErrorMatches, "device not found") 462 c.Check(p, Equals, "") 463 464 p, err = gadget.FindMountPointForStructure(&gadget.LaidOutStructure{ 465 VolumeStructure: &gadget.VolumeStructure{ 466 Name: "bar", 467 Filesystem: "ext4", 468 }, 469 }) 470 c.Assert(err, ErrorMatches, "device not found") 471 c.Check(p, Equals, "") 472 } 473 474 func mockProcSelfFilesystem(c *C, root, content string) { 475 psmi := filepath.Join(root, osutil.ProcSelfMountInfo) 476 err := os.MkdirAll(filepath.Dir(psmi), 0755) 477 c.Assert(err, IsNil) 478 err = ioutil.WriteFile(psmi, []byte(content), 0644) 479 c.Assert(err, IsNil) 480 } 481 482 func (d *deviceSuite) TestDeviceFindMountPointErrorBadMountinfo(c *C) { 483 // taken from core18 system 484 485 fakedevice := filepath.Join(d.dir, "/dev/sda2") 486 err := ioutil.WriteFile(fakedevice, []byte(""), 0644) 487 c.Assert(err, IsNil) 488 err = os.Symlink(fakedevice, filepath.Join(d.dir, "/dev/disk/by-label/system-boot")) 489 c.Assert(err, IsNil) 490 491 mockProcSelfFilesystem(c, d.dir, "garbage") 492 493 found, err := gadget.FindMountPointForStructure(&gadget.LaidOutStructure{ 494 VolumeStructure: &gadget.VolumeStructure{ 495 Name: "EFI System", 496 Label: "system-boot", 497 Filesystem: "vfat", 498 }, 499 }) 500 c.Check(err, ErrorMatches, "cannot read mount info: .*") 501 c.Check(found, Equals, "") 502 } 503 504 func (d *deviceSuite) TestDeviceFindMountPointByLabeHappySimple(c *C) { 505 // taken from core18 system 506 507 fakedevice := filepath.Join(d.dir, "/dev/sda2") 508 err := ioutil.WriteFile(fakedevice, []byte(""), 0644) 509 c.Assert(err, IsNil) 510 err = os.Symlink(fakedevice, filepath.Join(d.dir, "/dev/disk/by-label/system-boot")) 511 c.Assert(err, IsNil) 512 err = os.Symlink(fakedevice, filepath.Join(d.dir, `/dev/disk/by-partlabel/EFI\x20System`)) 513 c.Assert(err, IsNil) 514 515 mountInfo := ` 516 170 27 8:2 / /boot/efi rw,relatime shared:58 - vfat ${rootDir}/dev/sda2 rw,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 517 172 27 8:2 /EFI/ubuntu /boot/grub rw,relatime shared:58 - vfat ${rootDir}/dev/sda2 rw,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 518 ` 519 mockProcSelfFilesystem(c, d.dir, strings.Replace(mountInfo[1:], "${rootDir}", d.dir, -1)) 520 521 found, err := gadget.FindMountPointForStructure(&gadget.LaidOutStructure{ 522 VolumeStructure: &gadget.VolumeStructure{ 523 Name: "EFI System", 524 Label: "system-boot", 525 Filesystem: "vfat", 526 }, 527 }) 528 c.Check(err, IsNil) 529 c.Check(found, Equals, "/boot/efi") 530 } 531 532 func (d *deviceSuite) TestDeviceFindMountPointByLabeHappyReversed(c *C) { 533 // taken from core18 system 534 535 fakedevice := filepath.Join(d.dir, "/dev/sda2") 536 err := ioutil.WriteFile(fakedevice, []byte(""), 0644) 537 c.Assert(err, IsNil) 538 // single property match 539 err = os.Symlink(fakedevice, filepath.Join(d.dir, "/dev/disk/by-label/system-boot")) 540 c.Assert(err, IsNil) 541 542 // reverse the order of lines 543 mountInfoReversed := ` 544 172 27 8:2 /EFI/ubuntu /boot/grub rw,relatime shared:58 - vfat ${rootDir}/dev/sda2 rw,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 545 170 27 8:2 / /boot/efi rw,relatime shared:58 - vfat ${rootDir}/dev/sda2 rw,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 546 ` 547 548 mockProcSelfFilesystem(c, d.dir, strings.Replace(mountInfoReversed[1:], "${rootDir}", d.dir, -1)) 549 550 found, err := gadget.FindMountPointForStructure(&gadget.LaidOutStructure{ 551 VolumeStructure: &gadget.VolumeStructure{ 552 Name: "EFI System", 553 Label: "system-boot", 554 Filesystem: "vfat", 555 }, 556 }) 557 c.Check(err, IsNil) 558 c.Check(found, Equals, "/boot/efi") 559 } 560 561 func (d *deviceSuite) TestDeviceFindMountPointPicksFirstMatch(c *C) { 562 // taken from core18 system 563 564 fakedevice := filepath.Join(d.dir, "/dev/sda2") 565 err := ioutil.WriteFile(fakedevice, []byte(""), 0644) 566 c.Assert(err, IsNil) 567 // single property match 568 err = os.Symlink(fakedevice, filepath.Join(d.dir, "/dev/disk/by-label/system-boot")) 569 c.Assert(err, IsNil) 570 571 mountInfo := ` 572 852 134 8:2 / /mnt/foo rw,relatime shared:58 - vfat ${rootDir}/dev/sda2 rw,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 573 172 27 8:2 /EFI/ubuntu /boot/grub rw,relatime shared:58 - vfat ${rootDir}/dev/sda2 rw,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 574 170 27 8:2 / /boot/efi rw,relatime shared:58 - vfat ${rootDir}/dev/sda2 rw,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 575 ` 576 577 mockProcSelfFilesystem(c, d.dir, strings.Replace(mountInfo[1:], "${rootDir}", d.dir, -1)) 578 579 found, err := gadget.FindMountPointForStructure(&gadget.LaidOutStructure{ 580 VolumeStructure: &gadget.VolumeStructure{ 581 Name: "EFI System", 582 Label: "system-boot", 583 Filesystem: "vfat", 584 }, 585 }) 586 c.Check(err, IsNil) 587 c.Check(found, Equals, "/mnt/foo") 588 } 589 590 func (d *deviceSuite) TestDeviceFindMountPointByPartlabel(c *C) { 591 fakedevice := filepath.Join(d.dir, "/dev/fakedevice") 592 err := ioutil.WriteFile(fakedevice, []byte(""), 0644) 593 c.Assert(err, IsNil) 594 err = os.Symlink(fakedevice, filepath.Join(d.dir, `/dev/disk/by-partlabel/pinkié\x20pie`)) 595 c.Assert(err, IsNil) 596 597 mountInfo := ` 598 170 27 8:2 / /mount-point rw,relatime shared:58 - ext4 ${rootDir}/dev/fakedevice rw 599 ` 600 601 mockProcSelfFilesystem(c, d.dir, strings.Replace(mountInfo[1:], "${rootDir}", d.dir, -1)) 602 603 found, err := gadget.FindMountPointForStructure(&gadget.LaidOutStructure{ 604 VolumeStructure: &gadget.VolumeStructure{ 605 Name: "pinkié pie", 606 Filesystem: "ext4", 607 }, 608 }) 609 c.Check(err, IsNil) 610 c.Check(found, Equals, "/mount-point") 611 } 612 613 func (d *deviceSuite) TestDeviceFindMountPointChecksFilesystem(c *C) { 614 fakedevice := filepath.Join(d.dir, "/dev/fakedevice") 615 err := ioutil.WriteFile(fakedevice, []byte(""), 0644) 616 c.Assert(err, IsNil) 617 err = os.Symlink(fakedevice, filepath.Join(d.dir, `/dev/disk/by-partlabel/label`)) 618 c.Assert(err, IsNil) 619 620 mountInfo := ` 621 170 27 8:2 / /mount-point rw,relatime shared:58 - vfat ${rootDir}/dev/fakedevice rw 622 ` 623 624 mockProcSelfFilesystem(c, d.dir, strings.Replace(mountInfo[1:], "${rootDir}", d.dir, -1)) 625 626 found, err := gadget.FindMountPointForStructure(&gadget.LaidOutStructure{ 627 VolumeStructure: &gadget.VolumeStructure{ 628 Name: "label", 629 // different fs than mount entry 630 Filesystem: "ext4", 631 }, 632 }) 633 c.Check(err, ErrorMatches, "mount point not found") 634 c.Check(found, Equals, "") 635 }