Skip to content

Commit c2fb96c

Browse files
committed
filesystem: fall back to path-only links if UUID cannot be determined
This is needed to allow creating protector links to btrfs filesystems. Update #339
1 parent 51c421d commit c2fb96c

2 files changed

Lines changed: 54 additions & 3 deletions

File tree

filesystem/mountpoint.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -545,12 +545,19 @@ func (mnt *Mount) getFilesystemUUID() (string, error) {
545545
}
546546

547547
// makeLink creates the contents of a link file which will point to the given
548-
// filesystem. This will be a string of the form "UUID=<uuid>\nPATH=<path>\n".
549-
// An error is returned if the filesystem's UUID cannot be determined.
548+
// filesystem. This will normally be a string of the form
549+
// "UUID=<uuid>\nPATH=<path>\n". If the UUID cannot be determined, the UUID
550+
// portion will be omitted.
550551
func makeLink(mnt *Mount) (string, error) {
551552
uuid, err := mnt.getFilesystemUUID()
552553
if err != nil {
553-
return "", &ErrMakeLink{mnt, err}
554+
// The UUID could not be determined. This happens for btrfs
555+
// filesystems, as the device number found via
556+
// /dev/disk/by-uuid/* for btrfs filesystems differs from the
557+
// actual device number of the mounted filesystem. Just rely
558+
// entirely on the fallback to mountpoint path.
559+
log.Print(err)
560+
return fmt.Sprintf("%s=%s\n", pathToken, mnt.Path), nil
554561
}
555562
return fmt.Sprintf("%s=%s\n%s=%s\n", uuidToken, uuid, pathToken, mnt.Path), nil
556563
}

filesystem/mountpoint_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,40 @@ func TestGetMountFromLink(t *testing.T) {
411411
}
412412
}
413413

414+
// Test that makeLink() is including the expected information in links.
415+
func TestMakeLink(t *testing.T) {
416+
mnt, err := getTestMount(t)
417+
if err != nil {
418+
t.Skip(err)
419+
}
420+
link, err := makeLink(mnt)
421+
if err != nil {
422+
t.Fatal(err)
423+
}
424+
425+
// Normally, both UUID and PATH should be included.
426+
if !strings.Contains(link, "UUID=") {
427+
t.Fatal("Link doesn't contain UUID")
428+
}
429+
if !strings.Contains(link, "PATH=") {
430+
t.Fatal("Link doesn't contain PATH")
431+
}
432+
433+
// Without a valid device number, only PATH should be included.
434+
mntCopy := *mnt
435+
mntCopy.DeviceNumber = 0
436+
link, err = makeLink(&mntCopy)
437+
if err != nil {
438+
t.Fatal(err)
439+
}
440+
if strings.Contains(link, "UUID=") {
441+
t.Fatal("Link shouldn't contain UUID")
442+
}
443+
if !strings.Contains(link, "PATH=") {
444+
t.Fatal("Link doesn't contain PATH")
445+
}
446+
}
447+
414448
// Test that old filesystem links that contain a UUID only still work.
415449
func TestGetMountFromLegacyLink(t *testing.T) {
416450
mnt, err := getTestMount(t)
@@ -456,6 +490,16 @@ func TestGetMountFromLinkFallback(t *testing.T) {
456490
t.Fatal("Link doesn't point to the same Mount")
457491
}
458492

493+
// only PATH given at all (should succeed)
494+
link = fmt.Sprintf("PATH=%s\n", mnt.Path)
495+
linkedMnt, err = getMountFromLink(link)
496+
if err != nil {
497+
t.Fatal(err)
498+
}
499+
if linkedMnt != mnt {
500+
t.Fatal("Link doesn't point to the same Mount")
501+
}
502+
459503
// only UUID valid (should succeed)
460504
link = fmt.Sprintf("UUID=%s\nPATH=%s\n", goodUUID, badPath)
461505
if linkedMnt, err = getMountFromLink(link); err != nil {

0 commit comments

Comments
 (0)