Sybase ASE用のsystemdスクリプトの生成

Sybase ASE用のsystemdスクリプトの生成

systemdで実行するようにSybaseインストールを設定しようとしました。

これ基本的なコマンドはここで説明します。ただし、手動で制御する場合は、次のコマンドを使用して起動します。 (startserverはRUN_SYBASEスクリプトの実行後に終了します。)

su - sybase
cd sqlserver/install
startserver -f RUN_SYBASE_localhost_back
startserver -f RUN_SYBASE_localhost

起動プロセスの詳細を見ることができます

[sybase@localhost install]$ showserver 
F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
0 S sybase   14072 14068  7  80   0 - 157888 futex_ 18:41 ?       00:11:26 /opt/sap/ASE-16_0/bin/dataserver -d/opt/sap/data/master.dat -e/opt/sap/ASE-16_0/install/SYBASE_localhost.log -c/opt/sap/ASE-16_0/SYBASE_localhost.cfg -M/opt/sap/ASE-16_0 -N/opt/sap/ASE-16_0/sysam/SYBASE_localhost.properties -i/opt/sap -sSYBASE_localhost
0 S sybase   14066 14063  0  80   0 -  6521 poll_s 18:41 ?        00:00:00 /opt/sap/ASE-16_0/bin/backupserver -e/opt/sap/ASE-16_0/install/SYBASE_localhost_back.log -N25 -C20 -I/opt/sap/interfaces -M/opt/sap/ASE-16_0/bin/sybmultbuf -SSYBASE_localhost_back

Sybaseを終了するには、Sybase自体でコマンドを実行する必要があります。

[sybase@localhost ~]$  isql -Usa -Ppassword -SSYBASE_localhost << EOF_INPUT
shutdown SYB_BACKUP with nowait
go
shutdown
go
EOF_INPUT

Backup Server: 3.48.1.1: The Backup Server will go down immediately. 
Terminating sessions.
Server SHUTDOWN by request.
ASE is terminating this process.
CT-LIBRARY error:
        ct_results(): network packet layer: internal net library error: Net-Library operation terminated due to disconnect
[sybase@localhost ~]$ echo $?  # yes the error was expected
0

source ~/SYBASE.shこれはbashrcで使用されるsuスクリプトです。しかし、systemdはbashrcを実行しません。 /opt/sap/stop_sybase_commandは、サーバーをシャットダウンするためにsybaseに入力した複数行の文字列です。

[Unit]
Description=Sybase ASE Server 16.0

[Service]
ExecStart=/bin/su sybase -c "source ~/SYBASE.sh; /opt/sap/ASE-16_0/bin/startserver -f /opt/sap/sqlserver/install/RUN_SYBASE_localhost_back; /opt/sap/ASE-16_0/bin/startserver -f /opt/sap/sqlserver/install/RUN_SYBASE_localhost"
ExecStop=/bin/su sybase -c "source ~/SYBASE.sh; /opt/sap/client/bin/isql -Usa -Ppassword -SSYBASE_localhost < /opt/sap/stop_sybase_command"
WorkingDirectory=/opt/sap/ASE-16_0/install/

[Install]
WantedBy=multi-user.target

systemctl start sybase.serviceを使用すると、正常に実行され、サーバーが作成されますが、最終的に失敗すると主張します。私はsybaseを起動した後、startserverコマンドが終了するためだと思います。

Active: failed (Result: exit-code) since Tue 2015-08-25 21:52:43 EDT; 11s ago

反対のアプローチを試してみましたが、Type=forkingこれはより早く失敗したと思いました。

[root@localhost ~]# systemctl start sybase.service 
Job for sybase.service failed. See 'systemctl status sybase.service' and 'journalctl -xn' for details.

しかし、どちらも起動しますが、停止はまったく機能しません。 root で停止コマンドを実行すると、正常に動作します。

[root@localhost ~]# /bin/su sybase -c "source ~/SYBASE.sh; /opt/sap/client/bin/isql -Usa -Ppassword -SSYBASE_localhost < /opt/sap/stop_sybase_command"
Backup Server: 3.48.1.1: The Backup Server will go down immediately. 
Terminating sessions.
Server SHUTDOWN by request.
ASE is terminating this process.
CT-LIBRARY error:
        ct_results(): network packet layer: internal net library error: Net-Library operation terminated due to disconnect
