// Path - Absolute path where the directory is mounted
// FilesystemType - Type of the mounted filesystem, e.g. "ext4"
// Device - Device for filesystem (empty string if we cannot find one)
+// DeviceNumber - Device number of the filesystem. This is set even if
+// Device isn't, since all filesystems have a device
+// number assigned by the kernel, even pseudo-filesystems.
//
// In order to use a Mount to store fscrypt metadata, some directories must be
// setup first. Specifically, the directories created look like:
Path string
FilesystemType string
Device string
+ DeviceNumber DeviceNumber
}
// PathSorter allows mounts to be sorted by Path.
return sb.String()
}
+// We get the device name via the device number rather than use the mount source
+// field directly. This is necessary to handle a rootfs that was mounted via
+// the kernel command line, since mountinfo always shows /dev/root for that.
+// This assumes that the device nodes are in the standard location.
+func getDeviceName(num DeviceNumber) string {
+ linkPath := fmt.Sprintf("/sys/dev/block/%v", num)
+ if target, err := os.Readlink(linkPath); err == nil {
+ return fmt.Sprintf("/dev/%s", filepath.Base(target))
+ }
+ return ""
+}
+
// Parse one line of /proc/self/mountinfo.
//
// The line contains the following space-separated fields:
}
var mnt *Mount = &Mount{}
+ var err error
+ mnt.DeviceNumber, err = newDeviceNumberFromString(fields[2])
+ if err != nil {
+ return nil
+ }
mnt.Path = unescapeString(fields[4])
mnt.FilesystemType = unescapeString(fields[n+1])
- mnt.Device = unescapeString(fields[n+2])
+ mnt.Device = getDeviceName(mnt.DeviceNumber)
return mnt
}
// filesystems are listed in mount order.
mountsByPath[mnt.Path] = mnt
- var err error
- mnt.Device, err = canonicalizePath(mnt.Device)
- // Only use real valid devices (unlike cgroups, tmpfs, ...)
- if err == nil && isDevice(mnt.Device) {
+ if mnt.Device != "" {
mountsByDevice[mnt.Device] = append(mountsByDevice[mnt.Device], mnt)
- } else {
- mnt.Device = ""
}
}
mountsInitialized = true
return err == nil && info.IsDir()
}
-// isDevice returns true if the path exists and is that of a device.
-func isDevice(path string) bool {
- info, err := loggedStat(path)
- return err == nil && info.Mode()&os.ModeDevice != 0
-}
-
// isDirCheckPerm returns true if the path exists and is a directory. If the
// specified permissions and sticky bit of mode do not match the path, an error
// is logged.