[译]UUID和Linux:你需要知道的一切

本文为 UUIDs and Linux: Everything you ever need to know [Update] 的翻译。

UUID在Linux中为何如此特别?我[原作者]不知道!但是这儿有你需要知道的、关于UUID在Linux下的一切!

背景

UUID是128位长的数字,表示为32位的16进制数字,被用于在软件开发中、在没有上下文的情况下唯一地标识信息。RFC 4122描述了UUID的规范,一个UUID的例子是:

13152fae-d25a-4d78-b318-74397eb08184

UUID在Linux最熟悉的场景应该是块设备的标识符了吧。Windows世界中的UUID以Microsoft的全局唯一标识符GUID的形式出现,这些标识符在Microsoft的组件对象模型[COM]中使用。

UUID以各种变体生成:最初大多数是从计算机的MAC派生的,随后使用了基于name的散列值。关于这个问题,有多少UUID,有多大概率会生成一个已有的UUID,这是来自维基百科上 UUID 的文章的一些数字:

在100年里,每秒生成十亿个UUID,生成重复的UUID的概率约为50%。如果每个人都有6亿个UUID,下一个UUID重复的概率约为50%。

fstab中的用法

就像之前提到的,UUID在Linux下被经常用于标识块设备。想象一下,你有两个硬盘通过USB连接上,它们不是持久存储,只能依赖两个设备的名字来区分:有时第一个USB硬盘是“sda”,有时它是“sdb”。所以要唯一寻址正确的磁盘,比如在 /etc/fstab 中,你必须添加如下条目:

UUID=9043278a-1817-4ff5-8145-c79d8e24ea79 /boot ext3 defaults 0 2

对于块设备,uuid是存储在超级块中的。
但请注意,当您使用LVM快照时,不应在fstab中使用UUID。 有关更多详细信息,请参阅下面的“何时不使用它们”。

Linux下的实现和生成

在Linux下UUID在file中生成,你可以通过 /drivers/char/random.c 来生成新的UUID:

$ cat /proc/sys/kernel/random/uuid
eaf3a162-d770-4ec9-a819-ec96d429ea9f

uuidgen,以及ext 2/3/4 工具 E2fsprogs 使用程序库 libuuid 来生成UUID:

$ uuidgen 
f81cc383-aa75-4714-aa8a-3ce39e8ad33c

Bash中如何得到UUID

UUID中最有趣的部分很可能是如何获取硬盘的当前UUID。 如前面已经提到的,有两种主要的方法来获取它们:在特殊目录中的 ls 命令和工具 blkid。

第一,在 /dev/disk/by-uuid 中执行 ls 命令。这个目录包含了名字为UUID,链接到“真正的”块设备文件。对于你很难辨别安装了什么磁盘的情况下,这是很方便的。

$ ls -l /dev/disk/by-uuid
lrwxrwxrwx 1 root root 10 11. Oct 18:02 53cdad3b-4b01-4a6c-a099-be1cdf1acf6d -> ../../sda2

第二,blkid 工具是util-linux软件包的一部分。它提供了一个界面来查询特定设备,并且还支持搜索标签。

$ blkid /dev/sda1
/dev/sda1: LABEL="/" UUID="ee7cf0a0-1922-401b-a1ae-6ec9261484c0" SEC_TYPE="ext2" TYPE="ext3"

这儿还有更多方法!让我们安装 hwinfo:

$ hwinfo --block
[...]
  UDI: /org/freedesktop/Hal/devices/volume_uuid_3e953ee0_79f2_4d94_98b3_5f49ad652b7c
[...]
  Device Files: [...] /dev/disk/by-uuid/3e953ee0-79f2-4d94-98b3-5f49ad652b7c
[...]

就像你看到的,hwinfo列出了大量有关硬件的数据——包括设备的UUID。 当你获取更多关于块设备的信息时使用它。

或者 udevadm?它是udev提供的、从udev数据库查询数据的工具。udev数据库包含了udev系统的所有信息,因此UUID信息只是一部分。 如果你正在写一个“现代”的脚本,它很好地与Linux标准工具集成,我想我会使用udev。 但是对于快速直接的、一次性的命令行工具,和hwinfo一样,它包含了太多的信息。

$ udevadm info -q all -n /dev/sda1|grep uuid
S: disk/by-uuid/9043278a-1817-4ff5-8145-c79d8e24ea79
E: [...] /dev/disk/by-uuid/9043278a-1817-4ff5-8145-c79d8e24ea79
E: ID_FS_UUID=9043278a-1817-4ff5-8145-c79d8e24ea79
E: ID_FS_UUID_ENC=9043278a-1817-4ff5-8145-c79d8e24ea79

在这种情况下,有时也提到udevinfo。 但是,它已被弃用,大多数发行版不再包含。 另外,另一种常提到的检索UUID的方法是从程序库 /lib/vol/vol_id。 但是如bug #476379所述,vol_id只是一个私有的udev函数。因为此接口不稳定它不应该被外部程序(或人)使用。此外,整个库可能会在将来删除——实际上已在某些发行版中删除了。

如何在GUI程序中获取UUID

如果你不善于使用shell,KDE-GUI工具也可以用来查找UUID:/usr/bin/kcmshell4 devinfo

设置UUID

就像评论中提到的,设置UUID有时也是必要的。因为UUID是超级块的一部分,所以根据文件系统的不同,可能要使用不同的工具。比如ext文件系统可以使用tune2fs:

# tune2fs -U new_uuid /dev/sdaX

什么时候不使用UUID

Zhenech 提到,并不是所有的地方都适合使用UUID。

因为挂载两个具有相同的UUID的文件系统是不可行的,所以需要额外关注LVM快照(或者克隆磁盘):因为具有同样的UUID,它们可能会挂载失败。

XFS:dm-2文件系统也会有重复的UUID,也无法挂载。

处理该问题的一种方法是更改UUID,另一种办法是挂载的时候带上nouuid选项。

Leave a Reply

Your email address will not be published. Required fields are marked *