В этой статье я разберу реальный случай очистки старого сервера Proxmox VE, на котором за несколько лет накопились отключённые диски виртуальных машин, orphan volumes и оставшиеся в device-mapper представления разделов гостевых дисков.
После очистки заполнение LVM-thin pool снизилось с 94,00% до 68,17%, а проверка не обнаружила unused-дисков, orphan volumes и оставшихся device-mapper mappings.
В начале я увидел в local-lvm несколько подозрительных пар:
На первый взгляд это выглядело как дублирование виртуальных машин или их дисков.
В результате выяснилось, что проблема состояла сразу из нескольких частей:
В процессе очистки заполнение основного thin-pool удалось снизить с:
до:
То есть фактически я освободил около 430 GiB физического пространства.
На момент работ сервер использовал достаточно старую версию Proxmox VE:
Основное хранилище:
Также присутствовали три отдельных обычных LVM storage:
Сервер к моменту диагностики не перезагружался почти два года:
Результат:
Позже эта деталь оказалась важной.
Первое, что я проверил, — конфигурацию каждой подозрительной VM.
Например:
Я получил:
Это означает:
То же самое было у VM 124:
И у VM 136:
Поэтому ориентироваться только на номер
Рабочий диск определяется конфигурацией VM — например,
Для дополнительной проверки физических volumes я использовал:
Например:
При попытке удалить старый диск непосредственно из списка Storage → local-lvm → VM Disks я получил:
Это нормальная защита Proxmox.
Если диск присутствует в конфигурации VM как:
его следует удалять через:
Но в моём случае и это сначала не сработало.
При удалении через Hardware я получил:
На этом этапе я ничего не стал удалять принудительно.
Я не использовал:
Сначала я посмотрел состояние device-mapper:
И обнаружил:
То есть старый виртуальный диск был разобран на разделы прямо на хосте:
А находившийся внутри гостевой CentOS LVM был активирован уже LVM самого Proxmox-хоста.
Сначала я проверил, что гостевые LVM-тома нигде не смонтированы:
Затем проверил open count:
После того как убедился, что:
я деактивировал только гостевые LV:
После этого mappings разделов имели:
Утилиты
Проверка:
После этого старый диск имел:
и нормально удалился через:
После удаления я проверил:
В результате остался только рабочий диск:
У VM 124 было:
Но внутри старого диска на хосте оказался активирован гостевой LVM:
Диагностика:
Я увидел:
Проверив отсутствие mount:
и убедившись, что этот LV не используется, я деактивировал его:
После этого снял mappings:
Проверил:
И затем удалил Unused Disk 0 через Hardware VM 124.
У VM 136 гостевого LVM поверх старого диска уже не было:
Поэтому достаточно было снять три mappings:
Проверить:
После этого старый диск имел
Один только этот диск освободил около 80 GiB физического пространства.
После ручной очистки нескольких VM я проверил весь сервер:
После удаления известных старых дисков вывод стал пустым.
Это означает, что зарегистрированных
Отсутствие
Я отдельно сравнил все физически существующие volumes в local-lvm с volumes, упоминающимися в конфигурациях VM и контейнеров.
Список физических томов:
Список томов из конфигураций QEMU VM и LXC:
Сравнение:
Я получил:
Это уже выглядело как настоящие orphan volumes.
Перед удалением я проверил каждый VMID по всем конфигурациям:
Для всех получил:
Далее, например:
возвращал:
То же самое было для остальных найденных VMID.
При этом:
показывал реально существующий:
То есть сама VM уже отсутствовала, но её старый LVM volume продолжал существовать и занимать место.
Основными проверками для orphan volume я считал следующие:
Моя версия Proxmox поддерживала:
Вывод:
Больше команда ничего не показала.
Это стало дополнительной проверкой того, что Proxmox не собирался восстанавливать какие-либо найденные volumes как
При этом сам по себе пустой
Основными оставались проверки конфигураций и существования VMID.
Для orphan volume уже нельзя использовать Hardware конкретной VM, потому что самой VM больше нет.
После снятия всех device-mapper зависимостей я удалял такие volumes штатной командой Proxmox:
Например:
Результат:
Важно:
У orphan-диска VM 108 обнаружилась ещё одна интересная ситуация:
Сначала я проверил, какой swap реально используется самим Proxmox:
Получил:
То есть хост использовал pve-swap с major/minor
После этого я деактивировал гостевые LV:
Затем снял mappings:
Проверил:
После того как родительский volume получил
До очистки у найденных orphan volumes были следующие значения:
Только эти orphan volumes занимали примерно 316 GiB реально выделенного пространства.
Основное хранилище у меня было LVM-thin.
Например:
Удаление такого диска освобождает не обязательно все 50 GiB, потому что реально в thin-pool могли быть выделены только использованные блоки.
Приблизительная оценка:
Для оценки я использовал:
Именно поэтому при работе с LVM-thin важен не только
После удаления старых дисков выяснилось, что на хосте всё ещё находятся десятки mappings:
При этом они имели:
Это не дополнительные копии дисков и не отдельные данные VM.
Это только device-mapper mappings разделов внутри существующих виртуальных дисков.
Сначала я сформировал список только тех mappings, которые имели
Здесь перенаправление в файл я специально оставил в той же строке, чтобы визуальный редактор XenForo не попытался интерпретировать строку, начинающуюся с символа
Затем проверил сформированный список:
Изначально у меня было 31 такое устройство.
Для удаления я использовал:
Я принципиально не использовал
На одном из разделов VM 100 я получил:
Хотя ранее mapping имел
Я проверил его отдельно:
Затем дерево зависимостей:
Mount и открытые процессы:
Проверил, не является ли раздел LVM PV:
И наличие LVM-томов поверх него:
Никаких зависимостей обнаружено не было.
После этого я выполнил:
Mappings удалились.
Родительский диск остался:
Проверка:
показала:
То есть
После VM 100 я пересоздал список:
Проверил:
После чего снова выполнил:
На одном из mappings VM 122 появилась кратковременная ошибка:
Но благодаря
После очистки команда:
не выводила ничего.
При этом сами рабочие виртуальные диски оставались:
Например:
Для работающих VM значение
Затем я заново сформировал списки всех volumes и всех volumes из конфигураций:
Сравнение:
Вывод был пустым.
Также:
показал только:
После этого основной local-lvm я считал полностью очищенным.
На сервере также находились три обычных LVM storage:
Сначала такие значения выглядели пугающе.
Но это обычный LVM, а не LVM-thin.
Практически весь объём VG был заранее выделен под большие виртуальные диски:
Поэтому 99.x% у такого storage не означает, что файловая система внутри гостевой VM заполнена на 99%.
Проверка:
показала ровно по одному ожидаемому диску:
Orphan volumes там не было.
У VM 123 и VM 137 присутствовали:
А у VM 140 уже было нормальное состояние без mappings разделов:
Сначала я проверил дерево:
Никаких дополнительных LVM или других device-mapper устройств поверх этих разделов не было.
После этого я снял mappings:
Финальное состояние:
Все три VM были запущены, поэтому
Финальная проверка всех partition mappings:
ничего не вывела.
Здесь удалось установить вторую половину механизма.
В моей конфигурации
То есть этот filter отсеивал
При этом на сервере работала стандартная event-based activation LVM.
Проверка:
показала сервисы вида:
Их команда запуска:
Кроме того, в udev присутствовало:
То есть если в системе появлялся block device с LVM PV гостевой системы, дальше могла происходить следующая цепочка:
Именно так на Proxmox-хосте могли оказаться активированными:
Однозначно установить источник этих partition mappings мне не удалось.
Формат:
характерен для device-mapper представлений разделов, которые могут создавать
Однако на момент диагностики:
ничего не показывал.
Также я не нашёл следов следующих инструментов:
в bash history, локальных скриптах и текущей конфигурации.
Проверка истории пакетов:
тоже ничего не показала.
Поиск в конфигурациях и локальных скриптах:
также был пустым.
Поэтому утверждать, что причиной был именно
Сервер работал непрерывно с:
то есть почти два года.
После ручной очистки команда:
оставалась пустой.
Mappings не возникли повторно.
Это хорошо укладывается в сценарий:
Полностью подтвердить эту версию можно будет после следующей плановой перезагрузки.
Можно было бы пытаться ограничить LVM autoactivation через filters или
Но сервер использовал:
Команда:
ничего не вывела.
Команда:
также была пустой.
При этом неправильный
Поэтому после очистки я решил не менять:
и оставить существующую LVM-конфигурацию без изменений.
После всех операций я проверил:
Рабочие VM-диски выглядели примерно так:
Для работающей VM состояние
Для выключенной VM LV может оставаться активным, но не иметь
Само по себе это не означает orphan volume.
До начала очистки:
После очистки:
Были удалены старые volumes:
Первые три были unused disks существующих VM.
Остальные шесть были подтверждёнными orphan volumes.
Для этих orphan volumes одновременно выполнялись условия:
В результате было освобождено примерно:
реального пространства основного thin-pool.
Если я снова столкнусь с подобной ситуацией, буду действовать именно в таком порядке.
Нужно определить:
Имена:
являются только именами volumes.
Рабочим вполне может быть
Сначала я убеждаюсь, что гостевой LV нигде не используется.
После этого деактивирую именно гостевой LV:
Проверяю
И снимаю только mappings с
Без
Удаляю через:
После всех проверок:
Эта команда окончательно удаляет данные указанного volume.
Для основного
Сравнение:
В нормальном состоянии вывод должен быть пустым.
На моей версии:
После моей очистки вывод был пустым.
И общий статус storage:
Поскольку я предполагаю, что mappings являлись историческими остатками почти двухлетнего uptime, окончательная проверка будет после следующей плановой перезагрузки.
Перед reboot можно сохранить текущее состояние:
После reboot:
Если вывод останется пустым, это будет сильным подтверждением того, что проблема действительно была связана со старыми накопившимися mappings.
Также я проверю:
На хосте не должны самопроизвольно появиться гостевые VG и LV вроде:
Главный вывод, который я сделал после этой чистки: наличие нескольких volumes вида
Сначала нужно определить, какой volume действительно подключён к VM, какой зарегистрирован как
Особенно осторожно нужно работать с LVM и LVM-thin, потому что поверх виртуального диска могут оставаться device-mapper mappings его разделов, а LVM хоста способен увидеть LVM PV гостевой операционной системы и автоматически активировать находящиеся внутри VG/LV.
Поэтому мой порядок действий теперь такой:
конфигурация VM → проверка storage → device-mapper → mount/swap → гостевой LVM → снятие mappings → удаление volume.
Я не использую массовые
В моём случае такой подход позволил без потери рабочих данных убрать старые unused и orphan-диски, очистить накопившиеся device-mapper mappings и снизить заполнение основного LVM-thin pool с 94.00% до 68.17%.
После очистки заполнение LVM-thin pool снизилось с 94,00% до 68,17%, а проверка не обнаружила unused-дисков, orphan volumes и оставшихся device-mapper mappings.
В начале я увидел в local-lvm несколько подозрительных пар:
Код:
vm-102-disk-0
vm-102-disk-1
vm-124-disk-0
vm-124-disk-1
vm-136-disk-0
vm-136-disk-1
На первый взгляд это выглядело как дублирование виртуальных машин или их дисков.
В результате выяснилось, что проблема состояла сразу из нескольких частей:
- старые диски, зарегистрированные в Proxmox как unused0;
- настоящие orphan volumes — физические LVM-тома, которые уже не принадлежали ни одной существующей VM;
- оставшиеся device-mapper mappings разделов вида
vm-XXX-disk-0p1,p2,p3и т. д.; - автоматически активированные на самом гипервизоре LVM-тома гостевых операционных систем;
- почти заполненный LVM-thin pool.
В процессе очистки заполнение основного thin-pool удалось снизить с:
Код:
94.00%
до:
Код:
68.17%
То есть фактически я освободил около 430 GiB физического пространства.
Исходная конфигурация
На момент работ сервер использовал достаточно старую версию Proxmox VE:
Код:
proxmox-ve: 7.1-1
pve-manager: 7.1-7
kernel: 5.13.19-2-pve
lvm2: 2.03.11
Основное хранилище:
Код:
lvmthin: local-lvm
thinpool data
vgname pve
content images,rootdir
Также присутствовали три отдельных обычных LVM storage:
Код:
lvm: local-lvm-3
vgname local-lvm-3
content rootdir,images
nodes pve
shared 0
lvm: local-lvm-4
vgname local-lvm-4
content images,rootdir
nodes pve
shared 0
lvm: local-lvm-5
vgname local-lvm-5
content rootdir,images
nodes pve
shared 0
Сервер к моменту диагностики не перезагружался почти два года:
Код:
uptime -s
uptime -p
Результат:
Код:
2024-08-18 16:54:02
up 1 year, 51 weeks, 4 days, 23 hours, 48 minutes
Позже эта деталь оказалась важной.
disk-0 и disk-1 не означают дубликаты
Первое, что я проверил, — конфигурацию каждой подозрительной VM.
Например:
Код:
qm config 102
Я получил:
Код:
scsi0: local-lvm:vm-102-disk-1,size=32G
unused0: local-lvm:vm-102-disk-0
Это означает:
Код:
vm-102-disk-1 = текущий рабочий диск
vm-102-disk-0 = старый отключённый диск
То же самое было у VM 124:
Код:
scsi0: local-lvm:vm-124-disk-1,size=50G
unused0: local-lvm:vm-124-disk-0
И у VM 136:
Код:
scsi0: local-lvm:vm-136-disk-1,size=80G
unused0: local-lvm:vm-136-disk-0
Поэтому ориентироваться только на номер
disk-0 или disk-1 нельзя.Рабочий диск определяется конфигурацией VM — например,
scsi0, virtio0 или sata0.Для дополнительной проверки физических volumes я использовал:
Код:
pvesm list local-lvm --vmid 102
Например:
Код:
Volid Format Type Size VMID
local-lvm:vm-102-disk-0 raw images 53687091200 102
local-lvm:vm-102-disk-1 raw images 34359738368 102
Почему Proxmox не дал удалить диск из Storage
При попытке удалить старый диск непосредственно из списка Storage → local-lvm → VM Disks я получил:
Код:
Cannot remove image, a guest with VMID '102' exists!
You can delete the image from the guest's hardware pane
Это нормальная защита Proxmox.
Если диск присутствует в конфигурации VM как:
Код:
unused0: local-lvm:vm-102-disk-0
его следует удалять через:
Код:
VM → Hardware → Unused Disk → Remove
Но в моём случае и это сначала не сработало.
Ошибка Logical volume is used by another device
При удалении через Hardware я получил:
Код:
lvremove 'pve/vm-102-disk-0' error:
Logical volume pve/vm-102-disk-0 is used by another device.
На этом этапе я ничего не стал удалять принудительно.
Я не использовал:
Код:
lvremove -f
dmsetup remove -f
wipefs
Сначала я посмотрел состояние device-mapper:
Код:
dmsetup info -c -o name,major,minor,attr,open | grep -E 'Name|102'
dmsetup ls --tree
И обнаружил:
Код:
centos-root
└─pve-vm--102--disk--0p2
└─pve-vm--102--disk--0
centos-swap
└─pve-vm--102--disk--0p2
└─pve-vm--102--disk--0
То есть старый виртуальный диск был разобран на разделы прямо на хосте:
Код:
pve-vm--102--disk--0p1
pve-vm--102--disk--0p2
А находившийся внутри гостевой CentOS LVM был активирован уже LVM самого Proxmox-хоста.
Как я безопасно освободил старый диск VM 102
Сначала я проверил, что гостевые LVM-тома нигде не смонтированы:
Код:
findmnt -S /dev/mapper/centos-root
findmnt -S /dev/mapper/centos-swap
swapon --show
Затем проверил open count:
Код:
dmsetup info -c -o name,open | grep -E 'centos|102'
После того как убедился, что:
Код:
centos-root Open 0
centos-swap Open 0
я деактивировал только гостевые LV:
Код:
lvchange -an centos/root
lvchange -an centos/swap
После этого mappings разделов имели:
Код:
pve-vm--102--disk--0p1 0
pve-vm--102--disk--0p2 0
Утилиты
kpartx на сервере не оказалось, поэтому mappings я снял напрямую:
Код:
dmsetup remove pve-vm--102--disk--0p1
dmsetup remove pve-vm--102--disk--0p2
Проверка:
Код:
dmsetup info -c -o name,open | grep 102
После этого старый диск имел:
Код:
pve-vm--102--disk--0 0
и нормально удалился через:
Код:
VM 102 → Hardware → Unused Disk 0 → Remove
После удаления я проверил:
Код:
qm config 102
pvesm list local-lvm --vmid 102
В результате остался только рабочий диск:
Код:
scsi0: local-lvm:vm-102-disk-1,size=32G
Аналогичный случай с Ubuntu на VM 124
У VM 124 было:
Код:
scsi0: local-lvm:vm-124-disk-1,size=50G
unused0: local-lvm:vm-124-disk-0
Но внутри старого диска на хосте оказался активирован гостевой LVM:
Код:
ubuntu-vg/ubuntu-lv
Диагностика:
Код:
dmsetup info -c -o name,open | grep -E 'ubuntu|124'
lvs -o vg_name,lv_name,lv_attr,lv_size,devices | grep -E 'ubuntu|124'
Я увидел:
Код:
ubuntu-vg ubuntu-lv 24.50g /dev/mapper/pve-vm--124--disk--0p3
Проверив отсутствие mount:
Код:
findmnt | grep -E 'ubuntu--vg|vm--124'
и убедившись, что этот LV не используется, я деактивировал его:
Код:
lvchange -an ubuntu-vg/ubuntu-lv
После этого снял mappings:
Код:
dmsetup remove pve-vm--124--disk--0p1
dmsetup remove pve-vm--124--disk--0p2
dmsetup remove pve-vm--124--disk--0p3
Проверил:
Код:
dmsetup info -c -o name,open | grep 124
И затем удалил Unused Disk 0 через Hardware VM 124.
VM 136 — только partition mappings
У VM 136 гостевого LVM поверх старого диска уже не было:
Код:
pve-vm--136--disk--0 3
pve-vm--136--disk--0p1 0
pve-vm--136--disk--0p2 0
pve-vm--136--disk--0p3 0
Поэтому достаточно было снять три mappings:
Код:
dmsetup remove pve-vm--136--disk--0p1
dmsetup remove pve-vm--136--disk--0p2
dmsetup remove pve-vm--136--disk--0p3
Проверить:
Код:
dmsetup info -c -o name,open | grep 136
После этого старый диск имел
Open 0 и нормально удалился через:
Код:
VM 136 → Hardware → Unused Disk 0 → Remove
Один только этот диск освободил около 80 GiB физического пространства.
Поиск всех unused-дисков
После ручной очистки нескольких VM я проверил весь сервер:
Код:
for id in $(qm list | awk 'NR>1 {print $1}'); do
unused=$(qm config "$id" | grep '^unused')
if [ -n "$unused" ]; then
echo "=== VM $id ==="
echo "$unused"
fi
done
После удаления известных старых дисков вывод стал пустым.
Это означает, что зарегистрированных
unused0, unused1 и т. д. больше не осталось.Поиск настоящих orphan volumes
Отсутствие
unused ещё не означает, что storage полностью чист.Я отдельно сравнил все физически существующие volumes в local-lvm с volumes, упоминающимися в конфигурациях VM и контейнеров.
Список физических томов:
Код:
pvesm list local-lvm | awk 'NR>1 {print $1}' | grep '^local-lvm:vm-' | sort -u > /tmp/local-lvm-all.txt
Список томов из конфигураций QEMU VM и LXC:
Код:
grep -rhoE 'local-lvm:vm-[0-9]+-disk-[0-9]+' /etc/pve/qemu-server/*.conf /etc/pve/lxc/*.conf 2>/dev/null | sort -u > /tmp/local-lvm-used.txt
Сравнение:
Код:
comm -23 /tmp/local-lvm-all.txt /tmp/local-lvm-used.txt
Я получил:
Код:
local-lvm:vm-108-disk-0
local-lvm:vm-115-disk-0
local-lvm:vm-132-disk-0
local-lvm:vm-134-disk-0
local-lvm:vm-138-disk-0
local-lvm:vm-139-disk-0
Это уже выглядело как настоящие orphan volumes.
Дополнительная проверка orphan volumes
Перед удалением я проверил каждый VMID по всем конфигурациям:
Код:
for id in 108 115 132 134 138 139; do
echo "===== VM $id ====="
grep -R "local-lvm:vm-$id-disk-0" /etc/pve/nodes/*/qemu-server /etc/pve/nodes/*/lxc 2>/dev/null || echo "NO CONFIG REFERENCE"
done
Для всех получил:
Код:
NO CONFIG REFERENCE
Далее, например:
Код:
qm config 108
возвращал:
Код:
Configuration file 'nodes/pve/qemu-server/108.conf' does not exist
То же самое было для остальных найденных VMID.
При этом:
Код:
pvesm list local-lvm --vmid 108
показывал реально существующий:
Код:
local-lvm:vm-108-disk-0
То есть сама VM уже отсутствовала, но её старый LVM volume продолжал существовать и занимать место.
Основными проверками для orphan volume я считал следующие:
- volume физически существует;
- ссылки на него в конфигурациях VM и LXC отсутствуют;
- VM с соответствующим VMID не существует.
Дополнительная проверка через qm rescan
Моя версия Proxmox поддерживала:
Код:
qm rescan --dryrun 1
Вывод:
Код:
NOTE: running in dry-run mode, won't write changes out!
rescan volumes...
Больше команда ничего не показала.
Это стало дополнительной проверкой того, что Proxmox не собирался восстанавливать какие-либо найденные volumes как
unused существующих VM.При этом сам по себе пустой
qm rescan я не считал достаточным доказательством orphan volume.Основными оставались проверки конфигураций и существования VMID.
Удаление orphan volume
Для orphan volume уже нельзя использовать Hardware конкретной VM, потому что самой VM больше нет.
После снятия всех device-mapper зависимостей я удалял такие volumes штатной командой Proxmox:
Код:
pvesm free local-lvm:vm-XXX-disk-0
Например:
Код:
pvesm free local-lvm:vm-108-disk-0
Результат:
Код:
Logical volume "vm-108-disk-0" successfully removed
Removed volume 'local-lvm:vm-108-disk-0'
Важно:
pvesm free окончательно удаляет содержимое volume. Я использовал эту команду только после полной проверки конкретного диска.VM 108 и гостевой cl-root/cl-swap
У orphan-диска VM 108 обнаружилась ещё одна интересная ситуация:
Код:
cl-root
└─pve-vm--108--disk--0p2
cl-swap
└─pve-vm--108--disk--0p2
Сначала я проверил, какой swap реально используется самим Proxmox:
Код:
dmsetup info -c -o name,major,minor | grep -E 'pve-swap|cl-swap'
swapon --show
Получил:
Код:
cl-swap 253 66
pve-swap 253 1
NAME TYPE SIZE USED PRIO
/dev/dm-1 partition 8G 4G -2
То есть хост использовал pve-swap с major/minor
253:1, а не гостевой cl-swap с 253:66.После этого я деактивировал гостевые LV:
Код:
lvchange -an cl/root
lvchange -an cl/swap
Затем снял mappings:
Код:
dmsetup remove pve-vm--108--disk--0p1
dmsetup remove pve-vm--108--disk--0p2
Проверил:
Код:
dmsetup info -c -o name,open | grep 108
После того как родительский volume получил
Open 0, я удалил orphan:
Код:
pvesm free local-lvm:vm-108-disk-0
Сколько места занимали найденные orphan volumes
До очистки у найденных orphan volumes были следующие значения:
Код:
vm-108-disk-0 70G × 42.80% ≈ 30 GiB
vm-115-disk-0 32G × 82.99% ≈ 27 GiB
vm-132-disk-0 50G × 67.84% ≈ 34 GiB
vm-134-disk-0 80G × 90.72% ≈ 73 GiB
vm-138-disk-0 80G × 90.50% ≈ 72 GiB
vm-139-disk-0 80G × 100.00% ≈ 80 GiB
Только эти orphan volumes занимали примерно 316 GiB реально выделенного пространства.
Почему LSize не равен реально освобождённому месту в LVM-thin
Основное хранилище у меня было LVM-thin.
Например:
Код:
vm-102-disk-0
LSize: 50G
Data%: 28.80
Удаление такого диска освобождает не обязательно все 50 GiB, потому что реально в thin-pool могли быть выделены только использованные блоки.
Приблизительная оценка:
Код:
50 × 0.288 ≈ 14.4 GiB
Для оценки я использовал:
Код:
lvs -o lv_name,lv_size,data_percent pve
Именно поэтому при работе с LVM-thin важен не только
LSize, но и Data%.Очистка оставшихся partition mappings рабочих VM
После удаления старых дисков выяснилось, что на хосте всё ещё находятся десятки mappings:
Код:
pve-vm--100--disk--0p1
pve-vm--100--disk--0p2
pve-vm--100--disk--0p3
При этом они имели:
Код:
Open 0
Это не дополнительные копии дисков и не отдельные данные VM.
Это только device-mapper mappings разделов внутри существующих виртуальных дисков.
Сначала я сформировал список только тех mappings, которые имели
Open 0:
Код:
dmsetup info -c --noheadings --separator ':' -o name,open | awk -F: '$2 == 0 && $1 ~ /^pve-vm--[0-9]+--disk--[0-9]+p[0-9]+$/ {print $1}' > /root/pve-partmaps-to-remove.txt
Здесь перенаправление в файл я специально оставил в той же строке, чтобы визуальный редактор XenForo не попытался интерпретировать строку, начинающуюся с символа
>, как цитату.Затем проверил сформированный список:
Код:
wc -l /root/pve-partmaps-to-remove.txt
cat /root/pve-partmaps-to-remove.txt
Изначально у меня было 31 такое устройство.
Для удаления я использовал:
Код:
udevadm settle
while IFS= read -r map; do
echo "Removing $map"
dmsetup remove --retry "$map" || {
echo "FAILED: $map"
break
}
done < /root/pve-partmaps-to-remove.txt
Я принципиально не использовал
--force.Device or resource busy при Open 0
На одном из разделов VM 100 я получил:
Код:
device-mapper: remove ioctl on pve-vm--100--disk--0p3 failed: Device or resource busy
Command failed.
Хотя ранее mapping имел
Open 0.Я проверил его отдельно:
Код:
dmsetup info -c -o name,major,minor,open | grep -E 'vm--100--disk--0|pve-swap'
Затем дерево зависимостей:
Код:
dmsetup ls --tree | grep -A12 -B5 'pve-vm--100--disk--0p3'
Mount и открытые процессы:
Код:
findmnt -S /dev/mapper/pve-vm--100--disk--0p3
fuser -vm /dev/mapper/pve-vm--100--disk--0p3
Проверил, не является ли раздел LVM PV:
Код:
pvs -o pv_name,vg_name,pv_attr,pv_size,pv_free | grep 'pve-vm--100--disk--0p3'
И наличие LVM-томов поверх него:
Код:
lvs -a -o vg_name,lv_name,lv_attr,lv_size,devices | grep -E 'pve-vm--100--disk--0p3|vm-100'
Никаких зависимостей обнаружено не было.
После этого я выполнил:
Код:
udevadm settle
dmsetup remove --retry pve-vm--100--disk--0p3
dmsetup remove --retry pve-vm--100--disk--0p4
dmsetup remove --retry pve-vm--100--disk--0p5
Mappings удалились.
Родительский диск остался:
Код:
pve-vm--100--disk--0 1
Проверка:
Код:
qm status 100
показала:
Код:
status: running
То есть
Open 1 был нормальным открытием диска работающей виртуальной машиной.Массовая очистка остальных свободных mappings
После VM 100 я пересоздал список:
Код:
dmsetup info -c --noheadings --separator ':' -o name,open | awk -F: '$2 == 0 && $1 ~ /^pve-vm--[0-9]+--disk--[0-9]+p[0-9]+$/ {print $1}' > /root/pve-partmaps-to-remove.txt
Проверил:
Код:
wc -l /root/pve-partmaps-to-remove.txt
cat /root/pve-partmaps-to-remove.txt
После чего снова выполнил:
Код:
udevadm settle
while IFS= read -r map; do
echo "Removing $map"
dmsetup remove --retry "$map" || {
echo "FAILED: $map"
break
}
done < /root/pve-partmaps-to-remove.txt
На одном из mappings VM 122 появилась кратковременная ошибка:
Код:
device-mapper: remove ioctl on pve-vm--122--disk--0p1 failed: Device or resource busy
Но благодаря
--retry удаление в итоге прошло, и итоговая проверка стала пустой:
Код:
dmsetup info -c -o name,open | grep -E 'pve-vm--.*disk--.*p[0-9]+'
Финальная проверка основного local-lvm
После очистки команда:
Код:
dmsetup info -c -o name,open | grep -E 'pve-vm--.*disk--.*p[0-9]+'
не выводила ничего.
При этом сами рабочие виртуальные диски оставались:
Код:
dmsetup info -c -o name,open | grep '^pve-vm'
Например:
Код:
pve-vm--100--disk--0 1
pve-vm--101--disk--0 1
pve-vm--102--disk--1 0
pve-vm--103--disk--0 1
Для работающих VM значение
Open 1 является ожидаемым.Затем я заново сформировал списки всех volumes и всех volumes из конфигураций:
Код:
pvesm list local-lvm | awk 'NR>1 {print $1}' | grep '^local-lvm:vm-' | sort -u > /tmp/local-lvm-all.txt
Код:
grep -rhoE 'local-lvm:vm-[0-9]+-disk-[0-9]+' /etc/pve/qemu-server/*.conf /etc/pve/lxc/*.conf 2>/dev/null | sort -u > /tmp/local-lvm-used.txt
Сравнение:
Код:
comm -23 /tmp/local-lvm-all.txt /tmp/local-lvm-used.txt
Вывод был пустым.
Также:
Код:
qm rescan --dryrun 1
показал только:
Код:
NOTE: running in dry-run mode, won't write changes out!
rescan volumes...
После этого основной local-lvm я считал полностью очищенным.
Отдельные storage local-lvm-3, local-lvm-4 и local-lvm-5
На сервере также находились три обычных LVM storage:
Код:
local-lvm-3 99.23%
local-lvm-4 99.81%
local-lvm-5 99.90%
Сначала такие значения выглядели пугающе.
Но это обычный LVM, а не LVM-thin.
Практически весь объём VG был заранее выделен под большие виртуальные диски:
Код:
VM 123:
scsi0: local-lvm-3:vm-123-disk-0,size=5546G
VM 137:
scsi0: local-lvm-4:vm-137-disk-0,size=13014G
VM 140:
scsi0: local-lvm-5:vm-140-disk-0,size=20470G
Поэтому 99.x% у такого storage не означает, что файловая система внутри гостевой VM заполнена на 99%.
Проверка:
Код:
pvesm list local-lvm-3
pvesm list local-lvm-4
pvesm list local-lvm-5
показала ровно по одному ожидаемому диску:
Код:
local-lvm-3:vm-123-disk-0
local-lvm-4:vm-137-disk-0
local-lvm-5:vm-140-disk-0
Orphan volumes там не было.
Очистка mappings на других LVM storage
У VM 123 и VM 137 присутствовали:
Код:
local--lvm--3-vm--123--disk--0p1
local--lvm--3-vm--123--disk--0p2
local--lvm--3-vm--123--disk--0p3
local--lvm--3-vm--123--disk--0p4
local--lvm--4-vm--137--disk--0p1
local--lvm--4-vm--137--disk--0p2
local--lvm--4-vm--137--disk--0p3
local--lvm--4-vm--137--disk--0p4
А у VM 140 уже было нормальное состояние без mappings разделов:
Код:
local--lvm--5-vm--140--disk--0 1
Сначала я проверил дерево:
Код:
dmsetup ls --tree | grep -E -A8 -B3 'local--lvm--(3-vm--123|4-vm--137)--disk--0p'
Никаких дополнительных LVM или других device-mapper устройств поверх этих разделов не было.
После этого я снял mappings:
Код:
udevadm settle
dmsetup remove --retry local--lvm--3-vm--123--disk--0p1
dmsetup remove --retry local--lvm--3-vm--123--disk--0p2
dmsetup remove --retry local--lvm--3-vm--123--disk--0p3
dmsetup remove --retry local--lvm--3-vm--123--disk--0p4
dmsetup remove --retry local--lvm--4-vm--137--disk--0p1
dmsetup remove --retry local--lvm--4-vm--137--disk--0p2
dmsetup remove --retry local--lvm--4-vm--137--disk--0p3
dmsetup remove --retry local--lvm--4-vm--137--disk--0p4
Финальное состояние:
Код:
local--lvm--3-vm--123--disk--0 1
local--lvm--4-vm--137--disk--0 1
local--lvm--5-vm--140--disk--0 1
Все три VM были запущены, поэтому
Open 1 здесь является нормальным состоянием.Финальная проверка всех partition mappings:
Код:
dmsetup info -c --noheadings --separator ':' -o name,open | grep -E 'disk--[0-9]+p[0-9]+'
ничего не вывела.
Откуда взялись гостевые LVM на самом Proxmox
Здесь удалось установить вторую половину механизма.
В моей конфигурации
/etc/lvm/lvm.conf присутствовал:
Код:
global_filter=["r|/dev/zd.*|"]
То есть этот filter отсеивал
/dev/zd*, но не исключал device-mapper устройства вида:
Код:
/dev/mapper/pve-vm--108--disk--0p2
При этом на сервере работала стандартная event-based activation LVM.
Проверка:
Код:
systemctl status 'lvm2-pvscan@*' --no-pager
показала сервисы вида:
Код:
lvm2-pvscan@8:19.service
lvm2-pvscan@8:0.service
lvm2-pvscan@8:48.service
lvm2-pvscan@8:32.service
Их команда запуска:
Код:
ExecStart=/sbin/lvm pvscan --cache --activate ay %i
Кроме того, в udev присутствовало:
Код:
ENV{SYSTEMD_WANTS}+="lvm2-pvscan@$major:$minor.service"
То есть если в системе появлялся block device с LVM PV гостевой системы, дальше могла происходить следующая цепочка:
Код:
partition mapping
↓
udev
↓
lvm2-pvscan@
↓
pvscan --cache --activate ay
↓
активация гостевого VG/LV
Именно так на Proxmox-хосте могли оказаться активированными:
Код:
centos-root
centos-swap
cl-root
cl-swap
ubuntu-vg/ubuntu-lv
Кто первоначально создал p1, p2, p3 и другие mappings
Однозначно установить источник этих partition mappings мне не удалось.
Формат:
Код:
vm--XXX--disk--0p1
vm--XXX--disk--0p2
vm--XXX--disk--0p3
характерен для device-mapper представлений разделов, которые могут создавать
kpartx и похожие инструменты.Однако на момент диагностики:
Код:
dpkg -l | grep -Ei 'kpartx|multipath|libguestfs'
ничего не показывал.
Также я не нашёл следов следующих инструментов:
Код:
kpartx
partx
qemu-nbd
guestmount
guestfish
в bash history, локальных скриптах и текущей конфигурации.
Проверка истории пакетов:
Код:
zgrep -hiE 'kpartx|multipath-tools|libguestfs' /var/log/apt/history.log* /var/log/dpkg.log* 2>/dev/null
тоже ничего не показала.
Поиск в конфигурациях и локальных скриптах:
Код:
grep -RniE '\b(kpartx|partx|dmsetup[[:space:]]+create|qemu-nbd|guestmount|guestfish)\b' /etc /usr/local /root 2>/dev/null
также был пустым.
Поэтому утверждать, что причиной был именно
kpartx, я не могу.Почему я считаю mappings историческими leftovers
Сервер работал непрерывно с:
Код:
2024-08-18 16:54:02
то есть почти два года.
После ручной очистки команда:
Код:
dmsetup info -c --noheadings -o name,open | grep -E 'disk--[0-9]+p[0-9]+'
оставалась пустой.
Mappings не возникли повторно.
Это хорошо укладывается в сценарий:
Код:
когда-то был запущен инструмент
↓
были созданы p1, p2, p3 и другие mappings
↓
LVM хоста увидел гостевые LVM PV
↓
автоматически активировались гостевые VG/LV
↓
инструмент перестал использоваться или был удалён
↓
mappings продолжили жить в device-mapper
↓
из-за почти двухлетнего uptime они оставались в системе до момента очистки
Полностью подтвердить эту версию можно будет после следующей плановой перезагрузки.
Почему я не стал менять lvm.conf
Можно было бы пытаться ограничить LVM autoactivation через filters или
auto_activation_volume_list.Но сервер использовал:
Код:
Proxmox VE 7.1
LVM 2.03.11
Команда:
Код:
lvmconfig --type full activation/auto_activation_volume_list
ничего не вывела.
Команда:
Код:
lvmconfig --type current | grep -A10 -B3 auto_activation
также была пустой.
При этом неправильный
global_filter или неправильная activation policy на гипервизоре потенциально могут создать гораздо более серьёзные проблемы, чем уже удалённые stale mappings.Поэтому после очистки я решил не менять:
Код:
/etc/lvm/lvm.conf
и оставить существующую LVM-конфигурацию без изменений.
Состояние LVM после очистки
После всех операций я проверил:
Код:
lvs -a -o vg_name,lv_name,lv_attr,lv_active,lv_device_open
Рабочие VM-диски выглядели примерно так:
Код:
VG LV Attr Active DevOpen
local-lvm-3 vm-123-disk-0 -wi-ao---- active open
local-lvm-4 vm-137-disk-0 -wi-ao---- active open
local-lvm-5 vm-140-disk-0 -wi-ao---- active open
pve vm-100-disk-0 Vwi-aotz-- active open
pve vm-101-disk-0 Vwi-aotz-- active open
pve vm-102-disk-1 Vwi-a-tz-- active
pve vm-124-disk-1 Vwi-a-tz-- active
pve vm-136-disk-1 Vwi-aotz-- active open
Для работающей VM состояние
active/open является ожидаемым.Для выключенной VM LV может оставаться активным, но не иметь
DevOpen.Само по себе это не означает orphan volume.
Что получилось в итоге
До начала очистки:
Код:
pve/data Data%: 94.00%
После очистки:
Код:
pve/data Data%: 68.17%
Были удалены старые volumes:
Код:
vm-102-disk-0
vm-124-disk-0
vm-136-disk-0
vm-108-disk-0
vm-115-disk-0
vm-132-disk-0
vm-134-disk-0
vm-138-disk-0
vm-139-disk-0
Первые три были unused disks существующих VM.
Остальные шесть были подтверждёнными orphan volumes.
Для этих orphan volumes одновременно выполнялись условия:
- не существовало соответствующей конфигурации VM;
- не было ссылок на volume из конфигураций
qemu-serverили LXC; - сам LVM volume физически продолжал существовать.
В результате было освобождено примерно:
Код:
430 GiB
реального пространства основного thin-pool.
Мой алгоритм безопасной очистки
Если я снова столкнусь с подобной ситуацией, буду действовать именно в таком порядке.
1. Проверить конфигурацию VM
Код:
qm config VMID
pvesm list STORAGE --vmid VMID
Нужно определить:
Код:
scsi0 / virtio0 / sata0 = рабочий диск
unused0 = отключённый диск
2. Не считать disk-0 автоматически старым
Имена:
Код:
disk-0
disk-1
disk-2
являются только именами volumes.
Рабочим вполне может быть
disk-1, а старым — disk-0.3. Если unused не удаляется — проверить device-mapper
Код:
dmsetup info -c -o name,open | grep VMID
dmsetup ls --tree
4. Проверить mount и swap
Код:
findmnt
swapon --show
fuser -vm DEVICE
5. Если поверх старого диска активирован гостевой LVM
Сначала я убеждаюсь, что гостевой LV нигде не используется.
После этого деактивирую именно гостевой LV:
Код:
lvchange -an VG/LV
6. Удалять только свободные partition mappings
Проверяю
Open:
Код:
dmsetup info -c -o name,open
И снимаю только mappings с
Open 0:
Код:
dmsetup remove --retry MAPPING
Без
--force.7. Для unused существующей VM
Удаляю через:
Код:
VM → Hardware → Unused Disk → Remove
8. Для подтверждённого orphan volume
После всех проверок:
Код:
pvesm free STORAGE:vm-XXX-disk-N
Эта команда окончательно удаляет данные указанного volume.
9. Найти все orphan volumes
Для основного
local-lvm:
Код:
pvesm list local-lvm | awk 'NR>1 {print $1}' | grep '^local-lvm:vm-' | sort -u > /tmp/local-lvm-all.txt
Код:
grep -rhoE 'local-lvm:vm-[0-9]+-disk-[0-9]+' /etc/pve/qemu-server/*.conf /etc/pve/lxc/*.conf 2>/dev/null | sort -u > /tmp/local-lvm-used.txt
Сравнение:
Код:
comm -23 /tmp/local-lvm-all.txt /tmp/local-lvm-used.txt
В нормальном состоянии вывод должен быть пустым.
10. Проверить Proxmox rescan
На моей версии:
Код:
qm rescan --dryrun 1
11. Проверить остаточные partition mappings
Код:
dmsetup info -c --noheadings --separator ':' -o name,open | grep -E 'disk--[0-9]+p[0-9]+'
После моей очистки вывод был пустым.
12. Проверить заполнение thin-pool
Код:
lvs -o lv_name,lv_size,data_percent pve
И общий статус storage:
Код:
pvesm status
Что проверить после следующей перезагрузки
Поскольку я предполагаю, что mappings являлись историческими остатками почти двухлетнего uptime, окончательная проверка будет после следующей плановой перезагрузки.
Перед reboot можно сохранить текущее состояние:
Код:
dmsetup info -c --noheadings -o name,open > /root/dmsetup-before-reboot.txt
После reboot:
Код:
dmsetup info -c --noheadings -o name,open | grep -E 'disk--[0-9]+p[0-9]+'
Если вывод останется пустым, это будет сильным подтверждением того, что проблема действительно была связана со старыми накопившимися mappings.
Также я проверю:
Код:
pvs
vgs
lvs -a -o vg_name,lv_name,lv_attr,lv_active,lv_device_open
На хосте не должны самопроизвольно появиться гостевые VG и LV вроде:
Код:
centos
cl
ubuntu-vg
Вывод
Главный вывод, который я сделал после этой чистки: наличие нескольких volumes вида
vm-XXX-disk-N ещё не означает дублирование виртуальной машины.Сначала нужно определить, какой volume действительно подключён к VM, какой зарегистрирован как
unused, а какой вообще больше не связан ни с одной существующей конфигурацией.Особенно осторожно нужно работать с LVM и LVM-thin, потому что поверх виртуального диска могут оставаться device-mapper mappings его разделов, а LVM хоста способен увидеть LVM PV гостевой операционной системы и автоматически активировать находящиеся внутри VG/LV.
Поэтому мой порядок действий теперь такой:
конфигурация VM → проверка storage → device-mapper → mount/swap → гостевой LVM → снятие mappings → удаление volume.
Я не использую массовые
lvremove -f и dmsetup remove -f, пока точно не установлено, что именно держит конкретный диск.В моём случае такой подход позволил без потери рабочих данных убрать старые unused и orphan-диски, очистить накопившиеся device-mapper mappings и снизить заполнение основного LVM-thin pool с 94.00% до 68.17%.