Skip to content

fastrapier/net-link-research

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Создание PV

При создании PV получаем вот такой ивент от netlink pvcreate

В этот момент файл в backup не создается

Создание VG

При создании VG получаем вот такой ивент от netlink vgcreate

В этот момент LVM создает файл по пути /etc/lvm/backup/{vg-name} vgcreate

Создание LV

При создании LV получаем вот такие ивенты от netlink lvcreate

В этот момент LVM обновляет файл по пути /etc/lvm/backup/{vg-name} lvcreate

Откуда pvs/vgs/lvs берут данные

Процесс чтения данных (на основе исходного кода LVM2)

Источник: lib/label/label.c

1. Сканирование устройств (label_scan)

При запуске pvs/vgs/lvs LVM выполняет label_scan — сканирует все блочные устройства в системе:

_scan_list() -> bcache_prefetch() -> bcache_get() -> _process_block()

При этом важно разделять общее поведение LVM и поведение конкретного запуска с ограничением устройств. В сохраненном trace для pvs с --devices утилита по-прежнему обходит части /dev и sysfs, но прямой open() по блочному устройству в этом запуске есть только для /dev/sdb. Детальный разбор вынесен в research/pvs/README.MD. Для нашей практической задачи это важно потому, что ограничение списка устройств может уменьшить число обращений к реальным дискам и снизить риск зависания, если один из посторонних дисков застрял в состоянии D.

Каждое устройство открывается через open(), и первые 4096 байт считываются в буфер headers_buf:

#define HEADERS_BUF_SIZE 4096
memcpy(headers_buf, bb->data, HEADERS_BUF_SIZE);

2. Поиск LVM-метки (LABELONE)

В функции _find_lvm_header() LVM ищет метку LABELONE в первых 4-х секторах (по 512 байт) устройства:

for (sector = start_sector; sector < start_sector + LABEL_SCAN_SECTORS;
     sector += LABEL_SIZE >> SECTOR_SHIFT) {
    lh = (struct label_header *) (headers_buf + (sector << SECTOR_SHIFT));
    if (!memcmp(lh->id, LABEL_ID, sizeof(lh->id))) {
        // нашли LVM label
    }
}

По умолчанию метка находится во 2-м секторе (смещение 512 байт от начала устройства).

3. Чтение PV header и MDA

После нахождения метки LVM вызывает labeller->ops->read() (это _text_read()), которая читает:

  • PV header — UUID физического тома, размер, расположение данных
  • MDA header (Metadata Area) — находится по смещению 4096 байт от начала устройства, размер заголовка 512 байт
  • Metadata text — текстовые метаданные в ASCII формате (~1 МиБ по умолчанию), следующие сразу за MDA header

4. Кэширование в lvmcache

Все найденные данные сохраняются в lvmcache — внутренний кэш LVM в оперативной памяти:

// Из комментария в label.c:
// ops->read() is _text_read() which reads the pv_header, mda
// locations, and metadata text. All of the info it finds about the PV
// and VG is stashed in lvmcache which saves it in the form of
// info/vginfo structs.

После этого команды pvs/vgs/lvs форматируют данные из lvmcache и выводят на экран.

Структура метаданных на диске

Смещение 0        -> Sector 0 (может быть пустой или содержать boot record)
Смещение 512      -> Sector 1: LABELONE + PV header (UUID, размеры, указатели на MDA)
Смещение 4096     -> MDA header (512 байт, включает checksum, version, offset на текст)
Смещение ~4608    -> Metadata text (ASCII, ~1 МиБ) — содержит описание VG, LV, PV

Источники:


Структура PV

type PVData struct {
	PVName string            `json:"pv_name,omitempty"`
	VGName string            `json:"vg_name,omitempty"`
	PVSize resource.Quantity `json:"pv_size,omitempty"`
	PVUsed string            `json:"pv_used,omitempty"` -- нигде не используется
	PVUuid string            `json:"pv_uuid,omitempty"`
	VGTags string            `json:"vg_tags,omitempty"`
	VGUuid string            `json:"vg_uuid,omitempty"`
}

Вывод pvs - pvs

Структура VG

type VGData struct {
	VGAttr   string            `json:"vg_attr"` -- нигде не используется
	VGFree   resource.Quantity `json:"vg_free"`
	VGName   string            `json:"vg_name"`
	VGShared string            `json:"vg_shared"`
	VGSize   resource.Quantity `json:"vg_size"`
	VGTags   string            `json:"vg_tags"`
	VGUUID   string            `json:"vg_uuid"`
}

Вывод vgs - vgs

Структура LV

type LVData struct {
	LVName          string            `json:"lv_name"`
	VGName          string            `json:"vg_name"`
	VGUuid          string            `json:"vg_uuid"`
	LVAttr          string            `json:"lv_attr"`
	LVSize          resource.Quantity `json:"lv_size"`
	PoolName        string            `json:"pool_lv"`
	Origin          string            `json:"origin"` -- не используется
	DataPercent     string            `json:"data_percent"`
	MetadataPercent string            `json:"metadata_percent"`
	MovePv          string            `json:"move_pv"` -- не используется
	MirrorLog       string            `json:"mirror_log"` -- не используется
	CopyPercent     string            `json:"copy_percent"` -- не используется
	ConvertLv       string            `json:"convert_lv"` -- не используется
	LvTags          string            `json:"lv_tags"`
	ThinID          string            `json:"thin_id"`
	MetadataLv      string            `json:"metadata_lv"`
	LVDmPath        string            `json:"lv_dm_path"`
}

Вывод lvs - lvs


Результаты исследования

Исследование pvs

Подробнее: research/pvs/README.MD

pvs --devices /dev/sdb ограничивает прямое чтение блочных устройств до целевого диска, но discovery через /dev и /sys остаётся.

Исследование vgs

Подробнее: research/vgs/README.md

  • vgs test-vg (с именем VG) — не ограничивает набор сканируемых дисков (все блочные устройства открываются O_DIRECT), но убирает глобальный лок P_global
  • vgs --devices /dev/sdb test-vg — ограничивает обращения к единственному устройству, но выдаёт warning о missing PV для VG из нескольких дисков

Исследование lvs

Подробнее: research/lvs/README.md

Поведение полностью идентично vgs: targeted запрос не ограничивает диски, только убирает глобальный лок; --devices ограничивает.

Альтернативные источники данных

Подробнее: research/alternatives/README.md

Источник label_scan Блочные устройства LVM-локи D-State risk
pvs/vgs/lvs (full) да все глобальный + VG высокий
pvs/vgs/lvs (targeted) да все VG only средний
pvs/vgs/lvs (--devices) ограниченный 1 устройство VG only ниже
/etc/lvm/backup/ нет нет нет нет
dmsetup нет нет нет нет
udev database нет нет нет нет

Матрица покрытия

Подробнее: research/coverage-matrix.md

Комбинация /etc/lvm/backup/ + dmsetup + udev database покрывает 100% нужных полей PV/VG/LV без единого обращения к блочным устройствам и без LVM-локов.

Стратегический вывод

Подробнее: research/strategy.md

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors