Linux 以编程方式查找分区的 UUID

Linux Programmatically find UUID's of Partitions

因此,我正在为我的工作开发一个相当精简的自定义 linux 构建。我正在尝试发现一种使用 C 获取硬盘驱动器和 zram 分区的 UUID 的方法。

libblkid 不可用,/etc/blkid.tab 不存在,/etc/fstab 仅提供文件系统名称和类型。 /etc/mtab 为空。 udev 也不可用。 /dev/disk/... 不存在。

/proc/partitions 可用,但即使在正常的 linux 系统上也不提供 UUID。

fdisk 只提供实际磁盘的信息,没有 UUID,也没有关于闪存的信息。

我查看了 blkid 的源代码,它似乎正在读取 /etc/blkid.tab,除非通过环境变量提供了另一个文件作为信息源。我试图找出是否有其他方法可以打开驱动器并找到 UUID,或者 linux 是否以我不知道的其他方式存储它们。

UUID 不是分区设置,它存储在文件系统级别。

# tune2fs -l /dev/sda4|grep UUID Filesystem UUID: 7a7be8cb-8271-4442-b0c3-2c1df2eaab6c

您可以查看/dev/disk/by-uuid中的符号链接。您可以使用 POSIX 系统调用,例如 opendirreadlink。您还可以 运行 ls -l /dev/disk/by-uuid,输出类似:

lrwxrwxrwx 1 root root 10 Jul 27 11:23 ec13636b-a731-41d0-8273-442f194cf37f -> ../../sda5
lrwxrwxrwx 1 root root 10 Jul 27 11:23 ed8799bc-34c3-4d37-b1b2-44562423a298 -> ../../sda1

首先,您知道分区和文件系统都有 UUID 吗?两者都不总是存在。 Linux 本身不知道 UUID,整个概念由安装在您系统上的程序在 user-space 中处理,据我所知,这些程序都使用 libblkid。

你说你想要分区 UUID,但你可能实际上想要文件系统 UUID。

Libblkid

抱歉,您说 "libblkid isn't available" 是什么意思?我有点怀疑。毕竟,Libblkid 是开放源代码和免费软件,所以如果您没有 libblkid 的副本,那么获取一个也很简单。 Libblkid 也是用 C 编写的,而您已经在用 C 编写代码,因此您必须 有一个 C 编译器来编译 libblkid。如有必要,您可以制作静态版本。

libblkid 的主要工作方式是直接从块设备读取数据。对于磁盘,这意味着读取分区 table。对于文件系统,这意味着从文件系统超级块中读取。理论上,如果您不能使用 libblkid(这是非常不寻常的,即使对于精简系统也是如此),您可以自己解析分区 table 或超级块。

Libblkid 在 /etc/blkid.tab 确实使用了一个缓存文件,但这只是一个缓存,没有必要。

UUID 的其他接口,如 /dev/disk/by-uuid,是由使用 libblkid 的程序在 user-space 中创建的。

文件系统 UUID

通常,如果您谈论的是您在 /dev/disk/by-uuid 中看到的 UUID,它们与您在 /etc/fstab 中使用的 UUID 相同,那么您就是在谈论文件系统 UUID。 libblkid 库负责为各种文件系统解码超级块。例如,您可以看到 Ext2 文件系统的 UUID 出现在 libblkid src/superblocks/ext.c line 48 中。 Libblkid 支持许多文件系统类型,您可以在 src/superblocks 目录中看到它们。

并非所有文件系统类型都有 UUID。 Ext2 有一个 UUID,FAT32 没有,但它有一个不同的 ID,目的相同。

分区 UUID

如果你真的需要唯一的分区UUID,你也可以得到。 Libblkid 从分区 table 中读取它。只有某些类型的分区 tables 有分区的 UUID。 GPT 有,但 DOS 分区 tables 没有。