ActiveScaleинженерная практика

TAPE_CONNECTOR_UNAVAILABLE при живом коннекторе ленты

Диагностика tape-connectorcold-storagetape501troubleshoothaproxy

Коротко. Продукт строит адреса проверок коннектора ленты из поля tape_connector.server, а это голый хост без порта — запрос уходит на 443. Если коннектор живёт на узле ActiveScale, на 443 сидит фронт узла (haproxy), и он отвечает 501 NotImplemented. Продукт считает коннектор недоступным и раз в ~4 часа поднимает CRITICAL. Лечится не «перезапуском», а тем, чтобы на адресе коннектора 443 отдавал именно коннектор.


Симптом

  • Событие COLD_STORAGE_TAPE_CONNECTOR_UNAVAILABLE (severity CRITICAL) открывается регулярно, с тактом около четырёх часов, и HANDLED_AUTO его не закрывает — коннектор «остаётся» недоступным.
  • При этом библиотека и привод живы, tapecmd drive list показывает приводы в состоянии Ok.
  • В логе фронта узла (/opt/ampli/var/log/haproxy/haproxy_*.log) видны 501 на пути /sws/v2/media/fsmedlist/state?format=JSON (иногда с ?media=…&state=protect|unprotect).
  • Операция защиты кассеты (protect/unprotect) «не срабатывает»: команда проходит без ошибки, но состояние кассеты в библиотеке не меняется.

Что проверить первым (read-only)

Все проверки — только чтение. mTLS-запросы к модели выполняются на узле, root (сертификаты продукта доступны только root).

  1. Что записано в модели адресом коннектора — на узле, root: bash sudo curl -sk --cert /opt/ampli/cfg/marvin/ssl/machine.cert \ --key /opt/ampli/cfg/marvin/ssl/machine.key \ https://127.0.0.1:8443/model/tapeconnector/ | jq \ '."tapeconnector"[] | {name, connection}' Ожидается connection[].server — только хост (<CONNECTOR_HOST>), а порт — в отдельном поле connection[].port. Если в server видно host:port или IPv4 с портом — это уже дефект конфигурации (см. «Профилактика»).

  2. Куда реально идёт запрос — в логе фронта за последние часы: bash sudo grep -h 'fsmedlist\|fschmedstate' /opt/ampli/var/log/haproxy/haproxy_*.log | tail -20 Ожидается: либо строк нет (коннектор отвечает сам), либо 501 — тогда фронт узла перехватывает запрос коннектора. Запомнить такт: если 501 идут ровно раз в 4 часа, это периодическая coldstorage.tape_media_verify.

  3. Отвечает ли коннектор на 443 именно как коннектор — с узла: bash curl -sk "https://<CONNECTOR_HOST>/sws/v2/media/fsmedlist/state?format=JSON" | head -c 300 Ожидается JSON с classes[] и footer.returnCode=0. Если вернулся 501/404/HTML фронта ActiveScale — на этом адресе на 443 не коннектор.

  4. Отвечает ли библиотечный канал (/aml/) — там порт приходит из модели вместе с адресом, поэтому этот путь обычно работает даже при сломанном /sws/: bash curl -sk "https://<CONNECTOR_HOST>:<CONNECTOR_PORT>/aml/media?status=used" | head -c 200 Ожидается список кассет с mediaType. Работающий /aml/ при 501 на /sws/ — характерный признак 443-конфликта, а не мёртвого коннектора.

  5. Состояние событий — в GUI (Events) или через модель: bash sudo curl -sk --cert /opt/ampli/cfg/marvin/ssl/machine.cert \ --key /opt/ampli/cfg/marvin/ssl/machine.key \ "https://127.0.0.1:8443/model/event/?fields=eventtype,severity,status,time" \ | jq -r '."event"[] | select(.eventtype|test("TAPE_CONNECTOR")) | [.time,.severity,.status]|@tsv' | tail Ожидается: свежие записи LIVE с шагом ~4 ч и без HANDLED_AUTO.


Причина

Механизм

Продукт собирает управляющие URL коннектора из свойства tape_connector.server:

https://{tape_connector.server}/sws/v2/media/fsmedlist/state?format=JSON
https://{tape_connector.server}/sws/v2/media/fschmedstate?media=<barcode>&state=protect|unprotect

Порта в URL нет, значит HTTPS идёт на 443. Если коннектор — отдельное устройство (вендорская форма), на 443 стоит именно он, и проверка проходит. Если коннектор живёт на узле ActiveScale, 443 узла держит фронт (haproxy, backend scaler-internal-traffic), scalerd на неизвестный путь отвечает 501 NotImplemented — продукт читает это как недоступность коннектора.

Отказ «тихий» с двух сторон:

  • coldstorage.tape_media_verify → подзадача _has_available_genscratch_media → RuntimeError → событие COLD_STORAGE_TAPE_CONNECTOR_UNAVAILABLE раз в ~4 часа;
  • protect/unprotect кассеты (fschmedstate) не выполняется — оператор видит «операция не сработала».

Асимметрия, которую легко проглядеть

Адреса библиотеки приходят из модели вместе с портом (tape_library.server = <CONNECTOR_HOST>:<CONNECTOR_PORT>), поэтому /aml/users/login, /aml/media и /aml/system/ras/tickets работают. Живой признак на нашем стенде: вход coldstorage через /aml/ отвечал 200, а /sws/ в это же время падал в 501.

Отсюда рабочее правило: порт добавляется только коннекторным /sws/-URL; библиотечные /aml/-URL трогать нельзя. Попытка применить «общий шаблон https://{}/» даёт https://host:port:port/aml/... — битый адрес, и nginx на узле не стартует вовсе.

