Что заставляет мою службу systemd зависать?

Вопрос или проблема

Ладно, это РЕШЕННАЯ проблема, но остаются несколько вопросов…

У меня есть некоторые “скрипты”, которые автоматически монтируют файловые системы, а затем делятся различными частями через NFS и Samba.

Я запускал версии этих скриптов в течение многих месяцев на системе с фиксированными (болтами закрепленными) дисками и использовал службу systemd, работало нормально.

Моя текущая система имеет диск, подключенный через USB (плюс фиксированный NVME), поэтому я использовал udev. Конечно, я столкнулся с проблемой “вы не можете выполнить mount(1) внутри правила udev (отдельное пространство имен для монтирования), поэтому я сделал ‘обычное’ (запуск службы):

graeme@argon:~$ cat /etc/udev/rules.d/99-QPImount.rules

ACTION=="add|change|online|bind", ENV{ID_FS_USAGE}=="filesystem", ENV{ID_FS_LABEL_ENC}=="rest?", TAG+="systemd" ENV{SYSTEMD_WANTS}+="QPImount.service"

Это работало нормально, когда я тестировал его (udevadm trigger -a add /dev/sda4) и на практике, когда отключал и снова включал питание.

Однако сегодня я включил систему без подключенного USB-диска, а затем позже подключил его. Мой скрипт не запустился. Проводя шаги вручную, все выглядело нормально, пока я не попробовал запустить службу вручную:

#systemctl start QPImount

Это зависает.

graeme@argon:~$ cat /etc/systemd/system/QPImount.service
[Unit]
Description=Сделать все файловые системы QPIhomebrew доступными (NFS & SAMBA)
After=remote-fs.target 
Before=minidlna.service samba.service

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'QPImount' && echo 'QPImount completed'

[Install]
#WantedBy=multi-user.target minidlna.service samba.service
#WantedBy=multi-user.target

Вы можете видеть, я хочу дождаться remote-fs.target (экспорт NFS не удается до этого момента)

К вашему сведению, в скрипте есть отладка, поэтому я вижу, что ОН НЕ НАЧАЛСЯ.

Если я перечислю цели…

# systemctl list-units --type target                                                                                                                                                                                                                           
  UNIT                   LOAD   ACTIVE   SUB    JOB   DESCRIPTION                                                                                                                                                                                                                     
  basic.target           загружен активно  активно          Основная система                                                                                                                                                                                                                    
  bluetooth.target       загружен активно  активно          Поддержка Bluetooth                                                                                                                                                                                                               
  cryptsetup.target      загружен активно  активно          Локальные шифрованные тома                                                                                                                                                                                                         
  getty.target           загружен активно  активно          Запросы на вход                                                                                                                                                                                                                   
  graphical.target       загружен неактивно неактивный начать Графический интерфейс                                                                                                                                                                                                             
  integritysetup.target  загружен активно  активно          Локальные тома с защитой целостности                                                                                                                                                                                               
  local-fs-pre.target    загружен активно  активно          Подготовка для локальных файловых систем                                                                                                                                                                                              
  local-fs.target        загружен активно  активно          Локальные файловые системы                                                                                                                                                                                                              
  multi-user.target      загружен неактивно неактивный начать Много-пользовательская система                                                                                                                                                                                                               
  network-online.target  загружен активно  активно          Сеть в сети                                                                                                                                                                                                               
  network.target         загружен активно  активно          Сеть                                                                                                                                                                                                                         
  nfs-client.target      загружен активно  активно          Службы клиента NFS                                                                                                                                                                                                             
  nss-lookup.target      загружен активно  активно          Поиск имен хостов и сетей                                                                                                                                                                                                   
  nss-user-lookup.target загружен активно  активно          Поиск имен пользователей и групп                                                                                                                                                                                                     
  paths.target           загружен активно  активно          Путь Units                                                                                                                                                                                                                      
  remote-fs-pre.target   загружен активно  активно          Подготовка к удаленным файловым системам                                                                                                                                                                                             
  remote-fs.target       загружен активно  активно          Удаленные файловые системы                                                                                                                                                                                                             
  rpc_pipefs.target      загружен активно  активно          rpc_pipefs.target                                                                                                                                                                                                               
  rpcbind.target         загружен активно  активно          Отображение портов RPC                                                                                                                                                                                                                 
  slices.target          загружен активно  активно          Единицы Slice                                                                                                                                                                                                                     
  sockets.target         загружен активно  активно          Единицы Socket                                                                                                                                                                                                                    
  sound.target           загружен активно  активно          Звуковая карта                                                                                                                                                                                                                      
  swap.target            загружен активно  активно          Свопы                                                                                                                                                                                                                           
  sysinit.target         загружен активно  активно          Инициализация системы                                                                                                                                                                                                           
  time-set.target        загружен активно  активно          Установка времени системы                                                                                                                                                                                                                 
  timers.target          загружен активно  активно          Единицы таймера                                                                                                                                                                                                                     
  veritysetup.target     загружен активно  активно          Локальные защищенные тома Verity                                                                                                                                                                                                  

                                                                                    

