mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-03 04:12:31 +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