4

I've been trying to set up our Sybase installation to run under systemd.

The basic commands are covered here but when we control it manually we start it with the following command (startserver exits after running the RUN_SYBASE scripts)

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

We can see details of the launched processes

[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

And to shut sybase down we need to execute a command in sybase itself

[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

This is what I have for a script so far, the su and source ~/SYBASE.sh is because that's used by the bashrc but systemd doesn't run the bashrc. The /opt/sap/stop_sybase_command is simply the multi-line string typed into sybase to shut down the server.

[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

Using systemctl start sybase.service executes alright and creates the server but ends up claiming it failed, I believe because the startserver commands exits after starting sybase

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

I tried using Type=forking instead but that made it think it failed even earlier.

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

But either way it starts up but stopping doesn't work at all, if I try the stop command as root it works fine

[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 ~]# 

But when I try stop using systemctl all I see in the status portion of the log is the command apparently failing

  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)

And as for the log itself the only thing printed in response to the stop command is the following

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

I'm trying to fix three issues with this script.

  1. Issue a start command without systemd thinking it failed
  2. Issue a stop command that actually stops sybase
  3. Have status give feedback on whether the processes shown by showserver are running

thank you

UPDATE: Following meuh's advice I went with the following script which seems to do what I need

[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

Responding to mueh's question the process seems to be included in the control group but when I manually kill it the process just gets removed.

[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 ~]# 

Yeah, and I'm not sure what the ��� characters are from, it's just some weird thing that pops up all over the place when I'm ssh'd into the VM (I assume it's a harmless encoding thing)

1

Try adding to the [Service] a PIDFile= entry with the name of a file in which you should put the process id of your dataserver. Edit your ExecStart line to get this pid somehow, eg from the showserver command. Such a file may already be created by Sybase. You probably need to use Type=forking again.

Ensure the exit code from your Exec scripts is 0 if they work but systemd says they dont, eg by adding exit 0 at the end.


Perhaps your process is leaving the control group somehow. I used the following as a testing service: in /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

I started this with

$ 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

After 5 seconds the status shows just the sleep running. Its pid is in /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

A stop works, as the status shows:

$ 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

Starting again and killing the sleep by hand makes systemd notice the process death immediately and it runs the ExecStop and removes the /tmp/mypid file without needing to do a stop:

$ 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 $?
  • The altered script isn't quite working after all. If I manually kill the Main PID stored in PIDFile systemctl status seems completely unaware and keeps reporting that it's alive. – Aaron Luchko Aug 31 '15 at 22:10
  • Perhaps your process is leaving the control group. When started does systemctl status show a CGroup including your programs as in the example I added to my answer? – meuh Sep 1 '15 at 12:06
  • I updated the main post but it looks like manually killing just take it out of the control group without triggering the service to die. – Aaron Luchko Sep 2 '15 at 20:54
2

This is what I did. No forking or pid file required and can be run as sybase user. ExecStop is not required if you are happy with the dataserver being stopped with a kill command.

unit file ... /etc/systemd/system/sybase-srvnane

Add a separate unit file for each sybase server.

[Unit]
Description=Sybase dataserver

[Service]
User=sybase
ExecStart=/home/sybase/bin/run-dataserver SRVNAME
ExecStop=/home/sybase/bin/stop-dataserver SRVNAME

[Install]
WantedBy=multi-user.target

start script ... /home/sybase/bin/run-dataserver

#!/bin/sh

[ $# -ne 1 ] && echo "Usage: $0 <SYB_SERVER>" && exit 1
_server=${1}
. /opt/sybase/SYBASE.sh
_run_file=${SYBROOT}/${SYBASE_ASE}/install/RUN_${_server}
if [ -x ${_run_file} ]
then
        echo "Starting Sybase server ... ${_server}"
        . ${_run_file}
else
        echo "Cannot find run file ${_run_server}"
        exit 1
fi

stop script ... /home/sybase/bin/stop-dataserver

#!/bin/bash

[ $# -ne 1 ] && echo "Usage: $0 <SYB_SERVER>" && exit 1
_server=${1}
. /opt/sybase/SYBASE.sh
_isql=${SYBROOT}/${SYBASE_OCS}/bin/isql
if [ -x ${_isql} ]
then
        echo "Stopping Sybase server .... ${_server}"
        ${_isql} -U sa -S ${_server} << EOF
$( cat /home/sybase/.sa_password )
shutdown
go
EOF

fi

For completeness I also have stop for a backup server ... /home/sybase/bin/start-backup-dataserver

#!/bin/bash

[ $# -ne 1 ] && echo "Usage: $0 <SYB_SERVER>" && exit 1
_server=${1}
. /opt/sybase/SYBASE.sh
_isql=${SYBROOT}/${SYBASE_OCS}/bin/isql
if [ -x ${_isql} ]
then
        echo "Stopping Sybase backup server .... ${_server}"
        ${_isql} -U sa -S ${_server} << EOF
$( cat /home/sybase/.sa_password )
shutdown SYB_BACKUP
go
EOF

fi

I have a user read-only file /home/sybase/.sa_password for the password.

sudo systemctl daemon-reload and you are done.

0

Instead of using su for user you can use User= key for setting user in unit file

  • This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you can always comment on your own posts, and once you have sufficient reputation you will be able to comment on any post. – dhag Sep 1 '15 at 18:02
  • Op is trying run script as Sybase user and it accomplished by specifying user= key in unit file – AbdulKareem Sep 1 '15 at 18:07
  • It would be best if you expanded your answer to explain exactly which file should be modified, as well as how and why. As it is, your answer genuinely looked to me like a comment to the other answer. – dhag Sep 1 '15 at 18:15
  • I tried using User= but still needed to do a /bin/sh in the Exec commands in order to source ~/SYBASE.sh, I thought it seemed simpler to do it with /bin/su in the Exec lines – Aaron Luchko Sep 2 '15 at 17:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.