Я вижу, что remote-fs.target активен.

Итак, мой вопрос:

Я считаю, что systemd “ждет чего-то”, чтобы запустить QPImount.service. Есть ли команда, которая скажет мне, чего он ждет, прежде чем он запустит QPImount.

…статус показывает статус первого использования службы QPImount (для монтирования файловых систем NVME)… ничего по этому (потому что он не запущен?)

root@argon:/home/graeme# systemctl status QPImount                                                                                                                                                                                                                                    
QPImount.service - Сделать все файловые системы QPIhomebrew доступными (NFS & SAMBA)                                                                                                                                                                                                      
     Загружено: загружено (/etc/systemd/system/QPImount.service; статично)                                                                                                                                                                                                                    
     Активно: активируется (старт) с Пн 2025-03-03 09:02:01 GMT; 43мин назад                                                                                                                                                                                                          
   Основной PID: 1005 (QPImount)                                                                                                                                                                                                                                                          
      Задачи: 2 (лимит: 9569)                                                                                                                                                                                                                                                          
        ЦП: 134мс                                                                                                                                                                                                                                                                    
     ГруппаC: /system.slice/QPImount.service                                                                                                                                                                                                                                           
             005 /bin/bash /usr/local/bin/QPImount                                                                                                                                                                                                                                 
             1492 systemctl restart minidlna.service                                                                                                                                                                                                                                

                                                                                                                                                                                                                                                                                      
Мар 03 09:02:01 argon systemd[1]: Starting QPImount.service - Сделать все файловые системы QPIhomebrew доступными (NFS & SAMBA)...                                                                                                                                                          
Мар 03 09:02:01 argon bash[1005]: QPImount вызван с                                                                                                                                                                                                                               
Мар 03 09:02:01 argon bash[1029]: rmdir: не удалось удалить '/QPI/mounts/rest2/Multimedia': Нет такого файла или каталога                                                                                                                                                                   
Мар 03 09:02:01 argon bash[1029]: rmdir: не удалось удалить '/Multimedia': Нет такого файла или каталога                                                                                                                                                                                    
Мар 03 09:02:01 argon bash[1033]: rmdir: не удалось удалить '/QPI/mounts/rest2/USBUploads': Нет такого файла или каталога                                                                                                                                                                   
Мар 03 09:02:01 argon bash[1033]: rmdir: не удалось удалить '/USBUploads': Нет такого файла или каталога                                                                                                                                                                                    
Мар 03 09:02:01 argon bash[1047]: rmdir: не удалось удалить '/QPI/mounts/rest2/Recordings': Нет такого файла или каталога                                                                                                                                                                   
Мар 03 09:02:01 argon bash[1047]: rmdir: не удалось удалить '/Recordings': Нет такого файла или каталога                                                                                                                                                                                    
Мар 03 09:02:01 argon bash[1048]: rmdir: не удалось удалить '/QPI/mounts/rest2': Нет такого файла или каталога                                                                                                                                                                              
Мар 03 09:02:02 argon bash[1005]: Для QPI rest3 добавление Public svn git Web InternalAdmin Download home

…ниже есть “решение”, но вопрос о том, как это обнаружить, все еще открыт

Кажется, люди не любят, когда я даю частичный ответ в оригинале… поэтому выделен здесь

————– Решение ————–

