Зависшая блокировка файлов виртуальной машины VMware

Справочник системного администратора

Данная статья расскажет, как убрать зависшую блокировку файлов виртуальных машин в VMware ESXi.

Симптомы:
Внезапно пропал доступ к виртуалке на vmware, нет ни пинга, ни RDP.

В vCenter виртуалка vm-name в состоянии «недоступна», на вкладке Tasks&Events – ошибка «файл конфигурации недоступен». Состояние виртуалки меняется на разные степени недоступности (unknown/unaccessible) туда и обратно каждые секунд 10.

Лечение:
1) При попытке зайти в Browse Datastore – DS_name – каталог и файлы виртуалки есть. При попытке скопировать файлы виртуалки vm-name.vmx или vm-name.vmxf – тупит и говорит «ошибка копирования», без подробностей. Кроме того, есть файл блокировки vm-name.vmx~. Предполагая блокировку файлов, выводим в maintenance хост ESXi где она лежала (host13) – нормальные виртуалки с него съезжают, а эта так и остаётся. Перезагружаем, не дожидаясь завершения входа в режим обслуживания – результата нет. Видимо, это не тот хост.

2) Включаем (configuration – security profile – services) ssh и ESXi shell на произвольном хосте, в автостарт переводить не надо, просто запустить (options – start). Заходим на хост по ssh, смотрим что файлы точно есть:
cd /vmfs/volumes/DS_name/vm-name/
ls

Вывод:
vm-name-9462c45b.hlog vm-name.vmxf
vm-name-9462c45b.vswp vm-name.vmx~
vm-name-flat.vmdk vm-name_1-flat.vmdk
vm-name.nvram vm-name_1.vmdk
vm-name.vmdk vmware-1.log
vm-name.vmsd vmware-2.log
vm-name.vmx vmware.log
vm-name.vmx.lck vmx-vm-name-2489500763-1.vswp

Но все они заблокированы:

/vmfs/volumes/549030ba-7ff1cf81-677b-0025b5060a27/vm-name # touch *
touch: vm-name-9462c45b.vswp: Device or resource busy
touch: vm-name-flat.vmdk: Device or resource busy
touch: vm-name.nvram: Device or resource busy
touch: vm-name.vmx: Device or resource busy
touch: vm-name.vmx.lck: Device or resource busy
touch: vm-name.vmx~: Device or resource busy
touch: vm-name_1-flat.vmdk: Device or resource busy
touch: vmware.log: Device or resource busy
touch: vmx-vm-name-2489500763-1.vswp: Device or resource busy

3) Ищем кто заблокировал по инструкции http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=10051:

vmkfstools -D vm-name.vmx

Вывод:

Lock [type 10c00001 offset 111157248 v 129, hb offset 3383296
gen 135, mode 1, owner 54c0c4d4-45a3b3ba-b6c5-0025b5060a0e mtime 5688138
num 0 gblnum 0 gblgen 0 gblbrk 0]
Addr <4, 176, 4>, gen 26, links 1, type reg, flags 0, uid 0, gid 0, mode 100755
len 4281, nb 1 tbz 0, cow 0, newSinceEpoch 1, zla 2, bs 8192

Последний набор цифр из длинного GUID – это mac-адрес заблокировавшего хоста, 00:25:b5:06:0a:0e. Причем это, похоже, адрес первого адаптера eth0 – он не обязательно вообще участвует в сетевом трафике. Если вместо GUID одни нули – файл не заблокирован.

4) Методом перебора руками по Configuration – Network Adapters по всем хостам ESXi находим нужный хост, бывший владелец виртуалки, который никак её не отпустит. У нас это оказался host16. По идее, можно было бы его тоже перезагрузить и виртуалку бы отпустило, но мы пойдём более правильным путём. Не всегда перезагрузка хоста возможна из-за других виртуалок с RDM и т.п.

