mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-11-04 00:02:37 +01:00 
			
		
		
		
	Remove cloud-daemonize and use JSVC
We now use JSVC for daemonizing our agent and usage server.
This commit is contained in:
		
							parent
							
								
									c99b1d104a
								
							
						
					
					
						commit
						eab3e4783e
					
				@ -18,3 +18,4 @@
 | 
			
		||||
# management server compile-time environment parameters
 | 
			
		||||
 | 
			
		||||
paths.pid=@PIDDIR@
 | 
			
		||||
paths.scripts=@AGENTLIBDIR@
 | 
			
		||||
 | 
			
		||||
@ -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"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
@ -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);
 | 
			
		||||
    public void destroy() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static class ShutdownThread extends Thread {
 | 
			
		||||
        AgentShell _shell;
 | 
			
		||||
 | 
			
		||||
        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());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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 */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							@ -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.
 | 
			
		||||
 | 
			
		||||
@ -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"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
@ -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() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user