You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by al...@apache.org on 2012/07/25 01:11:42 UTC

[29/38] git commit: Remove cloud-daemonize and use JSVC

Remove cloud-daemonize and use JSVC

We now use JSVC for daemonizing our agent and usage server.


Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/eab3e478
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/eab3e478
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/eab3e478

Branch: refs/heads/vpc
Commit: eab3e4783e0f8aba7dab889bdfcc441a028b387a
Parents: c99b1d1
Author: Wido den Hollander <wi...@widodh.nl>
Authored: Tue Jul 24 15:18:32 2012 +0200
Committer: Wido den Hollander <wi...@widodh.nl>
Committed: Tue Jul 24 19:32:39 2012 +0200

----------------------------------------------------------------------
 agent/conf/environment.properties.in               |    1 +
 .../distro/ubuntu/SYSCONFDIR/init.d/cloud-agent.in |   46 ++-
 agent/libexec/agent-runner.in                      |   88 ----
 agent/src/com/cloud/agent/AgentShell.java          |   39 +-
 daemonize/daemonize.c                              |  351 ---------------
 debian/control                                     |    4 +-
 .../distro/ubuntu/SYSCONFDIR/init.d/cloud-usage.in |   28 +-
 usage/libexec/usage-runner.in                      |   37 --
 usage/src/com/cloud/usage/UsageServer.java         |   19 +-
 9 files changed, 93 insertions(+), 520 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/eab3e478/agent/conf/environment.properties.in
----------------------------------------------------------------------
diff --git a/agent/conf/environment.properties.in b/agent/conf/environment.properties.in
index c38e2b8..7fcf570 100644
--- a/agent/conf/environment.properties.in
+++ b/agent/conf/environment.properties.in
@@ -18,3 +18,4 @@
 # management server compile-time environment parameters
 
 paths.pid=@PIDDIR@
+paths.scripts=@AGENTLIBDIR@

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/eab3e478/agent/distro/ubuntu/SYSCONFDIR/init.d/cloud-agent.in
----------------------------------------------------------------------
diff --git a/agent/distro/ubuntu/SYSCONFDIR/init.d/cloud-agent.in b/agent/distro/ubuntu/SYSCONFDIR/init.d/cloud-agent.in
index c4607cb..e2bbdb6 100755
--- a/agent/distro/ubuntu/SYSCONFDIR/init.d/cloud-agent.in
+++ b/agent/distro/ubuntu/SYSCONFDIR/init.d/cloud-agent.in
@@ -36,15 +36,33 @@ whatami=cloud-agent
 # set environment variables
 
 SHORTNAME="$whatami"
-PIDFILE=@PIDDIR@/"$whatami".pid
-LOCKFILE=@LOCKDIR@/"$SHORTNAME"
-LOGFILE=@AGENTLOG@
+PIDFILE=/var/run/"$whatami".pid
+LOCKFILE=/var/lock/subsys/"$SHORTNAME"
+LOGFILE=/var/log/cloud/agent/agent.log
 PROGNAME="Cloud Agent"
+CLASS="com.cloud.agent.AgentShell"
 
 unset OPTIONS
