Что вызывает зависание моей службы 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=Make all the QPIhomebrew filesystems available (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           loaded active   active       Basic System                                                                                                                                                                                                                    
  bluetooth.target       loaded active   active       Bluetooth Support                                                                                                                                                                                                               
  cryptsetup.target      loaded active   active       Local Encrypted Volumes                                                                                                                                                                                                         
  getty.target           loaded active   active       Login Prompts                                                                                                                                                                                                                   
  graphical.target       loaded inactive dead   start Graphical Interface                                                                                                                                                                                                             
  integritysetup.target  loaded active   active       Local Integrity Protected Volumes                                                                                                                                                                                               
  local-fs-pre.target    loaded active   active       Preparation for Local File Systems                                                                                                                                                                                              
  local-fs.target        loaded active   active       Local File Systems                                                                                                                                                                                                              
  multi-user.target      loaded inactive dead   start Multi-User System                                                                                                                                                                                                               
  network-online.target  loaded active   active       Network is Online                                                                                                                                                                                                               
  network.target         loaded active   active       Network                                                                                                                                                                                                                         
  nfs-client.target      loaded active   active       NFS client services                                                                                                                                                                                                             
  nss-lookup.target      loaded active   active       Host and Network Name Lookups                                                                                                                                                                                                   
  nss-user-lookup.target loaded active   active       User and Group Name Lookups                                                                                                                                                                                                     
  paths.target           loaded active   active       Path Units                                                                                                                                                                                                                      
  remote-fs-pre.target   loaded active   active       Preparation for Remote File Systems                                                                                                                                                                                             
  remote-fs.target       loaded active   active       Remote File Systems                                                                                                                                                                                                             
  rpc_pipefs.target      loaded active   active       rpc_pipefs.target                                                                                                                                                                                                               
  rpcbind.target         loaded active   active       RPC Port Mapper                                                                                                                                                                                                                 
  slices.target          loaded active   active       Slice Units                                                                                                                                                                                                                     
  sockets.target         loaded active   active       Socket Units                                                                                                                                                                                                                    
  sound.target           loaded active   active       Sound Card                                                                                                                                                                                                                      
  swap.target            loaded active   active       Swaps                                                                                                                                                                                                                           
  sysinit.target         loaded active   active       System Initialization                                                                                                                                                                                                           
  time-set.target        loaded active   active       System Time Set                                                                                                                                                                                                                 
  timers.target          loaded active   active       Timer Units                                                                                                                                                                                                                     
  veritysetup.target     loaded active   active       Local Verity Protected Volumes                                                                                                                                                                                                  

                                                                                    

Я могу видеть, что remote-fs.target активен.

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

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

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

root@argon:/home/graeme# systemctl status QPImount                                                                                                                                                                                                                                    
QPImount.service - Make all the QPIhomebrew filesystems avaiable (NFS & SAMBA)                                                                                                                                                                                                      
     Loaded: loaded (/etc/systemd/system/QPImount.service; static)                                                                                                                                                                                                                    
     Active: activating (start) since Mon 2025-03-03 09:02:01 GMT; 43min ago                                                                                                                                                                                                          
   Main PID: 1005 (QPImount)                                                                                                                                                                                                                                                          
      Tasks: 2 (limit: 9569)                                                                                                                                                                                                                                                          
        CPU: 134ms                                                                                                                                                                                                                                                                    
     CGroup: /system.slice/QPImount.service                                                                                                                                                                                                                                           
             005 /bin/bash /usr/local/bin/QPImount                                                                                                                                                                                                                                 
             1492 systemctl restart minidlna.service                                                                                                                                                                                                                                

                                                                                                                                                                                                                                                                                      
Mar 03 09:02:01 argon systemd[1]: Starting QPImount.service - Make all the QPIhomebrew filesystems avaiable (NFS & SAMBA)...                                                                                                                                                          
Mar 03 09:02:01 argon bash[1005]: QPImount invoked with                                                                                                                                                                                                                               
Mar 03 09:02:01 argon bash[1029]: rmdir: failed to remove '/QPI/mounts/rest2/Multimedia': No such file or directory                                                                                                                                                                   
Mar 03 09:02:01 argon bash[1029]: rmdir: failed to remove '/Multimedia': No such file or directory                                                                                                                                                                                    
Mar 03 09:02:01 argon bash[1033]: rmdir: failed to remove '/QPI/mounts/rest2/USBUploads': No such file or directory                                                                                                                                                                   
Mar 03 09:02:01 argon bash[1033]: rmdir: failed to remove '/USBUploads': No such file or directory                                                                                                                                                                                    
Mar 03 09:02:01 argon bash[1047]: rmdir: failed to remove '/QPI/mounts/rest2/Recordings': No such file or directory                                                                                                                                                                   
Mar 03 09:02:01 argon bash[1047]: rmdir: failed to remove '/Recordings': No such file or directory                                                                                                                                                                                    
Mar 03 09:02:01 argon bash[1048]: rmdir: failed to remove '/QPI/mounts/rest2': No such file or directory                                                                                                                                                                              
Mar 03 09:02:02 argon bash[1005]: For QPI rest3 adding Public svn git Web InternalAdmin Download home

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

Похоже, людям не нравится, когда я частично отвечаю в оригинале… так что выделил сюда

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

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

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

systemctl restart smb.service      # Share out what we can via SABMA
systemctl restart minidlna.service # Share out via DLNA protocol

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

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

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

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

(Второй вопрос, как лучше всего достичь желаемого [перезапуска])

.

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

Ваша система сталкивается с проблемой зависания сервиса systemd, и, судя по вашему описанию, это связано с "взаимной блокировкой" (deadlock), когда один сервис ожидает завершения работы другого, но при этом сам пытается его запустить. Чтобы более подробно разобраться в этой проблеме и предложить решения, давайте основывать наш анализ на методе TEA (Theory, Example, Application).

Теория

Systemd и зависимости: Systemd — это система инициализации, основанная на зависимостях. Она управляет загрузкой системных сервисов в соответствии с заданной конфигурацией. Основные элементы конфигурации включают директивы After, Before, Requires, и Wants. Если сервис A имеет Before=B и одновременно пытается вызвать systemctl restart B внутри скрипта, это может привести к взаимной блокировке.

Директивы и параметры:

  • After и Before определяют порядок запуска сервисов.
  • Requires и Wants устанавливают жесткие и мягкие зависимости соответственно.
  • Type=oneshot используется для задач, не требующих долгого времени для выполнения.

Взаимная блокировка: Этот термин используется для описания ситуации, в которой два или более процесса ждут ресурсов, захваченных друг другом, и ни один из них не может продолжить выполнение, освобождая ресурс.

Пример

Исходя из вашего описания, следующее произошло:

  1. Определение зависимостей: У вас задано Before=minidlna.service samba.service, что означает, что ваш сервис должен завершиться перед стартом указанных сервисов.
  2. Вызов restart: Внутри скрипта вы пытаетесь запустить systemctl restart smb.service и systemctl restart minidlna.service, что конфликтует с указанием Before.

Этот конфликт заставляет systemd ждать завершения вашего сервиса, который, в свою очередь, пытается перезапустить зависимости, из-за чего система входит в состояние ожидания, и ваш сервис зависает.

Применение

Диагностика проблемы:

  1. Использование systemctl list-dependencies: Этот командный инструмент systemd может помочь определить все зависимости и обратные зависимости, связанные с конфигурацией вашего сервиса.

    systemctl list-dependencies QPImount
  2. Журнализировать события: Используйте journalctl -xe для просмотра журнала systemd, что может дать более полную картину происходящего.

  3. Логи unit-файла: Проверьте лог-файлы вашего сервиса, они дадут инсайты о том, на каком этапе выполнения скрипта возникают сложности.

Решения:

  1. Реорганизация зависимостей:

    • Перепишите зависимости, чтобы избежать циклических ссылок. Например, возможно, стоит разделить ваш скрипт на два этапа: первый выполняет все действия, не влияющие на запуск других сервисов, второй — перезапускает зависимости.
  2. Асинхронное выполнение: Запуск зависимых сервисов в фоновом режиме может помочь. Вместо restart возможно использовать systemctl try-restart, который не будет мешать вашему сервису завершить работу.

  3. Отсмотр состояния systemd: На системах Linux с поддержкой D-Bus можно использовать утилиты, такие как busctl, для получения информации о внутренних состояниях systemd.

    busctl tree org.freedesktop.systemd1

Советы по лучшим практикам:

  • Плоская экосистема сервисов: Избегайте избыточного взаимного влияния сервисов друг на друга через restart внутри скриптов. Рассмотрите возможность делегирования таких задач внешним скриптам, которые запускаются после загрузки сервиса.
  • Use of Sockets: Для NFS и других сетевых сервисов рассмотрите использование сокетов (socket activation) для их активации по мере необходимости.

Ваш оригинальный вопрос о том, есть ли команда, чтобы systemd сообщил, что именно он ожидает для старта определенного сервиса, не имеет прямого решения, так как systemd не предоставляет утилиту с такой функцией. Однако логика зависимостей и выводы systemctl — мощные инструменты для анализа блокировок.

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

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

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