The point of no return

We’re using Hsqldb and Glassfish on a project, our developers found some scripts to run java applications as daemon and it was ok for a while but when they started to report problems about the services I checked what they’re using. A lot of function’s, write’s, check’s, for’s, while’s, if’s, else’s etc.. There should be an easy way to do this? Guess what I decided to make it simple, Yet another NIH Syndrome ? :) Let me try to explain.. Bytheway we dont want to compile source code or add any 3rd party repositories.

But 1st what is a daemon? Daemon stands for Disk and Execution Monitor and is a long-running background process that answers requests for services. As explained in Wikipedia:

On a Unix-like system, the common method for a process to become a daemon, when the process is started from the command line or from a startup script such as an init script or a SystemStarter script, involves:

  1. Dissociating from the controlling tty
  2. Becoming a session leader
  3. Becoming a process group leader
  4. Executing as a background task by forking and exiting (once or twice). This is required sometimes for the process to become a session leader. It also allows the parent process to continue its normal execution.
  5. Setting the root directory (/) as the current working directory so that the process does not keep any directory in use that may be on a mounted file system (allowing it to be unmounted).
  6. Changing the umask to 0 to allow open(), creat(), et al. operating system calls to provide their own permission masks and not to depend on the umask of the caller
  7. Closing all inherited files at the time of execution that are left open by the parent process, including file descriptors 0, 1 and 2 for the standard streams (stdin, stdout and stderr). Required files will be opened later.
  8. Using a logfile, the console, or /dev/null as stdin, stdout, and stderr

There are some methods to run application as daemon on Linux such as; start-stop-daemon (part of dpkg package), Red Hat init.d function, Nohup

Start-stop-daemon: It’s a good tool but EPEL dpkg package does not consist it, I don’t know why ?
Red Hat init.d function: Setting application/working directory could be problem also not possible to get StdOut & StdErr outputs as log file
Nohup: No automation, you have to write lots of things.. nohup $command >>$log_file 2>&1 & echo \$! >$pid_file

No start-stop-daemon in EPEL repository, RHEL init.d daemon function is not enough, Nohup requires bash scripting knowledge.. Ok what now ??
Instead use Daemonize. Daemonize runs a command as a Unix daemon, it’s a good alternative for start-stop-daemon and daemonize package is in the EPEL repository.

I wrote an init.d script (Jdis) to run java applications as daemon with daemonize on RHEL and CentOS Linux, you can download Jdis from GitHub: java_daemon-init.sh

Hsqldb Init script example

An example from real world situation; Hsqldb. HyperSQL DataBase (Hsqldb) is a relational database software written in Java. It offers a small, fast multithreaded and transactional database engine with in-memory and disk-based tables and supports embedded and server mode.

Let’s daemonize it..

We dont want to run the application with root user

[root@zion ~]# useradd hsqldb -s /sbin/nologin

Change owner of the application directory

[root@zion ~]# chown -R hsqldb:hsqldb /opt/hsqldb
/etc/init.d/hsqldb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/bin/bash
#
# Jdis - Java daemon init-script for Red Hat / CentOS Linux
# Ali Erdinc Koroglu - http://ae.koroglu.org
# License : GNU GPL (http://www.gnu.org/licenses/gpl.html)
#
# You must install daemonize package from EPEL repository to use this script.
# How to add EPEL repository: http://ae.koroglu.org/docs/adding-epel-repository-on-centos/
#
# History:
# 2014-08-19 : First release
 
# chkconfig: 345 85 15
# description: Java daemon script
 
### BEGIN INIT INFO
# Provides:
# Required-Start: $local_fs $network $syslog $time
# Required-Stop: $local_fs $network $syslog $time
# Short-Description: start and stop Java daemons
# Description: Java daemon init script
### END INIT INFO
 
# source function library
. /etc/init.d/functions
 
# Java Home
java_home="/usr/java/jdk1.7.0_45"                                               # java path
 
# Service settings
service_name="hsqldb"                                                           # Service name
service_user="hsqldb"                                                           # User/group of process
pid_file="/var/run/$service_name.pid"                                           # Pid file
log_file="/var/log/$service_name/$service_name.log"                             # StdOut log file
errlog_file="/var/log/$service_name/$service_name-error.log"                    # StdErr log file
java="$java_home/bin/java"                                                      # Java binary
java_appdir="/opt/hsqldb/data"                                                  # Application path
java_applibdir="/opt/hsqldb/lib"                                                # Application Lib path
java_arg1="-server -Xms1G -Xmx6G -XX:NewSize=256m"                              # Argument 1
java_arg2="-XX:MaxNewSize=256m -XX:PermSize=512m -XX:MaxPermSize=512m"          # Argument 2
java_arg3="-Dproject.properties=$java_appdir/test.properties"                   # Argument 3
java_arg4="-classpath $java_applibdir/hsqldb.jar org.hsqldb.server.Server"      # Argument 4
java_args="$java_arg1 $java_arg2 $java_arg3 $java_arg4"                         # Java Arguments
 
