]> git.apps.os.sepia.ceph.com Git - fscrypt.git/commitdiff
filesystem: fall back to path-only links if UUID cannot be determined
authorEric Biggers <ebiggers@google.com>
Wed, 19 Jan 2022 07:43:35 +0000 (23:43 -0800)
committerEric Biggers <ebiggers@google.com>
Thu, 27 Jan 2022 07:22:55 +0000 (23:22 -0800)
This is needed to allow creating protector links to btrfs filesystems.

Update https://github.com/google/fscrypt/issues/339

filesystem/mountpoint.go
filesystem/mountpoint_test.go

index 20a85688c569982683f851459ad84d3d37ad4f8b..182cafa1b4427d0392a0d0ed6f861a512fbb5c59 100644 (file)
@@ -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
 }
index a4688edd18b403f80e84c1b747ac48c44ee5a12f..749e5e3bcb7984c9949b828ddd9c42278df22a18 100644 (file)
@@ -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)
@@ -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 {