-[ -r @SYSCONFDIR@/default/"$SHORTNAME" ] && source @SYSCONFDIR@/default/"$SHORTNAME"
-DAEMONIZE=@BINDIR@/@PACKAGE@-daemonize
-PROG=@LIBEXECDIR@/agent-runner
+[ -r /etc/default/"$SHORTNAME" ] && source /etc/default/"$SHORTNAME"
+
+# The first existing directory is used for JAVA_HOME (if JAVA_HOME is not defined in $DEFAULT)
+JDK_DIRS="/usr/lib/jvm/java-6-openjdk /usr/lib/jvm/java-6-openjdk-i386 /usr/lib/jvm/java-6-openjdk-amd64 /usr/lib/jvm/java-6-sun /usr/lib/jvm/java-1.5.0-sun /usr/lib/j2sdk1.5-sun /usr/lib/j2sdk1.5-ibm"
+
+for jdir in $JDK_DIRS; do
+    if [ -r "$jdir/bin/java" -a -z "${JAVA_HOME}" ]; then
+        JAVA_HOME="$jdir"
+    fi
+done
+export JAVA_HOME
+
+SCP="@SYSTEMCLASSPATH@"
+DCP="@DEPSCLASSPATH@"
+ACP="@AGENTCLASSPATH@"
+JCP="/usr/share/java/commons-daemon.jar"
+
+# We need to append the JSVC daemon JAR to the classpath
+# AgentShell implements the JSVC daemon methods
+export CLASSPATH="$SCP:$DCP:$ACP:$JCP:@AGENTSYSCONFDIR@"
 
 wait_for_network() {
     i=1
@@ -79,9 +97,7 @@ start() {
 
         wait_for_network
 
-	if start-stop-daemon --start --quiet \
-		--pidfile "$PIDFILE" \
-		--exec "$DAEMONIZE" -- -n "$SHORTNAME" -p "$PIDFILE" -l "$LOGFILE" "$PROG" $OPTIONS
+	if jsvc -cp "$CLASSPATH" -pidfile "$PIDFILE" $CLASS
 		RETVAL=$?
 	    then
 		rc=0
@@ -107,11 +123,11 @@ stop() {
     count="0"
 
     echo -n $"Stopping $PROGNAME" "$SHORTNAME"
-    start-stop-daemon --stop --quiet --oknodo --pidfile "$PIDFILE"
+    jsvc -pidfile "$PIDFILE" -stop $CLASS
 
     until [ "$count" -gt "$SHUTDOWN_WAIT" ]
     do
-        agentPid=`ps aux|grep [j]ava|grep cloud-agent`
+        agentPid=`ps aux|grep [j]svc|grep cloud-agent`
         if [ "$?" -gt "0" ];then
             break
         fi
@@ -119,16 +135,16 @@ stop() {
         let count="${count}+1"
     done
 
-    agentPid=`ps aux|grep [j]ava|grep cloud-agent`
+    agentPid=`ps aux|grep [j]svc|grep cloud-agent`
     if [ "$?" -eq "0" ]; then
-         agentPid=`ps aux|grep [j]ava|awk '{print $2}'`
+         agentPid=`ps aux|grep [j]svc|awk '{print $2}'`
          if [ "$agentPid" != "" ]; then
               kill -9 $agentPid
          fi
     fi
 
-	log_end_msg $?
-	rm -f "$PIDFILE"
+    log_end_msg $?
+    rm -f "$PIDFILE"
 }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/eab3e478/agent/libexec/agent-runner.in
----------------------------------------------------------------------
diff --git a/agent/libexec/agent-runner.in b/agent/libexec/agent-runner.in
deleted file mode 100755
index 8e548ae..0000000
--- a/agent/libexec/agent-runner.in
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env bash
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-# 
-#   http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-#run.sh runs the agent client.
-
-cd `dirname "$0"`
-
-SYSTEMJARS="@SYSTEMJARS@"
-SCP=$(build-classpath $SYSTEMJARS) ; if [ $? != 0 ] ; then SCP="@SYSTEMCLASSPATH@" ; fi
-DCP="@DEPSCLASSPATH@"
-ACP="@AGENTCLASSPATH@"
-export CLASSPATH=$SCP:$DCP:$ACP:@AGENTSYSCONFDIR@
-for jarfile in "@PREMIUMJAVADIR@"/* ; do
-	if [ ! -e "$jarfile" ] ; then continue ; fi
-	CLASSPATH=$jarfile:$CLASSPATH
-done
-for plugin in "@PLUGINJAVADIR@"/* ; do
-	if [ ! -e "$plugin" ] ; then continue ; fi
-	CLASSPATH=$plugin:$CLASSPATH
-done
-export CLASSPATH
-
-set -e
-cd "@AGENTLIBDIR@"
-echo Current directory is "$PWD"
-echo CLASSPATH to run the agent: "$CLASSPATH"
-
-export PATH=/sbin:/usr/sbin:"$PATH"
-SERVICEARGS=
-for x in private public ; do
-	configuration=`grep "^$x.network.device" "@AGENTSYSCONFDIR@"/agent.properties||true`
-	if [ -n "$configuration" ] ; then
-		echo "Using manually-configured network device $CONFIGURATION"
-	else
-		defaultroute=`ip route | grep ^default | cut -d ' ' -f 5`
-		test -n "$defaultroute"
-		echo "Using auto-discovered network device $defaultroute which is the default route"
-		SERVICEARGS="$SERVICEARGS $x.network.device="$defaultroute
-	fi
-done
-
-function termagent() {
-    if [ "$agentpid" != "" ] ; then
-	echo Killing VMOps Agent "(PID $agentpid)" with SIGTERM >&2
-	kill -TERM $agentpid
-	echo Waiting for agent to exit >&2
-	wait $agentpid
-	ex=$?
-	echo Agent exited with return code $ex >&2	
-    else
-	echo Agent PID is unknown >&2
-    fi
-}
-
-trap termagent TERM
-while true ; do
-	java -Xms128M -Xmx384M -cp "$CLASSPATH" "$@" com.cloud.agent.AgentShell $SERVICEARGS &
-	agentpid=$!
-	echo "Agent started.  PID: $!" >&2
-	wait $agentpid
-	ex=$?
-	if [ $ex -gt 128 ]; then
-		echo "wait on agent process interrupted by SIGTERM" >&2
-		exit $ex
-	fi
-	echo "Agent exited with return code $ex" >&2
-	if [ $ex -eq 0 ] || [ $ex -eq 1 ] || [ $ex -eq 66 ] || [ $ex -gt 128 ]; then
-		echo "Exiting..." > /dev/stderr
-		exit $ex
-	fi
-	echo "Restarting agent..." > /dev/stderr
-	sleep 1
-done

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/eab3e478/agent/src/com/cloud/agent/AgentShell.java
----------------------------------------------------------------------
diff --git a/agent/src/com/cloud/agent/AgentShell.java b/agent/src/com/cloud/agent/AgentShell.java
index 941f094..ca3f7de 100644
--- a/agent/src/com/cloud/agent/AgentShell.java
+++ b/agent/src/com/cloud/agent/AgentShell.java
@@ -27,6 +27,7 @@ import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.HttpURLConnection;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -371,7 +372,7 @@ public class AgentShell implements IAgentShell {
         return true;
     }
 
-    private void init(String[] args) throws ConfigurationException {
+    public void init(String[] args) throws ConfigurationException {
 
         final ComponentLocator locator = ComponentLocator.getLocator("agent");
 
@@ -383,8 +384,14 @@ public class AgentShell implements IAgentShell {
         }
         s_logger.info("Implementation Version is " + _version);
 
+        loadProperties();
         parseCommand(args);
 
+        List<String> properties = Collections.list((Enumeration<String>)_properties.propertyNames());
+        for (String property:properties){
+            s_logger.debug("Found property: " + property);
+        }
+
         _storage = locator.getManager(StorageComponent.class);
         if (_storage == null) {
             s_logger.info("Defaulting to using properties file for storage");
@@ -558,13 +565,10 @@ public class AgentShell implements IAgentShell {
         return _nextAgentId++;
     }
 
-    private void run(String[] args) {
+    public void start() {
         try {
             System.setProperty("java.net.preferIPv4Stack", "true");
 
-            loadProperties();
-            init(args);
-
             String instance = getProperty(null, "instance");
             if (instance == null) {
                 if (Boolean.parseBoolean(getProperty(null, "developer"))) {
@@ -579,7 +583,7 @@ public class AgentShell implements IAgentShell {
             String pidDir = getProperty(null, "piddir");
 
             final String run = "agent." + instance + "pid";
-            s_logger.debug("Checking to see if " + run + "exists.");
+            s_logger.debug("Checking to see if " + run + " exists.");
             ProcessUtil.pidCheck(pidDir, run);
 
             launchAgent();
@@ -616,22 +620,17 @@ public class AgentShell implements IAgentShell {
         }
     }
 
-    public static void main(String[] args) {
-        AgentShell shell = new AgentShell();
-        Runtime.getRuntime().addShutdownHook(new ShutdownThread(shell));
-        shell.run(args);
-    }
-
-    private static class ShutdownThread extends Thread {
-        AgentShell _shell;
+    public void destroy() {
 
-        public ShutdownThread(AgentShell shell) {
-            this._shell = shell;
-        }
+    }
 
-        @Override
-        public void run() {
-            _shell.stop();
+    public static void main(String[] args) {
+        try {
+            AgentShell shell = new AgentShell();
+            shell.init(args);
+            shell.start();
+        } catch (ConfigurationException e) {
+            System.out.println(e.getMessage());
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/eab3e478/daemonize/daemonize.c
----------------------------------------------------------------------
diff --git a/daemonize/daemonize.c b/daemonize/daemonize.c
deleted file mode 100644
index 0d3e392..0000000
--- a/daemonize/daemonize.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
- 
-  http://www.apache.org/licenses/LICENSE-2.0
- 
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-/*
-UNIX daemonizer.  Daemonizes any non-interactive console program and watches over it.
-Whenever a signal is sent to this process, it halts the daemonized process as well.
-
-To compile:	cc -o daemonize daemonize.c
-Usage:		./daemonize -?
-Users of this:	catalina initscript
-*/
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <unistd.h>
-#include <syslog.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <pwd.h>
-
-#define RUNNING_DIR	"/"
-#define PIDFILE		"/var/run/daemonize.pid"
-#define VARLOGFILE 	"/var/log/daemon.log"
-#define PROGNAME	"daemonized"
-#define DEFAULTUSER	"root"
-
-char * pidfile = PIDFILE;
-char * varlogfile = VARLOGFILE;
-char * progname = PROGNAME;
-char * user = PROGNAME;
-
-void initialize_syslog(const char*pn) {
-	openlog(pn,LOG_PID,LOG_DAEMON);
-	syslog(LOG_INFO, "syslog connection opened");
-}
-
-void cleanup_syslog() {
-	syslog(LOG_INFO, "syslog connection closed");
-	closelog(); 
-}
-
-int killed = 0;
-int killsignal = 0;
-int pidfile_fd;
-int varlogfile_fd;
-int uid = 0; int gid = 0;
-struct passwd *creds;
-
-void signal_handler(sig)
-int sig;
-{
-	killsignal = sig;
-	switch(sig) {
-	case SIGCHLD:
-		syslog(LOG_INFO,"sigchild signal caught");
-		break;
-	case SIGHUP:
-		syslog(LOG_INFO,"hangup signal caught");
-		killed = 1;
-		break;
-	case SIGTERM:
-		syslog(LOG_INFO,"terminate signal caught");
-		killed = 1;
-		break;
-	case SIGINT:
-		syslog(LOG_INFO,"keyboard interrupt signal caught");
-		killed = 1;
-		break;
-	}
-}
-
-int daemonize(const char*prog_name)
-{
-
-	char str[10];
-	int i;
-	int bufsize=1024; char *buf = malloc(1024);
-	
-	umask( S_IWGRP | S_IROTH | S_IWOTH ); /* set newly created file permissions */
-	
-	/* test logfile */
-	varlogfile_fd=open(varlogfile,O_RDWR|O_CREAT|O_APPEND,0666);
-	if (varlogfile_fd == -1) {
-		snprintf(buf,bufsize,"Could not open output file %s -- exiting",varlogfile); perror(buf);
-		return 1; /* exitvalue */
-	}
-	if (uid != 0) {
-		chown(varlogfile,uid,gid);
-	}
-	close(varlogfile_fd);
-	pidfile_fd=open(pidfile,O_RDWR|O_CREAT,0666);
-	if (pidfile_fd<0) {
-		snprintf(buf,bufsize,"The PID file %s cannot be opened -- exiting",pidfile); perror(buf);
-		return 2; /* exitvalue */
-	}
-	if (lockf(pidfile_fd,F_TEST,0)==1) {
-		snprintf(buf,bufsize,"A daemon is already running (cannot lock PID file %s) -- exiting",pidfile); perror(buf);
-		return 3; /* exitvalue */
-	}
-	close(pidfile_fd);
-	
-	if(getppid()==1) return 0; /* already a daemon */
-	i=fork();
-	if (i < 0) return 4; /* exitvalue */ /* fork error */
-	if (i > 0) exit(0); /* parent exits */
-
-	/* child (daemon) continues */
-	setsid(); /* obtain a new process group */
-
-	chdir(RUNNING_DIR); /* change running directory */
-	 
-	/* close FDs and reopen to logfile */
-	for (i=getdtablesize();i>=0;--i) close(i); /* close all descriptors */
-	varlogfile_fd=open(varlogfile,O_RDWR|O_APPEND,0666); dup(varlogfile_fd); dup(varlogfile_fd); /* handle standart I/O */
-	initialize_syslog(prog_name); /* set up syslog */
-	
-	/* PID file */
-	pidfile_fd=open(pidfile,O_RDWR|O_CREAT,0666);
-	if (pidfile_fd<0) {
-		syslog(LOG_ERR,"The PID file %s cannot be opened (%m) -- exiting",pidfile);
-		return 2; /* exitvalue */
-	}
-	if (lockf(pidfile_fd,F_TLOCK,0)<0) {
-		syslog(LOG_ERR,"A daemon is already running -- cannot lock PID file %s (%m) -- exiting",pidfile);
-		return 3; /* exitvalue */
-	}
-
-	/* first instance continues */
-	
-	/* record pid to pidfile */
-	sprintf(str,"%d\n",getpid());
-	if (write(pidfile_fd,str,strlen(str)) < strlen(str)) {
-		syslog(LOG_ERR,"Could not write PID into PID file %s (%m) -- exiting",pidfile);
-		return 5; /* exitvalue */
-	}
-	signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
-	signal(SIGTTOU,SIG_IGN);
-	signal(SIGTTIN,SIG_IGN);
-	signal(SIGHUP,signal_handler); /* catch hangup signal */
-	signal(SIGTERM,signal_handler); /* catch kill signal */
-	signal(SIGINT,signal_handler); /* catch keyboard interrupt signal */
-	
-	return 0;
-}
-
-void cleanup() {
-	cleanup_syslog();
-	unlink(pidfile);
-	close(pidfile_fd);
-	close(varlogfile_fd);
-}
-
-void usage(char * cmdname) {
-	fprintf (stderr,
-		"Usage: %s [options...] -- <command> [command-specific arguments...]\n"
-		"Daemonize any program.\n"
-		"\n"
-		"Options:\n"
-		"\n"
-		"	-l <logfile>:   log stdout/stderr to this *absolute* path (default "VARLOGFILE")\n"
-		"	-u <username>:   setuid() to this user name before starting the program (default "DEFAULTUSER")\n"
-		"	-p <pidfile>:   lock and write the PID to this *absolute* path (default "PIDFILE")\n"
-		"	-n <progname>:  name the daemon assumes (default "PROGNAME")\n"
-		"	-h: show this usage guide\n"
-		"\n"
-		"Exit status:\n"
-		" 0      if daemonized correctly\n"
-		" other  if an error took place\n"
-		"", cmdname);
-	exit(0);
-}
-
-int parse_args(int argc,char ** argv) {
-	int index;
-	int c;
-	
-// 	pidfile = PIDFILE;
-// 	varlogfile = VARLOGFILE;
-// 	progname = PROGNAME;
-	
-	opterr = 0;
-	
-	while ((c = getopt (argc, argv, "l:p:n:u:")) != -1)
-		switch (c)
-		{
-			case 'l':
-				varlogfile = optarg;
-				break;
-			case 'p':
-				pidfile = optarg;
-				break;
-			case 'n':
-				progname = optarg;
-				break;
-			case 'u':
-				if (getuid() != 0) {
-					fprintf (stderr, "-u can only be used by root.\nSee help with -h\n", user);
-					exit(64);
-				}
-				user = optarg;
-				creds = getpwnam(user);
-				if (creds == NULL) {
-					fprintf (stderr, "User %s was not found in the user database.\nSee help with -h\n", user);
-					exit(63);
-				}
-				uid = creds->pw_uid; gid = creds->pw_gid;
-				break;
-// 			case 'h':
-// 				break;
-// 				usage(argv[0]); /* halts after this */
-			case '?':
-				if (optopt == '?' || optopt == 'h')
-					usage(argv[0]); /* halts after this */
-				if (optopt == 'l' || optopt == 'p' || optopt == 'n')
-					fprintf (stderr, "Option -%c requires an argument.\nSee help with -h\n", optopt);
-				else if (isprint (optopt))
-					fprintf (stderr, "Unknown option `-%c'.\nSee help with -h\n", optopt);
-				else
-					fprintf (stderr, "Unknown option character `\\x%x'.\nSee help with -h\n", optopt);
-				exit(64); /* exitvalue */
-			default:
-				abort ();
-		}
-	
-	for (index = optind; index < argc; index++);
-
-	if (index == optind) {
-		fprintf (stderr, "You need to specify a command to run.\nSee help with -h\n", optopt);
-		exit(64); /* exitvalue */
-	}
-
-	return optind;
-}
-
-int main(int argc, char** argv)
-{
-	/* parse command line arguments, we will use the first non-option one as the starting point */
-	int i;
-	char ** newargv = calloc(argc+1, sizeof(char**));
-	int startat = parse_args(argc,argv);
-	int newargc = argc - startat; 
-	for (i = startat; i < argc; i++) { newargv[i-startat] = argv[i]; }
-
-	/* try and daemonize */
-	int daemonret = daemonize(progname);
-	if (daemonret) exit(daemonret);
-	syslog(LOG_INFO,"successfully daemonized");
-
-	/* fork */
-	int pid, wpid, status, execret;
-	syslog(LOG_INFO,"starting %s in subprocess",newargv[0]);
-	pid = fork();
-	if (pid < 0) {
-		/* failed to fork, damnit! */
-		syslog(LOG_ERR,"could not fork to run %s as a child process (%m)",newargv[0]);
-		exit(4); /* exitvalue */
-	}
-	else if (pid == 0) {
-		/* child */
-		if (uid != 0) {
-			execret = setgid(gid);
-			if (execret == -1) {
-				syslog(LOG_ERR,"could not setgid() to gid %d",gid);
-				exit(8); /* exitvalue */
-			}
-			execret = setuid(uid);
-			if (execret == -1) {
-				syslog(LOG_ERR,"could not setuid() to uid %d",uid);
-				exit(8); /* exitvalue */
-			}
-		}
-		execret = execvp(newargv[0],newargv);
-		if (errno == 2) {
-			syslog(LOG_ERR,"could not run program: no such file or directory");
-			exit(127);
-		}
-		if (errno == 13) {
-			syslog(LOG_ERR,"could not run program: permission denied");
-			exit(126);
-		}
-		syslog(LOG_ERR,"could not run program: unknown reason");
-		exit(255);
-	}
-
-	/* parent continues here */
-	syslog(LOG_INFO,"successfully started subprocess -- PID %d",pid);
-	int finalexit = 0;
-	int waitret = 0;
-	while (1) {
-		if (killed) {
-			kill(pid,killsignal);
-			killed = 0;
-		}
-		waitret = waitpid(pid,&status,WNOHANG);
-		if (waitret == pid) break;
-		usleep(250000);
-	}
-	
-	
-	if WIFEXITED(status) {
-		switch (WEXITSTATUS(status)) {
-			case 0:
-				syslog(LOG_INFO,"%s exited normally",newargv[0]);
-				break;
-			case 126:
-				syslog(LOG_ERR,"%s: permission denied",newargv[0]);
-				finalexit = 126; /* exitvalue */
-				break;
-			case 127:
-				syslog(LOG_ERR,"%s: command not found",newargv[0]);
-				finalexit = 127; /* exitvalue */
-				break;
-			default:
-				syslog(LOG_INFO,"%s exited abnormally with status %d",newargv[0],WEXITSTATUS(status));
-				finalexit = 6; /* exitvalue */
-		}
-	}
-	if WIFSIGNALED(status) {
-		syslog(LOG_INFO,"%s was killed with signal %d",newargv[0],WTERMSIG(status));
-		finalexit = 7; /* exitvalue */
-	}
-
-	syslog(LOG_INFO,"shutting down");
-	cleanup();
-	exit(finalexit);
-}
-
-/* EOF */
-

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/eab3e478/debian/control
----------------------------------------------------------------------
diff --git a/debian/control b/debian/control
index db717a4..5669610 100644
--- a/debian/control
+++ b/debian/control
@@ -123,7 +123,7 @@ Provides: vmops-agent
 Conflicts: vmops-agent
 Replaces: vmops-agent
 Architecture: any
-Depends: openjdk-6-jre, cloud-utils (= ${source:Version}), cloud-core (= ${source:Version}), cloud-agent-deps (= ${source:Version}), python, cloud-python (= ${source:Version}), cloud-agent-libs (= ${source:Version}), cloud-agent-scripts (= ${source:Version}), libcommons-httpclient-java, libcommons-collections-java, libcommons-dbcp-java, libcommons-pool-java, libcommons-logging-java, libvirt0, sysvinit-utils, chkconfig, qemu-kvm, libvirt-bin,  uuid-runtime, rsync, grep, iproute, ebtables, vlan, libcglib-java, libcommons-httpclient-java, libservlet2.5-java, liblog4j1.2-java, libjna-java, wget
+Depends: openjdk-6-jre, cloud-utils (= ${source:Version}), cloud-core (= ${source:Version}), cloud-agent-deps (= ${source:Version}), python, cloud-python (= ${source:Version}), cloud-agent-libs (= ${source:Version}), cloud-agent-scripts (= ${source:Version}), libcommons-httpclient-java, libcommons-collections-java, libcommons-dbcp-java, libcommons-pool-java, libcommons-logging-java, libvirt0, sysvinit-utils, chkconfig, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, ebtables, vlan, libcglib-java, libcommons-httpclient-java, libservlet2.5-java, liblog4j1.2-java, libjna-java, wget, jsvc
 Description: CloudStack agent
  The CloudStack agent is in charge of managing shared computing resources in
  a CloudStack Cloud Stack-powered cloud.  Install this package if this computer
@@ -141,7 +141,7 @@ Provides: vmops-usage
 Conflicts: vmops-usage
 Replaces: vmops-usage
 Architecture: any
-Depends: openjdk-6-jre, cloud-utils (= ${source:Version}), cloud-core (= ${source:Version}), cloud-deps (= ${source:Version}), cloud-server (= ${source:Version}), cloud-setup (= ${source:Version}), cloud-client (= ${source:Version})
+Depends: openjdk-6-jre, cloud-utils (= ${source:Version}), cloud-core (= ${source:Version}), cloud-deps (= ${source:Version}), cloud-server (= ${source:Version}), cloud-setup (= ${source:Version}), cloud-client (= ${source:Version}), jsvc
 Description: CloudStack usage monitor
  The CloudStack usage monitor provides usage accounting across the entire cloud for
  cloud operators to charge based on usage parameters.

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/eab3e478/usage/distro/ubuntu/SYSCONFDIR/init.d/cloud-usage.in
----------------------------------------------------------------------
diff --git a/usage/distro/ubuntu/SYSCONFDIR/init.d/cloud-usage.in b/usage/distro/ubuntu/SYSCONFDIR/init.d/cloud-usage.in
index e59fc2a..13876b9 100755
--- a/usage/distro/ubuntu/SYSCONFDIR/init.d/cloud-usage.in
+++ b/usage/distro/ubuntu/SYSCONFDIR/init.d/cloud-usage.in
@@ -18,11 +18,29 @@ LOCKFILE=@LOCKDIR@/"$SHORTNAME"
 LOGFILE=@USAGELOG@
 PROGNAME="CloudStack Usage Monitor"
 USER=@MSUSER@
+CLASS="com.cloud.usage.UsageServer"
 
 unset OPTIONS
 [ -r @SYSCONFDIR@/default/"$SHORTNAME" ] && source @SYSCONFDIR@/default/"$SHORTNAME"
-DAEMONIZE=@BINDIR@/@PACKAGE@-daemonize
-PROG=@LIBEXECDIR@/usage-runner
+
+# The first existing directory is used for JAVA_HOME (if JAVA_HOME is not defined in $DEFAULT)
+JDK_DIRS="/usr/lib/jvm/java-6-openjdk /usr/lib/jvm/java-6-openjdk-i386 /usr/lib/jvm/java-6-openjdk-amd64 /usr/lib/jvm/java-6-sun /usr/lib/jvm/java-1.5.0-sun /usr/lib/j2sdk1.5-sun /usr/lib/j2sdk1.5-ibm"
+
+for jdir in $JDK_DIRS; do
+    if [ -r "$jdir/bin/java" -a -z "${JAVA_HOME}" ]; then
+        JAVA_HOME="$jdir"
+    fi
+done
+export JAVA_HOME
+
+SCP="@SYSTEMCLASSPATH@"
+DCP="@DEPSCLASSPATH@"
+UCP="@USAGECLASSPATH@"
+JCP="/usr/share/java/commons-daemon.jar"
+
+# We need to append the JSVC daemon JAR to the classpath
+# AgentShell implements the JSVC daemon methods
+export CLASSPATH="$SCP:$DCP:$UCP:$JCP:@USAGESYSCONFDIR@"
 
 start() {
         log_daemon_msg $"Starting $PROGNAME" "$SHORTNAME"
@@ -39,9 +57,7 @@ start() {
 		exit 1
 	fi
 
-	if start-stop-daemon --start --quiet \
-		--pidfile "$PIDFILE" \
-		--exec "$DAEMONIZE" -- -n "$SHORTNAME" -p "$PIDFILE" -l "$LOGFILE" -u "$USER" "$PROG" $OPTIONS
+        if jsvc -cp "$CLASSPATH" -pidfile "$PIDFILE" -user "$USER" $CLASS
 		RETVAL=$?
 	    then
 		rc=0
@@ -64,7 +80,7 @@ start() {
 
 stop() {
 	echo -n $"Stopping $PROGNAME" "$SHORTNAME"
-	start-stop-daemon --stop --quiet --oknodo --pidfile "$PIDFILE"
+        jsvc -pidfile "$PIDFILE" -stop $CLASS
 	log_end_msg $?
 	rm -f "$PIDFILE"
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/eab3e478/usage/libexec/usage-runner.in
----------------------------------------------------------------------
diff --git a/usage/libexec/usage-runner.in b/usage/libexec/usage-runner.in
deleted file mode 100755
index a5d57ef..0000000
--- a/usage/libexec/usage-runner.in
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# the License.  You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-SYSTEMJARS="@SYSTEMJARS@"
-SCP=$(build-classpath $SYSTEMJARS) ; if [ $? != 0 ] ; then SCP="@SYSTEMCLASSPATH@" ; fi
-DCP="@DEPSCLASSPATH@"
-ACP="@USAGECLASSPATH@"
-export CLASSPATH=$SCP:$DCP:$ACP:@USAGESYSCONFDIR@
-for jarfile in "@PREMIUMJAVADIR@"/* ; do
-	if [ ! -e "$jarfile" ] ; then continue ; fi
-	CLASSPATH=$jarfile:$CLASSPATH
-done
-for plugin in "@PLUGINJAVADIR@"/* ; do
-	if [ ! -e "$plugin" ] ; then continue ; fi
-	CLASSPATH=$plugin:$CLASSPATH
-done
-export CLASSPATH
-
-set -e
-echo Current directory is "$PWD"
-echo CLASSPATH to run the usage server: "$CLASSPATH"
-exec java -cp "$CLASSPATH" -Dpid=$$ -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=@USAGELOGDIR@ "$@" com.cloud.usage.UsageServer

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/eab3e478/usage/src/com/cloud/usage/UsageServer.java
----------------------------------------------------------------------
diff --git a/usage/src/com/cloud/usage/UsageServer.java b/usage/src/com/cloud/usage/UsageServer.java
index c03f7f0..4cdca79 100644
--- a/usage/src/com/cloud/usage/UsageServer.java
+++ b/usage/src/com/cloud/usage/UsageServer.java
@@ -28,7 +28,16 @@ public class UsageServer {
      * @param args
      */
     public static void main(String[] args) {
-        // TODO: do we need to communicate with mgmt server?
+        UsageServer usage = new UsageServer();
+        usage.init(args);
+        usage.start();
+    }
+
+    public void init(String[] args) {
+
+    }
+
+    public void start() {
         final ComponentLocator _locator = ComponentLocator.getLocator(UsageServer.Name, "usage-components.xml", "log4j-cloud_usage");
         UsageManager mgr = _locator.getManager(UsageManager.class);
         if (mgr != null) {
@@ -37,4 +46,12 @@ public class UsageServer {
             }
         }
     }
+
+    public void stop() {
+
+    }
+
+    public void destroy() {
+
+    }
 }