LINUX.ORG.RU

Сздание unit-а для systemd.

 ,


1

1

Доброго времени суток Всем! Есть PACS - dcm4chee. Для управления этим сервисом составил такой unit файл для systemd:

[root@dcm4chee system]# cat ./dcm4chee.service
[Unit]
Description=DICOM server daemon
After=network.target mariadb.service iscsi.service

[Service]
ExecStart=/opt/dcm4chee-2.17.3-mysql/bin/dcm4chee_init_redhat.sh start
ExecReload=/opt/dcm4chee-2.17.3-mysql/bin/dcm4chee_init_redhat.sh restart
ExecStop=/opt/dcm4chee-2.17.3-mysql/bin/dcm4chee_init_redhat.sh stop
KillMode=control-group

[Install]
WantedBy=multi-user.target
[root@dcm4chee ~]# systemctl status dcm4chee
dcm4chee.service - DICOM server daemon
   Loaded: loaded (/usr/lib/systemd/system/dcm4chee.service; enabled)
   Active: failed (Result: exit-code) since Thu 2015-04-23 11:26:18 NOVT; 1 weeks 6 days ago
  Process: 2468 ExecStop=/opt/dcm4chee-2.17.3-mysql/bin/dcm4chee_init_redhat.sh stop (code=exited, status=1/FAILURE)
  Process: 2450 ExecStart=/opt/dcm4chee-2.17.3-mysql/bin/dcm4chee_init_redhat.sh start (code=exited, status=0/SUCCESS)
 Main PID: 2450 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/dcm4chee.service

Apr 23 11:26:18 dcm4chee.corp.zdravalt.ru dcm4chee_init_redhat.sh[2468]: at java.net.Socket.connect(Socket.java:529)
Apr 23 11:26:18 dcm4chee.corp.zdravalt.ru dcm4chee_init_redhat.sh[2468]: at java.net.Socket.connect(Socket.java:478)
Apr 23 11:26:18 dcm4chee.corp.zdravalt.ru dcm4chee_init_redhat.sh[2468]: at java.net.Socket.<init>(Socket.java:375)
Apr 23 11:26:18 dcm4chee.corp.zdravalt.ru dcm4chee_init_redhat.sh[2468]: at java.net.Socket.<init>(Socket.java:276)
Apr 23 11:26:18 dcm4chee.corp.zdravalt.ru dcm4chee_init_redhat.sh[2468]: at org.jnp.interfaces.TimedSocketFactory.createSocket(TimedSocketFactory.java:84)
Apr 23 11:26:18 dcm4chee.corp.zdravalt.ru dcm4chee_init_redhat.sh[2468]: at org.jnp.interfaces.TimedSocketFactory.createSocket(TimedSocketFactory.java:77)
Apr 23 11:26:18 dcm4chee.corp.zdravalt.ru dcm4chee_init_redhat.sh[2468]: at org.jnp.interfaces.NamingContext.getServer(NamingContext.java:244)
Apr 23 11:26:18 dcm4chee.corp.zdravalt.ru dcm4chee_init_redhat.sh[2468]: ... 5 more
Apr 23 11:26:18 dcm4chee.corp.zdravalt.ru systemd[1]: dcm4chee.service: control process exited, code=exited status=1
Apr 23 11:26:18 dcm4chee.corp.zdravalt.ru systemd[1]: Unit dcm4chee.service entered failed state.

В скрипте /opt/dcm4chee-2.17.3-mysql/bin/dcm4chee_init_redhat.sh кроме задания переменных окружения выполняется запуск java программы через ещё один скрипт.

Проблема в том что при просмотре статуса сервиса systemctl status dcm4chee, статус отображается не верно и выключить командой systemctl stop dcm4chee не получается.

Подскажите в чём проблема.

Я не совсем понял ситуацию, но думаю, что проблема мне понятна. В юните не указан «тип» программы (директива Type=), и по умолчанию берётся тип «simple».

Если вкратце, то «simple» означает, что systemd будет следить за непосредственно запущенным им процессом, и его завершение будет означать самопроизвольную остановку программы. А в твоём случае непосредственно запускаемый процесс — это стартовый скрипт, который в свою очередь запускает ещё один скрипт (уже другой процесс), а сам завершается. На этом месте systemd считает, что сервис самопроизвольно завершился, и добивает все процессы в контрольной группе.

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

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 2)
Ответ на: комментарий от galliley

Примерно вот так:

[Unit]
Description=DCM4CHEE DICOM Image Manager

[Service]
User=pacs
Type=forking

ExecStart=/usr/bin/env \
        LD_LIBRARY_PATH=${JBOSS_HOME}/bin/native \
        ${JAVA_HOME}/bin/java \
                ${JAVA_OPTS} \
                -Djava.awt.headless=true \
                -Dprogram.name=dcm4chee \
                -Dapp.name=dcm4chee \
                -Djava.library.path=${JBOSS_HOME}/bin/native \
                -Djava.endorsed.dirs=${JBOSS_HOME}/lib/endorsed \
                -classpath ${JBOSS_HOME}/bin/run.jar:${JAVA_HOME}/lib/tools.jar \
                org.jboss.Main -b ${JBOSS_BIND_ADDR} -c ${JBOSS_CONF} 

ExecStop=/usr/bin/env \
        ${JAVA_HOME}/bin/java \
                -classpath ${JBOSS_HOME}/bin/shutdown.jar:${JBOSS_HOME}/client/jnet.jar \
                org.jboss.Shutdown --shutdown