При написании этого сообщения, я нашел свою проблему (https://wiki.c2.com/?CardboardProgrammer также известный как картонный супермен)

В службе я указываю “Before=minidlna.service samba.service”, но в моем скрипте я делаю:

systemctl restart smb.service      # Поделиться тем, что можем через SAMBA
systemctl restart minidlna.service # Поделиться через DLNA протокол

…так что “смертельное объятие”, я должен запустить ПЕРЕД smb.service, НО прежде чем закончить, я должен перезапустить smb.service (думаю, я мог бы сделать это в фоновом режиме?) Я считаю, что делать это тоже “нельзя”… но вы видите мою проблему? Как только появляется новая файловая система, различные службы нужно перезапустить, чтобы с этим справиться.

Кстати, я заметил, что runlevel(1) возвращает “неизвестно” в то время, как сейчас возвращает “5”… намек/подпись на блокировку.

Но исходный вопрос остается: “есть ли команда, которую я могу ввести в systemd, чтобы спросить ‘чего вы ждете, чтобы запустить эту службу’?

…так что НЕ “от чего он зависит”, а скорее “вы его не запустили? …почему?” предположительно, у systemd есть некоторое внутреннее состояние, которое говорит “ожидание X”

(2-й вопрос, как лучше достичь того, что я хочу [перезапуск])

Ответ или решение

Причины зависания сервиса systemd могут быть разнообразными и связаны с множеством факторов. Давайте разберемся, какие проблемы могут вызывать зависание сервиса, а затем перейдём к возможным решениям и рекомендациям для предотвращения таких ситуаций в дальнейшем.

Теория

1. Взаимная блокировка (Deadlock):
Ваша проблема, судя по всему, связана с взаимной блокировкой. Это состояние, при котором два или более процесса ожидают, пока другой сделает что-то для завершения, при этом ни один из них не может продолжить работу.

2. Некорректная конфигурация зависимостей:
В systemd очень важно корректно настроить зависимости между сервисами. Неправильная конфигурация может привести к зависаниям или недоступным сервисам.

3. Непредвиденные изменения в аппаратуре или окружении системы:
Подключение или отключение устройств может нарушить работу сервисов, если конфигурация не была подготовлена к такого рода изменениям. Это особенно актуально для систем с внешними накопителями.

4. Ошибки в скриптах или программах:
Могут быть в виде бесконечных циклов, преждевременных выходов и блокировок ресурсов, которые необходимы другим процессам.

Пример

В вашем случае проблема была вызвана зависимостями между сервисами. Вы указали, что ваш сервис должен выполняться до minidlna.service и smb.service. Однако внутри вашего скрипта вы пытались перезапустить эти сервисы, что привело к появлению взаимной блокировки — сервис не может завершиться до тех пор, пока не завершит перезапуск smb.service, но задан в качестве необходимости выполнения до него.

Приложение

Решение проблемы

  1. Избегайте вызова команд systemctl в сервисах, которые требуют конкретного порядка запуска.
    Используйте возможность фоново запускать команды или подумайте о реструктуризации скрипта таким образом, чтобы сократить зависимости и избежать взаимных блокировок.

  2. Измените конфигурационные файлы systemd:
    Вы можете попробовать следующие подходы:

    • Определите более простой порядок зависимостей, разделяя задачи так, чтобы избежать необходимости взывать systemd команды внутри ваших скриптов.
    • Используйте более продвинутые механизмы, такие как ExecStartPre и ExecStartPost, для выполнения необходимых операций до и после основной команды.
  3. Изучение возможных состояний зависимостей в systemd:
    В вашем случае, возможно, полезно будет использовать systemctl list-dependencies --reverse, чтобы увидеть, какие сервисы могут ожидать ваш сервис для завершения запуска. Однако, нужно помнить, что systemd не предоставляет прямой команды для выведения конкретного ожидания.

  4. Перемещение временных зависимостей в отдельные задачи/таймеры:
    Подумайте об использовании механизма таймеров systemd, который позволит выполнять задачи без жесткой привязки к состоянию других сервисов, тем самым снижая риск взаимной блокировки.

  5. Логирование и отладка:
    Усиление уровней логирования для более подробной информации о действиях и состояниях позволит оперативнее выявлять места потенциальных зависаний. Использование journalctl -xe может дать более глубокую информацию о состоянии системных журналов и текущих проблемах.

Используя приведенные методики и подходы, вы можете более эффективно управлять сервисами в вашей системе, минимизировать риск зависания, а также повысить стабильность её работы в условиях изменяющегося окружения и оборудования. Обязательно следуйте лучшим практикам и постоянно тестируйте изменения в изолированной среде перед их внедрением в рабочую систему.

Оцените материал
Добавить комментарий

Капча загружается...