Физическая структура RPM-пакета: Заголовок, метаданные и полезная нагрузка
Любой RPM-пакет, который вы устанавливаете в Rosa Linux, физически представляет собой один бинарный файл с расширением .rpm. Для конечного пользователя это просто «установщик программы», но для мейнтейнера — это строго структурированный контейнер. Понимание того, как байты организованы внутри этого контейнера, позволяет диагностировать ошибки сборки, восстанавливать повреждённые пакеты и оптимизировать процесс доставки ПО.
Файл RPM не является монолитным архивом. Он состоит из четырёх последовательных секций, каждая из которых выполняет свою уникальную задачу. Процесс чтения пакета пакетным менеджером всегда идёт строго сверху вниз.
Четыре кита RPM-пакета
Физическая структура файла делится на следующие блоки (в порядке их расположения):
- Lead (Вводная часть)
- Signature (Подпись)
- Header (Заголовок или Метаданные)
- Payload (Полезная нагрузка)
Рассмотрим каждую секцию под микроскопом.
1. Lead: Историческое наследие и идентификация
Lead — это самая первая структура данных в файле. Её размер всегда строго фиксирован и составляет 96 байт.
Главная задача этой секции — сообщить операционной системе и утилитам (например, команде file), что перед ними именно RPM-пакет, а не MP3-трек или текстовый документ. Это достигается с помощью магического числа (magic number).
Магическое число — это уникальная последовательность байтов в самом начале файла. Для RPM это всегда четыре байта: ed ab ee db (в шестнадцатеричной системе).
Магические числа — стандартный подход в UNIX-подобных системах для определения типа файла без оглядки на его расширение. Вы можете переименовать
package.rpmвpackage.txt, но система всё равно распознает в нём RPM-архив.
Помимо магического числа, Lead содержит:
- Мажорную и минорную версии формата RPM (обычно 3.0).
- Тип пакета (бинарный или исходный — SRPM).
- Архитектуру, для которой собран пакет (например,
x86_64илиaarch64). - Имя пакета (ограничено 66 символами).
Практический нюанс: В современных версиях RPM секция Lead считается устаревшей (legacy). Пакетный менеджер читает из неё только магическое число, чтобы убедиться в правильности формата. Вся остальная информация (имя, архитектура) дублируется и читается из секции Header, так как ограничение в 66 символов для имени пакета давно стало недостаточным.
Вы можете увидеть Lead своими глазами, используя утилиту hexdump, которая выводит содержимое файла в шестнадцатеричном формате:
hexdump -C -n 96 package.rpm
В первой строке вывода вы чётко увидите байты ed ab ee db.
2. Signature: Гарантия целостности и подлинности
Сразу после Lead идёт секция Signature (Подпись). Её расположение неслучайно: пакетный менеджер должен убедиться, что файл не повреждён и получен из доверенного источника, до того, как начнёт распаковывать сложные метаданные или тяжеловесный архив.
Секция подписи содержит криптографические хеши и цифровые подписи:
- MD5 / SHA256 хеши: Гарантируют целостность. Если при скачивании пакета потерялся хотя бы один байт, пересчитанный хеш не совпадёт с тем, что записан в Signature, и установка будет прервана с ошибкой.
- GPG-подпись: Гарантирует подлинность. Она подтверждает, что пакет был собран официальной сборочной системой Rosa Linux (или конкретным разработчиком), и в него не был внедрён вредоносный код третьими лицами.
Если пакет не подписан GPG-ключом, система выдаст предупреждение NOKEY при попытке установки. Для мейнтейнера Rosa Linux подписание своих пакетов перед отправкой в репозиторий — обязательный шаг.
3. Header: Мозг пакета
Header (Заголовок) — это самая важная часть для пакетного менеджера. Именно здесь хранятся все метаданные: зависимости, описание, скрипты установки (pre/post install), список файлов и информация о лицензии.
Структура Header спроектирована как миниатюрная, невероятно быстрая база данных. Она состоит из трёх частей:
- Вводная часть заголовка (Header Structure Header) — содержит магическое число заголовка и размеры следующих блоков.
- Массив индексов (Index Array).
- Хранилище данных (Data Store).
Чтобы понять, как это работает, представим библиотеку. Хранилище данных — это полки с книгами (сами данные), а Массив индексов — это картотека, где написано, на какой полке лежит нужная книга.
Каждая запись в массиве индексов состоит из 16 байт и содержит четыре поля:
- Tag (Тег): Числовой идентификатор того, что мы ищем. Например, тег
1000означает имя пакета,1001— версию,1049— список зависимостей (Requires). - Type (Тип): Тип данных (строка, целое число, массив строк).
- Offset (Смещение): Указатель. Показывает, на сколько байт нужно отступить в Хранилище данных, чтобы начать читать значение.
- Count (Количество): Сколько элементов нужно прочитать.
Такая архитектура позволяет утилите rpm работать молниеносно. Когда вы выполняете команду rpm -qp --requires package.rpm (показать зависимости пакета), утилите не нужно читать весь файл. Она находит тег зависимостей в массиве индексов, смотрит смещение и мгновенно считывает нужные байты из хранилища данных. Полезная нагрузка при этом вообще не затрагивается.
4. Payload: Полезная нагрузка
После того как метаданные закончились, начинается Payload — непосредственно файлы, которые будут установлены в файловую систему Rosa Linux (бинарные исполняемые файлы, библиотеки, конфигурационные файлы, документация).
Полезная нагрузка представляет собой сжатый архив формата cpio (copy in, copy out).
Почему создатели RPM выбрали cpio, а не привычные tar или zip?
cpioисторически лучше работает с жесткими ссылками (hardlinks) и специальными файлами устройств (device nodes).- Формат
cpioпозволяет извлекать файлы потоково, без необходимости читать весь архив целиком или создавать временные индексы в оперативной памяти.
Сам по себе cpio не сжимает данные, он только объединяет их в один поток. Поэтому поверх него применяется алгоритм сжатия. Эволюция алгоритмов сжатия в RPM выглядит так:
| Алгоритм | Скорость распаковки | Степень сжатия | Статус в современных дистрибутивах |
|---|---|---|---|
| gzip | Высокая | Низкая | Устарел, использовался в ранних версиях |
| bzip2 | Низкая | Высокая | Устарел, слишком медленный |
| xz (LZMA) | Средняя | Очень высокая | Долгое время был стандартом |
| zstd | Очень высокая | Высокая | Современный стандарт (в т.ч. для Rosa Linux) |
Современные версии Rosa Linux используют алгоритм zstd (Zstandard). Он обеспечивает степень сжатия на уровне xz, но распаковывается в несколько раз быстрее, что критически важно при обновлении сотен пакетов одновременно.
Практика: Извлечение файлов без установки
Как мейнтейнеру, вам часто придётся заглядывать внутрь пакета, не устанавливая его в систему. Поскольку Payload — это просто сжатый cpio архив, мы можем отделить его от заголовков и распаковать стандартными утилитами.
Для этого используется команда rpm2cpio, которая отрезает Lead, Signature и Header, выдавая в стандартный вывод чистый поток cpio:
# Извлечь содержимое пакета в текущую директорию
rpm2cpio my-package-1.0.rpm | cpio -idmv
Разбор ключей cpio:
-i(extract) — извлечь файлы.-d(make directories) — создавать директории по мере необходимости.-m(preserve modification time) — сохранить оригинальное время изменения файлов.-v(verbose) — выводить список извлекаемых файлов на экран.
Типичные проблемы и подводные камни
Понимание структуры спасает при отладке. Вот несколько частых ситуаций:
-
Ошибка "Header V4 RSA/SHA256 Signature, key ID ...: NOKEY" Система прочитала секцию Signature, нашла там подпись, но в вашей системе нет публичного ключа для её проверки. Пакет не повреждён, проблема в доверии.
-
Ошибка "cpio: read failed - Inappropriate ioctl for device" или "Payload is not an archive" Это означает, что секции Lead и Header прочитались успешно, но система не может распаковать Payload. Чаще всего это происходит, если пакет собран в новом дистрибутиве с использованием сжатия
zstd, а вы пытаетесь установить его в старой системе, где пакетный менеджер понимает толькоxzилиgzip. -
Повреждение файла при передаче (Truncated file) Если файл скачался не до конца, проверка Signature (MD5/SHA) сразу выдаст ошибку. Но если вы принудительно отключите проверку подписи,
rpmсможет прочитать Header (он находится в начале файла), покажет вам список файлов, но при попытке установки упадёт на этапе чтения Payload, так как архив оборван.
Архитектура RPM-пакета — это пример элегантного инженерного решения. Разделение на легковесные метаданные (Header) и тяжеловесный архив (Payload) позволяет пакетным менеджерам мгновенно разрешать зависимости графа из десятков тысяч пакетов, скачивая только заголовки, и загружать полезную нагрузку только тогда, когда план установки полностью утверждён.