Гипотезы, которые проверяются так же

  • Гипотеза: коннектор действительно выключен. Проверка п.3–4 выше: если не отвечает ни /sws/, ни /aml/ и порт не слушается (ss -ltnp на коннекторе), это не конфликт портов, а отказ устройства.

Решение (штатное)

Штатно коннектор ленты — отдельное устройство со своим адресом в приватной сети, а не надстройка на узле. На своём адресе 443 свободен, продукт его не патчит и не перепутывает с фронтом.

  1. Выделить коннектору собственный адрес в сети, доступной всем узлам кластера (задачи распределяются между узлами, поэтому адрес должен быть виден с каждой ноды). Это <CONNECTOR_HOST>.

  2. Убедиться, что на этом адресе слушаются оба порта — 443 (SWS + AML: логин, каталог кассет, RAS-тикеты) и <CONNECTOR_PORT> (14512, data-plane DTT: очередь запросов, приводы, архивация). Ожидаемо: ss -ltnp на коннекторе показывает оба порта, 443 отвечает на /sws/v2/media/fsmedlist/state.

  3. Записать в модель адрес коннектора — в connection[].server только хост, порт — в connection[].port. Это делается в GUI (Configuration → Cold Storage / Connector) либо штатным PUT в модель: bash sudo curl -sk --cert /opt/ampli/cfg/marvin/ssl/machine.cert \ --key /opt/ampli/cfg/marvin/ssl/machine.key \ -X PUT -H 'Content-Type: application/json' \ -d '{"connection":[{"server":"<CONNECTOR_HOST>","port":"14512"}]}' \ https://127.0.0.1:8443/model/tapeconnector/<CONNECTOR_NAME>/ Ожидается 200. REST модели отдаёт даты числами, а принимает ISO — не переносить даты из GET в PUT.

  4. Дать продукту перечитать модель и переконфигурировать затронутые приложения — штатным прогоном configure (см. install-ng: фазы и флаги) либо ожиданием ближайшего цикла coldstorage.* (до ~4 ч).

  5. Проверить, что событие больше не поднимается: закрыть текущее событие штатным действием (HANDLED_AUTO или ignore в GUI) и наблюдать один–два цикла.

Если штатный путь недоступен

Не штатно, временная мера. Если выделить коннектору отдельный адрес нельзя и он вынужденно живёт на узле, приходится развести трафик по порту: коннекторные /sws/-запросы направлять на порт коннектора через прозрачный проброс, а не на 443 узла. Такое решение всегда означает правку файла из пакета продукта и проброс порта на узле, поэтому:

  • правка снимается любым апгрейдом продукта — нужен афтер-фикс и запись в реестр обходов;
  • dpkg -V будет показывать модификацию пакета;
  • после правки плагина перезапускается только таск-менеджер, не marvinservices целиком (иначе рискуют встать samurai/haproxy и узел станет красным);
  • синтаксис проверяется тем же интерпретатором, что у продукта, а не «питоном, который под рукой»;
  • перед правкой фиксируется контрольная сумма файла и снимается проверяемый бэкап вне каталога продукта.

План замены на штатный путь — п.1–3 выше, с отмашкой оператора в спокойное окно.


Проверка

  • curl -sk "https://<CONNECTOR_HOST>/sws/v2/media/fsmedlist/state?format=JSON" → JSON, classes[] с классами данных и чётности, footer.returnCode=0; не 501.
  • curl -sk "https://<CONNECTOR_HOST>:<CONNECTOR_PORT>/aml/media?status=used" → список кассет с mediaType.
  • protect/unprotect кассеты через продукт → по коду ответа (FS0249 = попытка повторить защиту на уже защищённой кассете, то есть операция дошла до библиотеки).
  • В логе фронта узла нет новых 501 на /sws/v2/media/fsmedlist/state.
  • Новых COLD_STORAGE_TAPE_CONNECTOR_UNAVAILABLE нет за два цикла наблюдения (около 8 часов).
  • Задачи tape_media_verify, tape_safety_check, tape_drive_verify — SUCCESS.
  • В журнале коннектора видны запросы от узлов продукта, включая POST /aml/users/login.

Профилактика

  • Коннектор — отдельный адрес. Это единственная форма, в которой 443 принадлежит коннектору, а не фронту узла. Планировать адрес заранее — см. Планирование холодного тира и ленты.
  • В connection[].server — только хост. Порт в поле адреса ломает не только коннектор, но и nginx на узле (invalid port in upstream), а узел из-за этого становится красным.
  • Не патчить «общий шаблон». Если правка коннекторных URL всё же делалась, патчить только коннекторные строки и никогда не задевать /aml/.
  • Мониторинг: держать COLD_STORAGE_TAPE_CONNECTOR_UNAVAILABLE в алертах, но с разбором по пути: код 501 от фронта и код 200 от коннектора — разные причины.
  • После любого изменения модели ленты — прогонять configure и смотреть один цикл задач, а не только «зелёную плитку» в GUI.

Источники и дата

  • Quantum, Software Documentation Center (ActiveScale 7.3): https://qsupport.quantum.com/kb/flare/Content/ActiveScale/Software/Content/Index_Files/Index_Software.htm (дата доступа: 2026-11-07).
  • Наша практика, обезличено: разбор конфликта 443 между коннектором и фронтом узла на лабораторном стенде; вендорский скрипт настройки коннектора прописывает RESTD_PORT=14512 и открывает tcp/443 + tcp/14512 — то есть коннектор штатно живёт на двух портах и на своём адресе.
  • Обновлено: 2026-11-07.

Нужен инженер? Разберу вашу ситуацию и скажу, что делать — по шагам, с проверками.

Обсудить задачу