[root@localhost ~]# 

ただし、systemctlの使用を停止しようとすると、ログのステータスセクションでコマンドが失敗したようです。

  Process: 20961 ExecStop=/bin/sh -c /bin/su sybase -c "source ~/SYBASE.sh; /opt/sap/client/bin/isql -Usa -Ppassword -SSYBASE_localhost < /opt/sap/stop_sybase_command" (code=exited, status=255)

ログ自体の場合、stopコマンドに応答して印刷される唯一の内容は次のとおりです。

Aug 25 21:59:48 localhost.localdomain systemd[1]: Stopped Sybase ASE Server 16.0.

私はこのスクリプトの3つの問題を解決しようとしています。

  1. 起動コマンドを実行すると、systemdは失敗したとは思わない。
  2. 実際に Sybase を停止する停止コマンドを実行します。
  3. ステータスが表示されたプロセスshowserverが実行されているかどうかに関するフィードバックを提供します。

ありがとう

修正する:meuhが提案したように、必要なタスクを実行する次のスクリプトを使用しました。

[Unit]
Description=Sybase ASE Server 16.0

[Service]
# Systemd executes a single command with su -c which ignores the bashrc setting our environment, instead su to sybase and run the SYBASE.sh directly

# Could strictly be two services but we'll be lazy and just do one. After starting the backup and main server we find the pid of the main server and drop it into a PID file
ExecStart=/bin/su sybase -c "source ~/SYBASE.sh; /opt/sap/ASE-16_0/bin/startserver -f /opt/sap/sqlserver/install/RUN_SYBASE_localhost_back; /opt/sap/ASE-16_0/bin/startserver -f /opt/sap/sqlserver/install/RUN_SYBASE_localhost; showserver | sed '2q;d'| awk '{ print $4 }' > /opt/sap/sqlserver/install/sybase.pid"

# Shutting down we actually have to issue the command from inside sybase
ExecStop=/bin/sh -c '/bin/su sybase -c "source ~/SYBASE.sh; /opt/sap/client/bin/isql -Usa -Ppassword -SSYBASE_localhost < /opt/sap/stop_sybase_command"'

# The startserver commands exits so we need to track the fork, listed in sybase.pid
Type=forking
PIDFile=/opt/sap/sqlserver/install/sybase.pid
WorkingDirectory=/opt/sap/ASE-16_0/install/

[Install]
WantedBy=multi-user.target

muehさんの質問に回答すると、そのプロセスがコントロールグループに含まれているようですが、手動でkillさせるとそのプロセスが削除されます。

[root@localhost ~]# systemctl status sybase.service |head -7
sybase.service - Sybase ASE Server 16.0
   Loaded: loaded (/etc/systemd/system/sybase.service; enabled)
   Active: active (running) since Wed 2015-09-02 02:41:40 EDT; 23s ago
  Process: 23384 ExecStop=/bin/sh -c /bin/su sybase -c "source ~/SYBASE.sh; /opt/sap/client/bin/isql -Usa -Pscadacom -SSYBASE_localhost < /opt/sap/stop_sybase_command" (code=exited, status=255)
 Main PID: 23431 (backupserver)
   CGroup: /system.slice/sybase.service
           ��� 23431 /opt/sap/ASE-16_0/bin/backupserver -e/opt/sap/ASE-16_0/install/SYBASE_localhost_back.log -N25 -C20 -I/opt/sap/interfaces -M/opt/sap/ASE-16_0/bin/sybmultbuf -SSYBASE_localhost_back
[root@localhost ~]# kill 23431
[root@localhost ~]# systemctl status sybase.service |head -7
sybase.service - Sybase ASE Server 16.0
   Loaded: loaded (/etc/systemd/system/sybase.service; enabled)
   Active: active (running) since Wed 2015-09-02 02:41:40 EDT; 1min 56s ago
  Process: 23384 ExecStop=/bin/sh -c /bin/su sybase -c "source ~/SYBASE.sh; /opt/sap/client/bin/isql -Usa -Pscadacom -SSYBASE_localhost < /opt/sap/stop_sybase_command" (code=exited, status=255)
 Main PID: 23431
   CGroup: /system.slice/sybase.service

