Skip to content

Commit

Permalink
filesystem: fall back to path-only links if UUID cannot be determined
Browse files Browse the repository at this point in the history
This is needed to allow creating protector links to btrfs filesystems.

Update #339
  • Loading branch information
ebiggers committed Jan 27, 2022
1 parent 51c421d commit c2fb96c
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 3 deletions.
13 changes: 10 additions & 3 deletions filesystem/mountpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -545,12 +545,19 @@ func (mnt *Mount) getFilesystemUUID() (string, error) {
}

// makeLink creates the contents of a link file which will point to the given
// filesystem. This will be a string of the form "UUID=<uuid>\nPATH=<path>\n".
// An error is returned if the filesystem's UUID cannot be determined.
// filesystem. This will normally be a string of the form
// "UUID=<uuid>\nPATH=<path>\n". If the UUID cannot be determined, the UUID
// portion will be omitted.
func makeLink(mnt *Mount) (string, error) {
uuid, err := mnt.getFilesystemUUID()
if err != nil {
return "", &ErrMakeLink{mnt, err}
// The UUID could not be determined. This happens for btrfs
// filesystems, as the device number found via
// /dev/disk/by-uuid/* for btrfs filesystems differs from the
// actual device number of the mounted filesystem. Just rely
// entirely on the fallback to mountpoint path.
log.Print(err)
return fmt.Sprintf("%s=%s\n", pathToken, mnt.Path), nil
}
return fmt.Sprintf("%s=%s\n%s=%s\n", uuidToken, uuid, pathToken, mnt.Path), nil
}
44 changes: 44 additions & 0 deletions filesystem/mountpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,40 @@ func TestGetMountFromLink(t *testing.T) {
}
}

// Test that makeLink() is including the expected information in links.
func TestMakeLink(t *testing.T) {
mnt, err := getTestMount(t)
if err != nil {
t.Skip(err)
}
link, err := makeLink(mnt)
if err != nil {
t.Fatal(err)
}

// Normally, both UUID and PATH should be included.
if !strings.Contains(link, "UUID=") {
t.Fatal("Link doesn't contain UUID")
}
if !strings.Contains(link, "PATH=") {
t.Fatal("Link doesn't contain PATH")
}

// Without a valid device number, only PATH should be included.
mntCopy := *mnt
mntCopy.DeviceNumber = 0
link, err = makeLink(&mntCopy)
if err != nil {
t.Fatal(err)
}
if strings.Contains(link, "UUID=") {
t.Fatal("Link shouldn't contain UUID")
}
if !strings.Contains(link, "PATH=") {
t.Fatal("Link doesn't contain PATH")
}
}

// Test that old filesystem links that contain a UUID only still work.
func TestGetMountFromLegacyLink(t *testing.T) {
mnt, err := getTestMount(t)
Expand Down Expand Up @@ -456,6 +490,16 @@ func TestGetMountFromLinkFallback(t *testing.T) {
t.Fatal("Link doesn't point to the same Mount")
}

// only PATH given at all (should succeed)
link = fmt.Sprintf("PATH=%s\n", mnt.Path)
linkedMnt, err = getMountFromLink(link)
if err != nil {
t.Fatal(err)
}
if linkedMnt != mnt {
t.Fatal("Link doesn't point to the same Mount")
}

// only UUID valid (should succeed)
link = fmt.Sprintf("UUID=%s\nPATH=%s\n", goodUUID, badPath)
if linkedMnt, err = getMountFromLink(link); err != nil {
Expand Down

0 comments on commit c2fb96c

Please sign in to comment.