RETVAL=0
start() {
    [ -x $java ] || exit 5
    echo -n $"Starting $service_name: "
    if [ $EUID -ne 0 ]; then
        RETVAL=1
        failure
    elif [ -s /var/run/$service_name.pid ]; then
        RETVAL=1
        echo -n $"already running.."
        failure
    else
        daemonize -u $service_user -p $pid_file -o $log_file -e $errlog_file -c $java_appdir $java $java_args && success || failure
        RETVAL=$?
        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$service_name
    fi;
    echo
    return $RETVAL
}
 
stop() {
    echo -n $"Stopping $service_name: "
    if [ $EUID -ne 0 ]; then
        RETVAL=1
        failure
    else
        killproc -p $pid_file
        RETVAL=$?
        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$service_name
    fi;
    echo
    return $RETVAL
}
 
restart(){
    stop
    start
}
 
case "$1" in
    start)
        start
        RETVAL=$?
        ;;
    stop)
        stop
        RETVAL=$?
        ;;
    restart)
        restart
        RETVAL=$?
        ;;
    status)
        status $service_name
        RETVAL=$?
        ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart}"
        RETVAL=2
esac
exit $RETVAL

lets check..

[root@zion ~]# /etc/init.d/hsqldb start
Starting hsqldb:                                           [  OK  ]
[root@zion ~]# ps aux | grep hsqldb
hsqldb     463  178  1.0 8555172 349364 ?      Ssl  15:04   0:10 /usr/java/jdk1.7.0_45/bin/java -server -Xms1G -Xmx6G -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=512m -XX:MaxPermSize=512m -Dproject.properties=/usr/share/pronet/hsqldb/data/test.properties -classpath /usr/share/pronet/hsqldb/lib/hsqldb.jar org.hsqldb.server.Server
root       485  0.0  0.0 103244   848 pts/0    R+   15:04   0:00 grep hsqldb
[root@zion ~]# /etc/init.d/hsqldb status
hsqldb (pid  463) is running...
[root@zion ~]# /etc/init.d/hsqldb stop
Stopping hsqldb:                                           [  OK  ]

Iterative Bash Script to Generate Fibonacci Series

23rd June 2013 by Ali Erdinç Köroğlu

In mathematics, the Fibonacci series are the numbers in the following integer sequence as 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144..
As you already know that recursion is a function that call itself, too many levels of recursion may crash script with a segfault. So lets write fibonacci series with iterative method.

1
2
3
4
5
6
7
8
9
10
#!/bin/bash
l=1
n=0
for (( i=0; i<=25; i++ ))
do
    echo -n "$n "
    n=$(($n+$l))
    l=$(($n-$l))
done
echo ""

Output and time

erdinc@gauss ~ $ time ./fibo 
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025

real    0m0.009s
user    0m0.005s
sys     0m0.003s

WordPress, php-rss reader ve simpleXML üzerine

10th June 2008 by Ali Erdinç Köroğlu

Şu aralar YDÜ-IBM innovasyon merkeziyle haşır neşir yollarda seyyah misali dolaşıyorken web temelli bir projede içerik yönetim sistemi içine başka bir kaynaktan rss çekip göstermek gerekti, php5 ile birlikte gelen aşağıda bir örneğini gördüğünüz simpleXML’i kullanayım dedim.

1
2
3
4
5
6
7
<?php
$rss =  simplexml_load_file('http://erdinc.neu.edu.tr/?feed=rss2&cat=8');
$title =  $rss->channel->title;
foreach ($rss->channel->item as $item) {
  echo "<a href='" . $item->link . "'>" . $item->title . "</a>";
  echo "<p>" . $item->content . "</p>";}
?>

Buraya kadar her şey normal ancak wordpress “Description” tag’ın da belirli bir karakter sayısından sonra feed içine […] kokuyor. Dönüp wordpress koduna baktıktan sonra bu işi en kısa yoldan aşağıdaki gibi çözebilirim diye düşündüm. Böylelikle simpleXML’de kısıtlama olmayan içeriği çok rahat alabildim.

1
2
3
4
5
6
7
8
9
10
11
--- wp-includes/feed-rss2.php.org   2008-06-10 03:08:48.000000000 +0300
+++ wp-includes/feed-rss2.php       2008-06-10 03:45:25.000000000 +0300
@@ -43,9 +43,9 @@
<?php else : ?>
                <description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
        <?php if ( strlen( $post->post_content ) > 0 ) : ?>
-               <content:encoded><![CDATA[<?php the_content() ?>]]></content:encoded>
+               <content><![CDATA[<?php the_content() ?>]]></content>
        <?php else : ?>
-               <content:encoded><![CDATA[<?php the_excerpt_rss() ?>]]></content:encoded>
+               <content><![CDATA[<?php the_excerpt_rss() ?>]]></content>

Belki bir gün birini işine yarar, şimdilik google’ın tozlu raflarından birine yerleşsin :)