[root@localhost ~]# 

はい、���文字がどこから来たのかわかりません。 VMにSSHで接続すると、あちこちで奇妙な内容が現れます(無害なエンコーディングだと思いました)。

答え1

これが私がすることです。フォークやpidファイルは必要なく、sybaseユーザーとして実行できます。 Kill コマンドを使用してデータサーバーを停止するのに満足している場合は、ExecStop は必要ありません。

ユニットファイル... /etc/systemd/system/sybase-srvnane

Sybase サーバーごとに別々の単位ファイルを追加します。

[単位]
説明=Sybaseデータサーバー

[提供する]
ユーザー=サイベース
ExecStart=/home/sybase/bin/run-dataserver SRVNAME
ExecStop=/home/sybase/bin/stop-dataserver SRVNAME

[インストールする]
WantedBy =マルチユーザー。ターゲット

起動スクリプト.../home/sybase/bin/run-dataserver

#!/bin/sh

[ $# -ne 1 ] && echo "使用法: $0 <SYB_SERVER>" && 終了 1
_サーバー=${1}
。 /opt/sybase/SYBASE.sh
_run_file=${SYBROOT}/${SYBASE_ASE}/install/RUN_${_server}
if [ -x ${_run_file} ]
それから
        echo "Sybase サーバーの起動中...${_server}"
        。 ${_run_file}
その他
        echo "実行ファイル ${_run_server} が見つかりません。"
        1番出口
フィリピン諸島

スクリプトの停止... /home/sybase/bin/stop-dataserver

#!/bin/bash

[ $# -ne 1 ] && echo "使用法: $0 <SYB_SERVER>" && 終了 1
_サーバー=${1}
。 /opt/sybase/SYBASE.sh
_isql=${SYBROOT}/${SYBASE_OCS}/bin/isql
if [ -x ${_isql} ]
それから
        echo "Sybase サーバーを停止しています...${_server}"
        ${_isql} -U sa -S ${_server} << EOF
$(cat/home/sybase/.sa_password)
閉鎖
行く
EOF

フィリピン諸島

完全性のためにバックアップサーバーも停止しました... /home/sybase/bin/start-backup-dataserver

#!/bin/bash

[ $# -ne 1 ] && echo "使用法: $0 <SYB_SERVER>" && 終了 1
_サーバー=${1}
。 /opt/sybase/SYBASE.sh
_isql=${SYBROOT}/${SYBASE_OCS}/bin/isql
if [ -x ${_isql} ]
それから
        echo "Sybase バックアップサーバーを停止しています...${_server}"
        ${_isql} -U sa -S ${_server} << EOF
$(cat/home/sybase/.sa_password)
SYB_BACKUP オフ
行く
EOF

フィリピン諸島

/home/sybase/.sa_password ファイルのみをパスワードで読み取るユーザーがいます。

sudo systemctl daemon-reloadこれで終わりました。

答え2

データサーバーのプロセスIDを入力する必要があるファイル名としてエントリを追加してみてください[Service]。たとえば、コマンドでこのpidを取得するには、行をPIDFile=編集します。 Sybaseがそのようなファイルを生成した可能性があります。再使用する必要があるかもしれません。ExecStartshowserverType=forking

exit 0たとえば、最後に追加してExecスクリプトの終了コードが0であることを確認します(動作しているがsystemdが機能しない場合)。


おそらく、あなたのプロセスが何らかの方法でコントロールグループを離れたかもしれません。テストサービスとして以下を使用しています。/etc/systemd/system/myscript.service

[Unit]
Description=Try Forking using PIDFile
After=syslog.target
[Service]
Type=Forking
PIDFile=/tmp/mypid
ExecStart=/bin/bash -c '( (nohup sleep 99999 & echo $! >/tmp/mypid )& sleep 5 )'
ExecStop=/bin/bash -c 'kill -1 $(</tmp/mypid); >/tmp/mypid; exit 0'
[Install]
WantedBy=multi-user.target

私はこれを始めました

$ sudo systemctl daemon-reload
$ sudo systemctl enable myscript
$ sudo systemctl start myscript
$ sudo systemctl status myscript;echo $?
   Loaded: loaded (/etc/systemd/system/myscript.service; enabled)
   Active: active (running) since  09:01:33 CEST; 2s ago
 Main PID: 25485 (bash)
   CGroup: /system.slice/myscript.service
       |-25485 /bin/bash -c ( (nohup sleep 99999 & echo $! >/tmp/mypid )&...
       |-25486 /bin/bash -c ( (nohup sleep 99999 & echo $! >/tmp/mypid )&...
       |-25488 sleep 5
       `-25489 sleep 99999

5秒後、ステータスはスリープ実行中にのみ表示されます。そのpidはにあります/tmp/mypid

$ sudo systemctl status myscript;echo $?
   Active: active (running) since  09:01:33 CEST; 11s ago
 Main PID: 25489 (sleep)
   CGroup: /system.slice/myscript.service
       `-25489 sleep 99999

ステータスに示されているように動作が停止しました。

$ sudo systemctl stop myscript;echo $?
0
$ sudo systemctl status myscript;echo $?
   Active: inactive (dead) since  09:01:55 CEST; 4s ago
  Process: 25504 ExecStop=/bin/bash -c kill ...
  Process: 25489 ExecStart=/bin/bash -c ( (nohup sleep ...
 Main PID: 25489 (code=killed, signal=TERM)
3

再起動して手動でスリープモードを終了すると、systemd はプロセスの終了をすぐに認識し、ExecStop を実行して/tmp/mypid停止せずにファイルを削除します。

$ sudo systemctl start myscript
$ sudo kill -15 $(</tmp/mypid) # pid 25529
$ ps -p $(</tmp/mypid)
   bash: /tmp/mypid: No such file or directory
$ sudo systemctl status myscript;echo $?
   Active: inactive (dead) since  09:03:53 CEST; 9s ago
  Process: 25568 ExecStop=/bin/bash -c kill
  Process: 25529 ExecStart=/bin/bash -c ( (nohup sleep
 Main PID: 25529 (code=killed, signal=TERM)
   09:02:38 systemd[1]: Started Try Forking using PIDFile.
   09:03:53 bash[25568]: /bin/bash: line 0: kill: (25529) - No suc...ss
3
$ sudo systemctl disable myscript;echo $?

答え3

suUser=ユーザーの代わりにキーを使用して、ユニットファイルでユーザーを設定できます。

答え4

たくさん何年も前にこれを行った人に感謝します。私はあなたの最高のアドバイスと私の仕事のいくつかを混ぜて、次のように成功しました。

[Unit]
Description=Sybase ASE Server 16.0
After=network.target

[Service]
Environment=PW=sapassword DS=SERVERNAME
WorkingDirectory=/opt/sap/ASE-16_0/install/
Type=forking

ExecStart=/sbin/runuser sybase -c ". ../../SYBASE.sh; startserver -f RUN_${DS} -f RUN_${DS}_back"
ExecStop= /sbin/runuser sybase -c ". ../../SYBASE.sh; printf 'shutdown\ngo' | isql -Usa -P$PW -S$DS"
    
[Install]
WantedBy=multi-user.target

私はすべてを1つのファイルに収める単純さが好きで、いくつかの問題を解決します。

  • すべてのプロセスを単一の制御グループに維持する/sbin/runuser代わりに使用してください。/bin/suこれにより、サービスが他のサービスと同じように機能します。つまり、systemctl status sybase.serviceサービスを実行するとサービスが実行中であることを示しsystemctl stop sybase.service、正常なシャットダウンを実行するほか、バックアップサーバに TERM を送信します。 runuserおそらくSELinuxを使用している人にのみ必要なようですが、私には多くの意味があります。明らかに、runuserは、rootが権限の低いユーザーに切り替えられる状況のために作成されました。
  • Environment=このファイルをサーバーで実行するには、1行だけ編集できます。
  • パスワードを環境に入力すると、誰かがパスワードを実行したときにパスワードが公開されるのを防ぎますsystemctl status sybase.server。実際のファイルはルートからのみ読み取ることができます。
  • After=network.target起動時にバックアップサーバーが起動することを確認する
  • systemdはPIDfileに対して役に立つ作業をしないので、省略します。

関連情報