KillMode=control-group

Environment=JBOSS_HOME=/usr/local/dcm4chee
Environment=JBOSS_CONF=default
Environment=JBOSS_BIND_ADDR=0.0.0.0
Environment=JAVA_HOME=/usr/java/jdk
Environment="JAVA_OPTS=-Xms128m -Xmx512m -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000"

[Install]
WantedBy=multi-user.target
intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)

Сделайте ссылку на скрипт в /etc/init.d, и systemd сам сгенерирует для него сервис-файл с корректными зависимостями, типом и т.д.

anonymous
()
Ответ на: комментарий от intelfx

А как же легаси? Конечно оно понятно, что вопрос про systemd, но таки пока что готовить продукт который пускается с systemd-only, слегка рановато имхо.

Нельзя разве pid файл заставить его пасти? Или делегировать init'овский status в systemd?

pon4ik ★★★★★
()
Ответ на: комментарий от intelfx

Теперь во время выполнения systemctl start dcm4chee ничего не происходит и через некоторое время systemd прекращает запуск процесса.

galliley
() автор топика
Ответ на: комментарий от intelfx

Во-первых, /usr/bin/env явно лишний, путь к жабе указан напрямик.

Во-вторых, что мешает LD_LIBRARY_PATH пихнуть к остальным env-переменным, за что ему такая честь?

В-третьих, меня напрягает ${JAVA_HOME}/lib/tools.jar в строке запуска. Не выглядит это как стандартная либа жабы. Там точно не ${JBOSS_HOME}?

morse ★★★★★
()
Ответ на: комментарий от morse

Я вот это

Environment=JAVA_HOME=/usr/java/jdk
поменял на
Environment=JAVA_HOME=/usr/java/jdk1.6.0_45

galliley
() автор топика
Ответ на: комментарий от morse

/usr/bin/env явно лишний, путь к жабе указан напрямик

Нет, systemd не разрешает подстановки в пути к исполняемому файлу.

что мешает LD_LIBRARY_PATH пихнуть к остальным env-переменным

Опять же, systemd не умеет рекурсивно подставлять переменные.

меня напрягает ${JAVA_HOME}/lib/tools.jar в строке запуска

Хз, так было в исходном скрипте.

intelfx ★★★★★
()
Ответ на: комментарий от galliley

Вероятно, я опять ошибся с Type. Поставь Type=simple. Понятия не имею, форкается ли процесс java. Видимо, не форкается.

intelfx ★★★★★
()
Ответ на: комментарий от galliley

Дочерние процессы при запущенном исходном тоже не влияют. Тут разница в том, какой процесс systemd считает «главным» (за смертью которого следит).

В случае Type=simple это тот процесс, который был непосредственно запущен (самым первым). Если он умирает — сервис считается упавшим.

В случае Type=forking systemd будет ждать, что запущенный процесс дважды форкнется, и вот этот дважды потомок будет считаться главным процессом. Ещё там можно указать путь к PID-файлу, но я не разбирался в механике работы этой директивы. Если же двойного форка не произошло (т. е. мы ошиблись, указав forking вместо simple), то systemd по прошествии некоторого времени прибьёт все процессы в контрольной группе и скажет, что запуск неуспешен.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 3)
Ответ на: комментарий от intelfx

Нормально заработало вот так:

[Unit]
Description=DICOM server daemon
After=network.target mariadb.service iscsi.service

[Service]
Environment=JBOSS_HOME=/opt/dcm4chee-2.17.3-mysql
Environment=JBOSS_CONF=default
Environment=JBOSS_BIND_ADDR=0.0.0.0
Environment=JAVA_HOME=/usr/java/jdk

ExecStart=/usr/bin/env \
        LD_LIBRARY_PATH=${JBOSS_HOME}/bin/native \
        ${JAVA_HOME}/bin/java \
                -server -Xms254m -Xmx1024m -XX:MaxPermSize=254m -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 \
                -Djboss.messaging.ServerPeerID=0 \
                -Djavax.xml.transform.TransformerFactory=com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl \
                -Djava.awt.headless=true \
                -Dapp.name=dcm4chee \
                -Djava.net.preferIPv4Stack=true \
                -Djava.library.path=${JBOSS_HOME}/bin/native \
                -Djava.endorsed.dirs=${JBOSS_HOME}/lib/endorsed \
                -classpath ${JBOSS_HOME}/bin/run.jar:${JAVA_HOME}/lib/tools.jar org.jboss.Main \
                -b ${JBOSS_BIND_ADDR} -c ${JBOSS_CONF}

ExecStop=/usr/bin/env \
        ${JAVA_HOME}/bin/java \
                -classpath ${JBOSS_HOME}/bin/shutdown.jar:${JBOSS_HOME}/client/jnet.jar \
                org.jboss.Shutdown --shutdown -u admin -p admin

KillMode=control-group

[Install]
WantedBy=multi-user.target

galliley
() автор топика
Ответ на: комментарий от galliley

Как можно к топику добавить тэг dcm4chee?

galliley
() автор топика
Ответ на: комментарий от darkenshvein

Юнит в systemd описывает конфигурацию запуска различных сервисов, таймеров, сокетов и тому подобное, длинный список.

подробней: man systemd.unit

surefire ★★★
()
Ответ на: комментарий от darkenshvein

Это для неосиляторов сисвинит. Забудь.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.