5) Де-регистрируем (не удаляем!!!), т.е. Remove from inventory, проблемную виртуалку. Зарегистрировать назад через vCenter оно не даёт – правой на .vmx файл, Add to inventory – неактивно. Заходим на хост, где пытались виртуалку запустить host13 при помощи vSphere Client напрямую. В виртуалках присутствует Unknown (unavailble) – так и должно быть по статье, смело дерегистрируем её, но никаких результатов это не даёт, ничего не меняется и зарегистрировать её по прежнему нельзя. Заходим на хост – последний владелец виртуалки host16 при помощи vSphere Client напрямую. На нём (и только на нём, а не на другом хосте или vCenter!) виртуалку можно зарегистрировать, что мы и делаем. Однако она, вместо нормального имени, регистрируется как Unknown (unavailble), включить её не получается, потому дерегистрируем назад.

6) Идём по статье дальше, включаем SSH и ESXi Shell на проблемном хосте – последнем владельце виртуалки host16, заходим на него по SSH. Смотрим, не осталось ли процессов, которые держат файлы виртуалки. Набор процессов конкретной виртуалки в терминологии VMware называется World. Запускаем:

esxcli vm process list

Видим кучу запущенных виртуалок, в т.ч. нашу vm-name, здесь оно ещё помнит её по имени:

some-vm-1
World ID: 7100719
Process ID: 0
VMX Cartel ID: 7100718
UUID: 42 20 e7 a6 8b 37 ed 57-c8 c9 d5 1c 79 a1 c3 ba
Display Name: some-vm-1
Config File: /vmfs/volumes/549030ba-7ff1cf81-677b-0025b5060a27/some-vm-1/some-vm-1.vmx

vm-name
World ID: 7100994
Process ID: 0
VMX Cartel ID: 7100993
UUID: 42 20 c4 55 06 c4 f6 a9-30 6e 61 a9 d2 39 d4 d5
Display Name: vm-name
Config File: /vmfs/volumes/549030ba-7ff1cf81-677b-0025b5060a27/vm-name/vm-name.vmx

some-vm-2
World ID: 7100730
Process ID: 0
VMX Cartel ID: 7100727
UUID: 42 20 2d 16 90 d2 b1 4b-7d 79 d5 3c 38 48 45 ac
Display Name: some-vm-2
Config File: /vmfs/volumes/5490305f-51759a8e-fcd9-0025b5060a27/some-vm-2/some-vm-2.vmx

Видим идентификатор мира, по которому можно убить все процессы виртуалки, что мы и делаем:

vm process kill --type=soft --world-id=7100994

Процесс так сразу не убивается (soft), надо подождать пару минут (периодически выполняем команду vmkfstools -D vm-name.vmx  на первом хосте, где мы узнали MAC хоста заблокировавшего файлы машины, дожидаемся момента где при выводе мы получим GUID с нулями).

7) После удаления процесса регистрируем виртуалку на проблемном хосте – последнем владельце виртуалки host16 через vSphere Client, подключенный напрямую к ней (регистрация на vCenter всё ещё заканчивается неудачей). Регистрация на хосте проходит успешно, виртуалку включаем (power on). Загружать ОС не обязательно, достаточно включить, дождаться начала загрузки (с предложением войти в Safe Mode) и выключить – это корректно снимет блокировки с файловой системы, которые никуда не делись с убиением процесса.

8) Де-регистрируем (Remove from inventory) виртуалку на проблемном хосте, теперь с ней всё ок и её надо зарегистрировать на vCenter, что мы и делаем, в этот раз правой на файл .vmx – Add to inventory там активно. При регистрации vCenter ругается, что виртуалка с таким именем уже была, но зарегистрировать даёт. При включении виртуалки оно предупреждает, что он такую уже знал когда-то – и что вы с ней сделали? Ответ Move, который надо выбрать, сохраняет ID виртуалки и какие-то связанные с ним события для Operations Manager и т.п., в то время как ответ Copy (который выбирать не надо) сгенерирует новый ID.

9) Готово, виртуалку можно включать, мигрировать и т.п. – теперь с ней всё хорошо. Не забываем остановить ESXi Shell и ssh где запускали.