Изменение UUID’а

Алексей Федорчук

Вот уже много лет как в Linux’е для именования блочных устройств (фигурально выражаясь, дисков и их разделов) используются разные модели их именования: традиционные имена «верхнего уровня» (вида /dev/sd?#), по фабричному идентификатору (by-id), по метке (by-label), по так называемому универсальному уникальному идентификатору (by-uuid). Зачем и почему — говорилось ранее. Здесь же замечу только, по однозначно блочное устройство идентифицируется только в модели by-id. Однако на практике, с лёгкой руки разработчиков Ubuntu, распространение получила модель by-uuid.

Причина, подозреваю, в том, что её ранний, текстовый, инсталлятор (ныне именуемый альтернативным, и уцелевший только в Lubutu и в mini.iso) не обеспечивал корректного определения имён «верхнего уровня» в многодисковых системах с внешними накопителями. А, как известно, большую часть того, что придумывают в Ubuntu, рано или поздно, после явного периода смешков и сарказмов, втихаря обезъянничают в большинстве других дистрибутивов. Вне зависимости от того, хорошо это было придумано, или плохо.

Умолчальное именование by-uuid (в частности, в /etc/fstab) с точки зрения применителя было придумано… скажем так, неоднозначно. Конечно, эта модель делает имена блочных устройств независимыми, например, от перетыкания кабелей в разъёмы (кто из читающих эти строки проделывает данную процедуру ежедневно перед завтраком?). Но, как это ни парадоксально, UUID’ы, вопреки своему названию, как раз уникальности имён и не обеспечивают. В частности, при копировании образа раздела командой dd (или графической утилитой Gparted) клон наследует свой UUID от оригинала. Что создаёт вполне очевидные проблемы при загрузке, если и оригинальный раздел, и его клон находятся на внутренних накопителях машины.

К слову сказать, в этом случае клоном наследуется и так называемая метка (label), которая тоже атрибут файловой системы. Однако о том, как присваивать и изменять метки для файловых систем различных типов, некогда уже говорилось. А вот как в таком случае быть UUID’ами?

Как обычно, по разному. Во-первых, изменить UUID можно с помощью программы Gparted. Для этого достаточно в разделе с существующей файловой системой вызвать контекстное меню и в выбрать в нём соответствующий пункт:

uuid_001

После чего будет предложено случайным образом сгенерировать новый UUID:

uuid_002

А после согласия — и выполнить это. Что проходит для всех нативных файловых систем Linux’а, кроме btrfs. Есть подозрение — потому что раздел с btrfs по идее должен быть контейнером для её субтомов (suvolumes). Хотя в это дело я не вникал за неактуальностью (для меня). Кстати, для f2fs и nilfs я это тоже не проверял — и по той же причине.

Процедура, как видите, очень простая и не требует никаких особенных познаний, и даже сверки UUID’ов — вероятность их совпадения меньше вероятности встретить динозавра на улице Москвы. Её целесообразно проделать сразу после копирования образа раздела средствами того же Gparted’а. Однако запуск последнего только ради смены UUID’а не всегда целесообразен: только на сканирование разделов в многодисковой конфигурации может уйти немало времени. Так что есть смысл ознакомиться с утилитами CLI, служащими этой же цели.

Для начала — как можно поглядеть UUID’ы существующих разделов? В обычной жизни для этого достаточно команды

$ ls /dev/disk/by-uuid

которая выведёт полный их список:

0431914e-9f24-4fd2-b451-61d196a881ba@  91d57582-e743-4201-a55e-48da322c16de@  d2c8b3b6-2e6b-414b-8619-279be2ae270c@
0bbc88c4-8d12-4065-9483-6a8029f3257c@  ab854ece-c38a-4eba-8b49-63733a7aa5dd@  fd4d2779-b569-4ac1-b654-e39fb570f6b4@
25591190-1d11-4541-a4d3-df787fd93f60@  b1724134-6914-4ff2-af41-a74b11784556@
3f4dee17-6a11-417c-8001-93a0e50d89e8@  b37e25f5-8538-496d-b8aa-78cc3d4aad80@

А в форме

$ ls -l /dev/disk/by-uuid

она выведет и имена «верхнего уровня», на которые ссылаются UUID’ы

lrwxrwxrwx 1 root root 10 дек.  25 11:56 0431914e-9f24-4fd2-b451-61d196a881ba -> ../../sda1
lrwxrwxrwx 1 root root 10 дек.  25 11:56 0bbc88c4-8d12-4065-9483-6a8029f3257c -> ../../sda2
lrwxrwxrwx 1 root root 10 дек.  25 12:03 25591190-1d11-4541-a4d3-df787fd93f60 -> ../../sdc6
lrwxrwxrwx 1 root root 10 дек.  25 12:03 3f4dee17-6a11-417c-8001-93a0e50d89e8 -> ../../sdc1
lrwxrwxrwx 1 root root 10 дек.  25 11:56 91d57582-e743-4201-a55e-48da322c16de -> ../../sdb1
lrwxrwxrwx 1 root root 10 дек.  25 12:03 ab854ece-c38a-4eba-8b49-63733a7aa5dd -> ../../sdc8
lrwxrwxrwx 1 root root 10 дек.  25 11:56 b1724134-6914-4ff2-af41-a74b11784556 -> ../../sdd1
lrwxrwxrwx 1 root root 11 дек.  25 12:03 b37e25f5-8538-496d-b8aa-78cc3d4aad80 -> ../../sdc10
lrwxrwxrwx 1 root root 10 дек.  25 12:03 d2c8b3b6-2e6b-414b-8619-279be2ae270c -> ../../sdc7
lrwxrwxrwx 1 root root 10 дек.  25 12:03 fd4d2779-b569-4ac1-b654-e39fb570f6b4 -> ../../sdc9

Однако в нашем случае это не пройдёт: UUID клона в выводе команды ls будет потерян, так как имя соответствующей ссылки совпадает с именем её в оригинале. И тогда следует обратиться к специальной утилите blkid, запускаемой обязательно от лица администратора. Например, данная в форме

$ sudo blkid /dev/sdc*

она выведет UUID’ы всех разделов с файловыми системами на устройстве /dev/sdc (для неформатированных разделов будут даны только их PARTUUID’ы):

/dev/sdc: PTUUID="0004c32e" PTTYPE="dos"
/dev/sdc1: UUID="3f4dee17-6a11-417c-8001-93a0e50d89e8" TYPE="swap" PARTUUID="0004c32e-01"
/dev/sdc10: LABEL="ext4" UUID="b37e25f5-8538-496d-b8aa-78cc3d4aad80" TYPE="ext4" PARTUUID="0004c32e-0a"
/dev/sdc2: PARTUUID="0004c32e-02"
/dev/sdc3: PARTUUID="0004c32e-03"
/dev/sdc5: LABEL="ext4" UUID="b37e25f5-8538-496d-b8aa-78cc3d4aad80" TYPE="ext4" PARTUUID="0004c32e-05"
/dev/sdc6: LABEL="xfs" UUID="25591190-1d11-4541-a4d3-df787fd93f60" TYPE="xfs" PARTUUID="0004c32e-06"
/dev/sdc7: LABEL="reiser" UUID="d2c8b3b6-2e6b-414b-8619-279be2ae270c" TYPE="reiserfs" PARTUUID="0004c32e-07"
/dev/sdc8: LABEL="jfs" UUID="ab854ece-c38a-4eba-8b49-63733a7aa5dd" TYPE="jfs" PARTUUID="0004c32e-08"
/dev/sdc9: LABEL="btrfs" UUID="fd4d2779-b569-4ac1-b654-e39fb570f6b4" UUID_SUB="ea2b9fbf-8247-4233-9b61-fff4d83f5dbb" TYPE="btrfs" PARTUUID="0004c32e-09"

В списке присутствует раздел /dev/sdc10, являющийся клоном раздела /dev/sd5. Отфильтровав должным образом вывод предыдущей команды, можно убедиться в идентичности их идентификаторов и меток:

$ sudo blkid /dev/sdc* G ext4
/dev/sdc10: LABEL="ext4" UUID="b37e25f5-8538-496d-b8aa-78cc3d4aad80" TYPE="ext4" PARTUUID="0004c32e-0a"
/dev/sdc5: LABEL="ext4" UUID="b37e25f5-8538-496d-b8aa-78cc3d4aad80" TYPE="ext4" PARTUUID="0004c32e-05"

Как ликвидировать безобразие с совпадением меток — я уже писал. А для смены UUID’а существует утилита uuid. Соответствующий пакет в установке в mini-установке Ububntu отсутствует, поэтому для начала:

$ sudo apt in uuid/wily

Это не какая-то таинственная штука, а просто генератор случайных последовательностей символов того формата, который используется в качестве универсальных уникальных идентификаторов. И поэтому запуск её (можно — от лица обычного пользователя) ничего, кроме вывода набора цифр и букв, разделённых в нужных местах дефисами, не даёт:

$ uuid                                                            [~]
973cc278-aaff-11e5-b0fa-e7ba27cddeac

Чтобы этот вывод использовать, его надо приписать к соответствующей файловой системе раздела-клона. Как — зависит от файловой системы. Например, для ext4 это можно сделать, например, так (обращая внимание на форму кавычек):

$ sudo tune2fs /dev/sdc10 -U `uuid`
tune2fs 1.42.12 (29-Aug-2014)

После чего, повторив команду blkid с тем же фильтром, убедиться, что UUID клона стал отличаться от оригинала:

$ sudo blkid /dev/sdc* G ext4
/dev/sdc10: LABEL="ext4" UUID="7ba62d76-ab02-11e5-a0fa-5bfcb3a17d1a" TYPE="ext4" PARTUUID="0004c32e-0a"
/dev/sdc5: LABEL="ext4" UUID="b37e25f5-8538-496d-b8aa-78cc3d4aad80" TYPE="ext4" PARTUUID="0004c32e-05"

Разумеется, соответствующий файл появился и в каталоге /dev:

$ ll /dev/disk/by-uuid G 'sdc[5,10]'
lrwxrwxrwx 1 root root 11 дек.  25 15:24 7ba62d76-ab02-11e5-a0fa-5bfcb3a17d1a -> ../../sdc10
lrwxrwxrwx 1 root root 10 дек.  25 15:24 b37e25f5-8538-496d-b8aa-78cc3d4aad80 -> ../../sdc5

Впрочем, опция -U утилиты tune2fs имеет и собственные значения, позволяющие сгенерировать UUID, произвольный или привязанный к временной метке — random и time, соответственно. С этой целью нечувствительно для применителя вызывается команда uuidgen, которая входит в стандартный пакет util-linux, что имеется в любой системе, и потому никаких дополнительных средств не требует. Правда, мне встречалось мнение, что её рэндомизатор «недостаточно рэндомный». Однако думаю, что для десктопных целей он вполне сгодится:

$ sudo tune2fs /dev/sdc10 -U random

Кроме того, опция -U утилиты tune2fs может принимать значение clear — при этом UUID устройства, заданного в качестве аргумента команды, ликвидируется как класс. Правда, есть подозрение, что того же результата можно добиться просто удалением соответствующего симлинка из каталога /dev/disk/by-uuid/.

Сказанное относилось к смене UUID для разделов с файловой системой ext4, работа с которой и поддерживается утилитой tune2fs. Более иные файловые системы, разумеется, потребуют собственных средств. Например, для XFS это будет утилита xfs_admin, входящая в пакет xfsprogs, который и надлежит предварительно установить:

$ sudo apt install xfsprogs

Она имеет аналогичную опцию -U, в качестве значения которой надо подставить вывод команд uuid или uuidgen, для последней, например, так:

$ sudo xfs_admin -U `uuidgen -t` /dev/sdc6
Clearing log and setting UUID
writing all SBs
new UUID = 8948616e-ab08-11e5-8f45-d05099355b49

Операцию по смене пола UUID’а можно проделать и для разделов с файловыми системами reiserfs и jfs. В первом случае так:

$ sudo reiserfstune -u random /dev/sdc7

А во втором — так:

$ sudo jfs_tune -U random /dev/sdc8

Конечно же, предварительно установивши инструментальные пакеты — reiserfsprogs и jfsutils, соответственно.

С прочими нативными файловыми системами Linux’а (btrfs, f2fs, nilfs) предоставляю разбираться заинтересованным лицам. Ну а для ZFS определение UUID’а и тем более его изменение смысла не имеют. Так как ни z-пул, ни его datasets в обыденном смысле монтированию не подлежат.

Изменение UUID’а: 2 комментария

  1. Здесь, наверное, опечатка:
    $ ls /dev/disks/by-uuid

    Должно быть:
    $ ls /dev/disk/by-uuid

Добавить комментарий